summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/global/MkSpacer.vue
diff options
context:
space:
mode:
Diffstat (limited to 'packages/frontend/src/components/global/MkSpacer.vue')
-rw-r--r--packages/frontend/src/components/global/MkSpacer.vue96
1 files changed, 96 insertions, 0 deletions
diff --git a/packages/frontend/src/components/global/MkSpacer.vue b/packages/frontend/src/components/global/MkSpacer.vue
new file mode 100644
index 0000000000..b3a42d77e7
--- /dev/null
+++ b/packages/frontend/src/components/global/MkSpacer.vue
@@ -0,0 +1,96 @@
+<template>
+<div ref="root" :class="$style.root" :style="{ padding: margin + 'px' }">
+ <div ref="content" :class="$style.content">
+ <slot></slot>
+ </div>
+</div>
+</template>
+
+<script lang="ts" setup>
+import { inject, onMounted, onUnmounted, ref } from 'vue';
+import { deviceKind } from '@/scripts/device-kind';
+
+const props = withDefaults(defineProps<{
+ contentMax?: number | null;
+ marginMin?: number;
+ marginMax?: number;
+}>(), {
+ contentMax: null,
+ marginMin: 12,
+ marginMax: 24,
+});
+
+let ro: ResizeObserver;
+let root = $ref<HTMLElement>();
+let content = $ref<HTMLElement>();
+let margin = $ref(0);
+const widthHistory = [null, null] as [number | null, number | null];
+const heightHistory = [null, null] as [number | null, number | null];
+const shouldSpacerMin = inject('shouldSpacerMin', false);
+
+const adjust = (rect: { width: number; height: number; }) => {
+ if (shouldSpacerMin || deviceKind === 'smartphone') {
+ margin = props.marginMin;
+ return;
+ }
+
+ if (rect.width > (props.contentMax ?? 0) || (rect.width > 360 && window.innerWidth > 400)) {
+ margin = props.marginMax;
+ } else {
+ margin = props.marginMin;
+ }
+};
+
+onMounted(() => {
+ ro = new ResizeObserver((entries) => {
+ /* iOSが対応していない
+ adjust({
+ width: entries[0].borderBoxSize[0].inlineSize,
+ height: entries[0].borderBoxSize[0].blockSize,
+ });
+ */
+
+ const width = root!.offsetWidth;
+ const height = root!.offsetHeight;
+
+ //#region Prevent infinite resizing
+ // https://github.com/misskey-dev/misskey/issues/9076
+ const pastWidth = widthHistory.pop();
+ widthHistory.unshift(width);
+ const pastHeight = heightHistory.pop();
+ heightHistory.unshift(height);
+
+
+ if (pastWidth === width && pastHeight === height) {
+ return;
+ }
+ //#endregion
+
+ adjust({
+ width,
+ height,
+ });
+ });
+ ro.observe(root!);
+
+ if (props.contentMax) {
+ content!.style.maxWidth = `${props.contentMax}px`;
+ }
+});
+
+onUnmounted(() => {
+ ro.disconnect();
+});
+</script>
+
+<style lang="scss" module>
+.root {
+ box-sizing: border-box;
+ width: 100%;
+}
+
+.content {
+ margin: 0 auto;
+ container-type: inline-size;
+}
+</style>