Skip to content

Commit 09a312a

Browse files
committed
Refactor to composition API
1 parent c58332c commit 09a312a

45 files changed

Lines changed: 703 additions & 1442 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

components/ButtonBackground.vue

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,24 @@
2727
</DeferredComponent>
2828
</template>
2929

30-
<script>
30+
<script setup>
3131
import { ref, watch } from 'vue';
3232
import { XIcon, CheckIcon } from 'lucide-vue-next';
3333
34-
export default {
35-
props: {
36-
custom: Boolean,
37-
active: Boolean,
38-
attributes: Object,
39-
},
34+
defineProps({
35+
custom: Boolean,
36+
active: Boolean,
37+
attributes: Object,
38+
});
4039
41-
components: { XIcon, CheckIcon },
40+
defineEmits(['delete']);
4241
43-
setup() {
44-
const visible = ref(false);
45-
const hasBeenVisible = ref(false);
42+
const visible = ref(false);
43+
const hasBeenVisible = ref(false);
4644
47-
watch(visible, (newVal) => {
48-
if (newVal) {
49-
hasBeenVisible.value = true;
50-
}
51-
});
52-
53-
return { visible, hasBeenVisible };
54-
},
55-
};
45+
watch(visible, (newVal) => {
46+
if (newVal) {
47+
hasBeenVisible.value = true;
48+
}
49+
});
5650
</script>

components/ButtonTheme.vue

Lines changed: 53 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -49,112 +49,66 @@
4949
</div>
5050
</template>
5151

