Skip to content

Commit 0fcb389

Browse files
committed
Get rid of calculating element sizes by split width
1 parent e73ae3a commit 0fcb389

File tree

6 files changed

+51
-24
lines changed

6 files changed

+51
-24
lines changed

src/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<resizable v-model:width="width">
33
<template v-slot:default>
44
<editor v-model:content="content" v-model:selection="selection" v-model:scroll="scroll" :icons="iconStore.icons"
5-
:size="editorStore.size" :width="width" />
5+
:size="editorStore.size" />
66
</template>
77
<template v-slot:fixed>
88
<scroller v-model:scroll="scroll">
9-
<BSMap v-bind:content="content" v-bind:size="editorStore.size" v-bind:width="width" />
9+
<BSMap v-bind:content="content" v-bind:size="editorStore.size" />
1010
</scroller>
1111
</template>
1212
</resizable>

src/components/BSMap.vue

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<template>
22
<div :style="{ lineHeight: `${size}px` }">
3-
<BSRow v-for="(row, index) in rows" :key="index" :content="row" :cols="cols" :size="size" :width="width"
4-
:row="index" />
3+
<BSRow v-for="(row, index) in rows" :key="index" :content="row" :cols="cols" :size="size" :row="index" />
54
</div>
65
</template>
76

@@ -13,7 +12,6 @@ import BSRow from './BSMap/BSRow.vue';
1312
const props = defineProps<{
1413
content: string;
1514
size: number;
16-
width: number;
1715
}>();
1816
1917
const rows = computed(() => props.content.split('\n'));

src/components/BSMap/BSRow.vue

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
:class="{ [$style.selection]: true, [$style.focused]: isFocused(row, offset, cell.length) }" :content="cell"
66
:size="size" :row="row" :offset="offset" />
77
</div>
8-
<div :class="$style.texts" :style="{ maxWidth: `${textMaxWidth}px` }">
8+
<div :class="$style.texts">
99
<BSText v-for="({ text, offset, align }, index) in texts" :key="index"
1010
:class="{ [$style.selection]: true, [$style.focused]: isFocused(row, offset, text.length) }" :content="text"
1111
:align="align" :row="row" :offset="offset" />
@@ -25,7 +25,6 @@ const props = defineProps<{
2525
content: string;
2626
cols: number;
2727
size: number;
28-
width: number;
2928
row: number;
3029
}>();
3130
@@ -58,8 +57,6 @@ const texts = computed(() => {
5857
5958
const iconWidth = computed(() => props.size * props.cols);
6059
61-
const textMaxWidth = computed(() => props.width - iconWidth.value);
62-
6360
function isFocused(row: number, offset: number, length: number): boolean {
6461
const { selection } = editorStore;
6562
return (
@@ -77,13 +74,13 @@ function isFocused(row: number, offset: number, length: number): boolean {
7774
align-items: stretch;
7875
7976
>.cells {
77+
flex: 0 0 auto;
8078
display: flex;
8179
justify-content: center;
8280
}
8381
8482
>.texts {
85-
flex-grow: 1;
86-
flex-shrink: 1000;
83+
flex: 1 1 auto;
8784
display: flex;
8885
}
8986

src/components/Editor.vue

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import '@/editor/rdt';
2323
import ISelection from '@/types/selection';
2424
import IIcon from '@/types/icon';
2525
26-
import useOnWindowResize from '@/composables/useOnWindowResize';
26+
import useClientSize from '@/composables/useClientSize';
2727
2828
interface IRenderer extends VirtualRenderer {
2929
scrollTop: number;
@@ -36,7 +36,6 @@ const props = defineProps<{
3636
scroll: number;
3737
icons: Record<string, IIcon | null>;
3838
size: number;
39-
width: number;
4039
}>();
4140
4241
const emit = defineEmits<{
@@ -45,14 +44,11 @@ const emit = defineEmits<{
4544
(e: 'update:scroll', scroll: number): void;
4645
}>();
4746
48-
const { width, scroll, selection } = toRefs(props);
47+
const { scroll, selection } = toRefs(props);
4948
5049
let editor: IEditor | undefined;
5150
let renderer: IRenderer | undefined;
5251
53-
useOnWindowResize(() => editor?.resize());
54-
watch(width, () => editor?.resize());
55-
5652
watch(scroll, (scroll) => renderer?.scrollToY(scroll));
5753
5854
function applySelection(row: number, offset: number, length: number) {
@@ -74,7 +70,7 @@ watch(selection, (selection) => {
7470
}
7571
});
7672
77-
const holder = ref<HTMLElement | null>(null);
73+
const holder = ref<HTMLElement | undefined>();
7874
onMounted(() => {
7975
if (holder.value) {
8076
editor = brace.edit(holder.value);
@@ -112,6 +108,9 @@ onMounted(() => {
112108
}
113109
});
114110
111+
const holderSize = useClientSize(holder);
112+
watch(holderSize, () => editor?.resize());
113+
115114
function getCompletions(
116115
editor: IEditor,
117116
session: IEditSession,

src/composables/useClientSize.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { onBeforeUnmount, onMounted, ref, watch, type Ref } from 'vue';
2+
3+
interface Size {
4+
width: number;
5+
height: number;
6+
}
7+
8+
export default function useClientSize(elementRef: Ref<HTMLElement | undefined>): Ref<Size | undefined> {
9+
const getSize = (target: HTMLElement | undefined): Size | undefined => target && {
10+
width: target.clientWidth,
11+
height: target.clientHeight,
12+
};
13+
14+
const size = ref<Size | undefined>(getSize(elementRef.value));
15+
16+
const observer = new ResizeObserver(() => {
17+
size.value = getSize(elementRef.value);
18+
});
19+
20+
watch(elementRef, () => {
21+
if (elementRef.value) {
22+
observer.observe(elementRef.value);
23+
}
24+
});
25+
26+
onMounted(() => {
27+
if (elementRef.value) {
28+
observer.observe(elementRef.value);
29+
}
30+
});
31+
32+
onBeforeUnmount(() => {
33+
if (elementRef.value) {
34+
observer.unobserve(elementRef.value);
35+
}
36+
});
37+
38+
return size;
39+
}

src/composables/useOnWindowResize.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)