52-
<script>
52+
<script setup>
5353
import { CheckIcon } from 'lucide-vue-next';
5454
import useShiki from '@/composables/useShiki';
5555
import { debounce, defaults, cloneDeep } from 'lodash';
5656
import { ref, watch, reactive, toRefs, onMounted } from 'vue';
5757
58-
export default {
59-
inheritAttrs: false,
58+
defineOptions({ inheritAttrs: false });
6059
61-
props: {
62-
code: {
63-
type: Array,
64-
required: true,
65-
},
66-
theme: {
67-
type: String,
68-
required: true,
69-
},
70-
active: {
71-
type: Boolean,
72-
required: true,
73-
},
74-
settings: {
75-
type: Object,
76-
required: true,
77-
},
78-
languages: {
79-
type: Array,
80-
required: true,
81-
},
82-
background: {
83-
type: Object,
84-
required: true,
60+
const props = defineProps({
61+
code: { type: Array, required: true },
62+
theme: { type: String, required: true },
63+
active: { type: Boolean, required: true },
64+
settings: { type: Object, required: true },
65+
languages: { type: Array, required: true },
66+
background: { type: Object, required: true },
67+
});
68+
69+
const { code, theme, settings, languages } = toRefs(props);
70+
71+
const { $shiki } = useNuxtApp();
72+
const { buildCodeBlocks } = useShiki();
73+
74+
const blocks = ref(null);
75+
const visible = ref(false);
76+
const rendered = ref(false);
77+
const rendering = ref(true);
78+
const themeSettings = reactive({});
79+
const previouslyRendered = ref(null);
80+
81+
const settingOverrides = {
82+
scale: 0.5, marginTop: 0, marginBottom: 0,
83+
marginLeft: 0, marginRight: 0, position: 'center',
84+
};
85+
86+
function generateTokens() {
87+
rendering.value = true;
88+
89+
buildCodeBlocks(
90+
{ code: code.value, theme: theme.value, languages: languages.value },
91+
({ blocks: code, themeType: type, themeBackground: background }) => {
92+
themeSettings.themeType = type;
93+
themeSettings.themeBackground = background;
94+
blocks.value = code;
8595
},
86-
},
87-
88-
components: { CheckIcon },
89-
90-
setup(props) {
91-
const { code, theme, settings, languages } = toRefs(props);
92-
93-
const { $shiki } = useNuxtApp();
94-
95-
const { buildCodeBlocks } = useShiki();
96-
97-
const blocks = ref(null);
98-
const visible = ref(false);
99-
const rendered = ref(false);
100-
const rendering = ref(true);
101-
const themeSettings = reactive({});
102-
const previouslyRendered = ref(null);
103-
104-
const settingOverrides = {
105-
scale: 0.5,
106-
marginTop: 0,
107-
marginBottom: 0,
108-
marginLeft: 0,
109-
marginRight: 0,
110-
position: 'center',
111-
};
112-
113-
function generateTokens() {
114-
rendering.value = true;
115-
116-
buildCodeBlocks(
117-
{
118-
code: code.value,
119-
theme: theme.value,
120-
languages: languages.value,
121-
},
122-
({ blocks: code, themeType: type, themeBackground: background }) => {
123-
themeSettings.themeType = type;
124-
themeSettings.themeBackground = background;
125-
126-
blocks.value = code;
127-
},
128-
5
129-
).then(() => {
130-
rendering.value = false;
131-
previouslyRendered.value = code.value;
132-
});
96+
5
97+
).then(() => {
98+
rendering.value = false;
99+
previouslyRendered.value = code.value;
100+
});
101+
}
102+
103+
watch(settings, (values) => Object.assign(themeSettings, defaults(settingOverrides, cloneDeep(values))), { immediate: true, deep: true });
104+
105+
onMounted(() => {
106+
watch(visible, (vis) => {
107+
if (vis && code.value != previouslyRendered.value) {
108+
$shiki.loadTheme(theme.value).then(generateTokens).then(() => (rendered.value = true));
133109
}
110+
});
134111
135-
watch(
136-
settings,
137-
(values) => Object.assign(themeSettings, defaults(settingOverrides, cloneDeep(values))),
138-
{ immediate: true, deep: true }
139-
);
140-
141-
onMounted(() => {
142-
watch(visible, (visible) => {
143-
if (visible && code.value != previouslyRendered.value) {
144-
$shiki
145-
.loadTheme(theme.value)
146-
.then(generateTokens)
147-
.then(() => (rendered.value = true));
148-
}
149-
});
150-
151-
watch(
152-
code,
153-
debounce(() => visible.value && generateTokens(), 750)
154-
);
155-
});
156-
157-
return { blocks, visible, rendered, rendering, themeSettings };
158-
},
159-
};
112+
watch(code, debounce(() => visible.value && generateTokens(), 750));
113+
});
160114
</script>

components/Canvas.vue

Lines changed: 53 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -92,108 +92,61 @@
9292
</Interact>
9393
</template>
9494

95-
<script>
95+
<script setup>
9696
import interact from 'interactjs';
9797
import { ref, toRefs, computed } from 'vue';
9898
99-
export default {
100-
props: {
101-
width: {
102-
type: Number,
103-
required: true,
104-
},
105-
height: {
106-
type: Number,
107-
required: true,
108-
},
109-
position: {
110-
type: String,
111-
required: true,
112-
},
113-
resizable: {
114-
type: Boolean,
115-
default: true,
116-
required: false,
117-
},
118-
zoom: {
119-
type: [Number, String],
120-
required: false,
121-
default: 1,
122-
},
123-
preview: {
124-
type: Boolean,
125-
default: false,
126-
},
127-
aspectRatio: {
128-
type: Array,
129-
required: false,
130-
},
131-
background: {
132-
type: String,
133-
required: true,
134-
},
135-
backgroundAttributes: {
136-
type: Object,
137-
required: true,
138-
},
99+
const props = defineProps({
100+
width: { type: Number, required: true },
101+
height: { type: Number, required: true },
102+
position: { type: String, required: true },
103+
resizable: { type: Boolean, default: true },
104+
zoom: { type: [Number, String], default: 1 },
105+
preview: { type: Boolean, default: false },
106+
aspectRatio: { type: Array, required: false },
107+
background: { type: String, required: true },
108+
backgroundAttributes: { type: Object, required: true },
109+
});
110+
111+
const emit = defineEmits(['update:width', 'update:height']);
112+
113+
const x = ref(null);
114+
const y = ref(null);
115+
const top = ref(null);
116+
const right = ref(null);
117+
const bottom = ref(null);
118+
const left = ref(null);
119+
120+
const { zoom, aspectRatio } = toRefs(props);
121+
122+
const ratio = computed(() => {
123+
if (aspectRatio.value) {
124+
const [ratioX, ratioY] = aspectRatio.value;
125+
return ratioX / ratioY;
126+
}
127+
});
128+
129+
const zoomScale = computed(() => 1 / Number(zoom.value));
130+
131+
const resize = computed(() => ({
132+
edges: {
133+
top: top.value?.$el,
134+
right: right.value?.$el,
135+
bottom: bottom.value?.$el,
136+
left: left.value?.$el,
139137
},
140-
141-
setup(props, { emit }) {
142-
const x = ref(null);
143-
const y = ref(null);
144-
145-
const top = ref(null);
146-
const right = ref(null);
147-
const bottom = ref(null);
148-
const left = ref(null);
149-
150-
const { zoom, aspectRatio } = toRefs(props);
151-
152-
const ratio = computed(() => {
153-
if (aspectRatio.value) {
154-
const [ratioX, ratioY] = aspectRatio.value;
155-
156-
return ratioX / ratioY;
157-
}
158-
});
159-
160-
const zoomScale = computed(() => 1 / Number(zoom.value));
161-
162-
const resize = computed(() => ({
163-
edges: {
164-
top: top.value?.$el,
165-
right: right.value?.$el,
166-
bottom: bottom.value?.$el,
167-
left: left.value?.$el,
168-
},
169-
modifiers: [
170-
interact.modifiers.aspectRatio({
171-
ratio: ratio.value,
172-
}),
173-
],
174-
}));
175-
176-
function onResize(event) {
177-
const container = event.target.parentNode;
178-
179-
if (event.rect.width) {
180-
const scaleX = container.getBoundingClientRect().width / container.offsetWidth;
181-
182-
const x = event.rect.width / scaleX;
183-
184-
emit('update:width', x);
185-
}
186-
187-
if (event.rect.height) {
188-
const scaleY = container.getBoundingClientRect().height / container.offsetHeight;
189-
190-
const y = event.rect.height / scaleY;
191-
192-
emit('update:height', y);
193-
}
194-
}
195-
196-
return { x, y, top, right, bottom, left, resize, onResize, zoomScale };
197-
},
198-
};
138+
modifiers: [interact.modifiers.aspectRatio({ ratio: ratio.value })],
139+
}));
140+
141+
function onResize(event) {
142+
const container = event.target.parentNode;
143+
if (event.rect.width) {
144+
const scaleX = container.getBoundingClientRect().width / container.offsetWidth;
145+
emit('update:width', event.rect.width / scaleX);
146+
}
147+
if (event.rect.height) {
148+
const scaleY = container.getBoundingClientRect().height / container.offsetHeight;
149+
emit('update:height', event.rect.height / scaleY);
150+
}
151+
}
199152
</script>

0 commit comments

Comments
 (0)