refactor(frontend): use composition api
This commit is contained in:
		
							parent
							
								
									238d0fa667
								
							
						
					
					
						commit
						3d4a90b08a
					
				
					 7 changed files with 125 additions and 381 deletions
				
			
		| 
						 | 
				
			
			@ -1,118 +0,0 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="">
 | 
			
		||||
	<div class="">
 | 
			
		||||
		<MkInput v-model="text">
 | 
			
		||||
			<template #label>Text</template>
 | 
			
		||||
		</MkInput>
 | 
			
		||||
		<MkSwitch v-model="flag">
 | 
			
		||||
			<span>Switch is now {{ flag ? 'on' : 'off' }}</span>
 | 
			
		||||
		</MkSwitch>
 | 
			
		||||
		<div style="margin: 32px 0;">
 | 
			
		||||
			<MkRadio v-model="radio" value="misskey">Misskey</MkRadio>
 | 
			
		||||
			<MkRadio v-model="radio" value="mastodon">Mastodon</MkRadio>
 | 
			
		||||
			<MkRadio v-model="radio" value="pleroma">Pleroma</MkRadio>
 | 
			
		||||
		</div>
 | 
			
		||||
		<MkButton inline>This is</MkButton>
 | 
			
		||||
		<MkButton inline primary>the button</MkButton>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="" style="pointer-events: none;">
 | 
			
		||||
		<Mfm :text="mfm"/>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="">
 | 
			
		||||
		<MkButton inline primary @click="openMenu">Open menu</MkButton>
 | 
			
		||||
		<MkButton inline primary @click="openDialog">Open dialog</MkButton>
 | 
			
		||||
		<MkButton inline primary @click="openForm">Open form</MkButton>
 | 
			
		||||
		<MkButton inline primary @click="openDrive">Open drive</MkButton>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent } from 'vue';
 | 
			
		||||
import MkButton from '@/components/MkButton.vue';
 | 
			
		||||
import MkInput from '@/components/MkInput.vue';
 | 
			
		||||
import MkSwitch from '@/components/MkSwitch.vue';
 | 
			
		||||
import MkTextarea from '@/components/MkTextarea.vue';
 | 
			
		||||
import MkRadio from '@/components/MkRadio.vue';
 | 
			
		||||
import * as os from '@/os';
 | 
			
		||||
import * as config from '@/config';
 | 
			
		||||
import { $i } from '@/account';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
	components: {
 | 
			
		||||
		MkButton,
 | 
			
		||||
		MkInput,
 | 
			
		||||
		MkSwitch,
 | 
			
		||||
		MkTextarea,
 | 
			
		||||
		MkRadio,
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			text: '',
 | 
			
		||||
			flag: true,
 | 
			
		||||
			radio: 'misskey',
 | 
			
		||||
			$i,
 | 
			
		||||
			mfm: `Hello world! This is an @example mention. BTW you are @${this.$i ? this.$i.username : 'guest'}.\nAlso, here is ${config.url} and [example link](${config.url}). for more details, see https://example.com.\nAs you know #misskey is open-source software.`,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		async openDialog() {
 | 
			
		||||
			os.alert({
 | 
			
		||||
				type: 'warning',
 | 
			
		||||
				title: 'Oh my Aichan',
 | 
			
		||||
				text: 'Lorem ipsum dolor sit amet, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async openForm() {
 | 
			
		||||
			os.form('Example form', {
 | 
			
		||||
				foo: {
 | 
			
		||||
					type: 'boolean',
 | 
			
		||||
					default: true,
 | 
			
		||||
					label: 'This is a boolean property',
 | 
			
		||||
				},
 | 
			
		||||
				bar: {
 | 
			
		||||
					type: 'number',
 | 
			
		||||
					default: 300,
 | 
			
		||||
					label: 'This is a number property',
 | 
			
		||||
				},
 | 
			
		||||
				baz: {
 | 
			
		||||
					type: 'string',
 | 
			
		||||
					default: 'Misskey makes you happy.',
 | 
			
		||||
					label: 'This is a string property',
 | 
			
		||||
				},
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async openDrive() {
 | 
			
		||||
			os.selectDriveFile(false);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async selectUser() {
 | 
			
		||||
			os.selectUser();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async openMenu(ev) {
 | 
			
		||||
			os.popupMenu([{
 | 
			
		||||
				type: 'label',
 | 
			
		||||
				text: 'Fruits',
 | 
			
		||||
			}, {
 | 
			
		||||
				text: 'Create some apples',
 | 
			
		||||
				action: () => {},
 | 
			
		||||
			}, {
 | 
			
		||||
				text: 'Read some oranges',
 | 
			
		||||
				action: () => {},
 | 
			
		||||
			}, {
 | 
			
		||||
				text: 'Update some melons',
 | 
			
		||||
				action: () => {},
 | 
			
		||||
			}, null, {
 | 
			
		||||
				text: 'Delete some bananas',
 | 
			
		||||
				danger: true,
 | 
			
		||||
				action: () => {},
 | 
			
		||||
			}], ev.currentTarget ?? ev.target);
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -23,22 +23,13 @@
 | 
			
		|||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent } from 'vue';
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { } from 'vue';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
	props: {
 | 
			
		||||
		def: {
 | 
			
		||||
			type: Array,
 | 
			
		||||
			required: true,
 | 
			
		||||
		},
 | 
			
		||||
		grid: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
defineProps<{
 | 
			
		||||
	def: any[];
 | 
			
		||||
	grid?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,153 +26,88 @@
 | 
			
		|||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent, onMounted, nextTick, ref, watch, computed, toRefs } from 'vue';
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { onMounted, nextTick, ref, watch, computed, toRefs, shallowRef } from 'vue';
 | 
			
		||||
import { debounce } from 'throttle-debounce';
 | 
			
		||||
import MkButton from '@/components/MkButton.vue';
 | 
			
		||||
import { i18n } from '@/i18n';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
	components: {
 | 
			
		||||
		MkButton,
 | 
			
		||||
	},
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
	modelValue: string | null;
 | 
			
		||||
	required?: boolean;
 | 
			
		||||
	readonly?: boolean;
 | 
			
		||||
	disabled?: boolean;
 | 
			
		||||
	pattern?: string;
 | 
			
		||||
	placeholder?: string;
 | 
			
		||||
	autofocus?: boolean;
 | 
			
		||||
	autocomplete?: string;
 | 
			
		||||
	spellcheck?: boolean;
 | 
			
		||||
	debounce?: boolean;
 | 
			
		||||
	manualSave?: boolean;
 | 
			
		||||
	code?: boolean;
 | 
			
		||||
	tall?: boolean;
 | 
			
		||||
	pre?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
	props: {
 | 
			
		||||
		modelValue: {
 | 
			
		||||
			required: true,
 | 
			
		||||
		},
 | 
			
		||||
		type: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		required: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		readonly: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		disabled: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		pattern: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		placeholder: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		autofocus: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
		autocomplete: {
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		spellcheck: {
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		code: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		tall: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
		pre: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
		debounce: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
		manualSave: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
	(ev: 'change', _ev: KeyboardEvent): void;
 | 
			
		||||
	(ev: 'keydown', _ev: KeyboardEvent): void;
 | 
			
		||||
	(ev: 'enter'): void;
 | 
			
		||||
	(ev: 'update:modelValue', value: string): void;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
	emits: ['change', 'keydown', 'enter', 'update:modelValue'],
 | 
			
		||||
const { modelValue, autofocus } = toRefs(props);
 | 
			
		||||
const v = ref<string>(modelValue.value ?? '');
 | 
			
		||||
const focused = ref(false);
 | 
			
		||||
const changed = ref(false);
 | 
			
		||||
const invalid = ref(false);
 | 
			
		||||
const filled = computed(() => v.value !== '' && v.value != null);
 | 
			
		||||
const inputEl = shallowRef<HTMLTextAreaElement>();
 | 
			
		||||
 | 
			
		||||
	setup(props, context) {
 | 
			
		||||
		const { modelValue, autofocus } = toRefs(props);
 | 
			
		||||
		const v = ref(modelValue.value);
 | 
			
		||||
		const focused = ref(false);
 | 
			
		||||
		const changed = ref(false);
 | 
			
		||||
		const invalid = ref(false);
 | 
			
		||||
		const filled = computed(() => v.value !== '' && v.value != null);
 | 
			
		||||
		const inputEl = ref(null);
 | 
			
		||||
const focus = () => inputEl.value.focus();
 | 
			
		||||
const onInput = (ev) => {
 | 
			
		||||
	changed.value = true;
 | 
			
		||||
	emit('change', ev);
 | 
			
		||||
};
 | 
			
		||||
const onKeydown = (ev: KeyboardEvent) => {
 | 
			
		||||
	if (ev.isComposing || ev.key === 'Process' || ev.keyCode === 229) return;
 | 
			
		||||
 | 
			
		||||
		const focus = () => inputEl.value.focus();
 | 
			
		||||
		const onInput = (ev) => {
 | 
			
		||||
			changed.value = true;
 | 
			
		||||
			context.emit('change', ev);
 | 
			
		||||
		};
 | 
			
		||||
		const onKeydown = (ev: KeyboardEvent) => {
 | 
			
		||||
			if (ev.isComposing || ev.key === 'Process' || ev.keyCode === 229) return;
 | 
			
		||||
	emit('keydown', ev);
 | 
			
		||||
 | 
			
		||||
			context.emit('keydown', ev);
 | 
			
		||||
	if (ev.code === 'Enter') {
 | 
			
		||||
		emit('enter');
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
			if (ev.code === 'Enter') {
 | 
			
		||||
				context.emit('enter');
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
const updated = () => {
 | 
			
		||||
	changed.value = false;
 | 
			
		||||
	emit('update:modelValue', v.value ?? '');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		const updated = () => {
 | 
			
		||||
			changed.value = false;
 | 
			
		||||
			context.emit('update:modelValue', v.value);
 | 
			
		||||
		};
 | 
			
		||||
const debouncedUpdated = debounce(1000, updated);
 | 
			
		||||
 | 
			
		||||
		const debouncedUpdated = debounce(1000, updated);
 | 
			
		||||
watch(modelValue, newValue => {
 | 
			
		||||
	v.value = newValue;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
		watch(modelValue, newValue => {
 | 
			
		||||
			v.value = newValue;
 | 
			
		||||
		});
 | 
			
		||||
watch(v, newValue => {
 | 
			
		||||
	if (!props.manualSave) {
 | 
			
		||||
		if (props.debounce) {
 | 
			
		||||
			debouncedUpdated();
 | 
			
		||||
		} else {
 | 
			
		||||
			updated();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		watch(v, newValue => {
 | 
			
		||||
			if (!props.manualSave) {
 | 
			
		||||
				if (props.debounce) {
 | 
			
		||||
					debouncedUpdated();
 | 
			
		||||
				} else {
 | 
			
		||||
					updated();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
	invalid.value = inputEl.value.validity.badInput;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
			invalid.value = inputEl.value.validity.badInput;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		onMounted(() => {
 | 
			
		||||
			nextTick(() => {
 | 
			
		||||
				if (autofocus.value) {
 | 
			
		||||
					focus();
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		return {
 | 
			
		||||
			v,
 | 
			
		||||
			focused,
 | 
			
		||||
			invalid,
 | 
			
		||||
			changed,
 | 
			
		||||
			filled,
 | 
			
		||||
			inputEl,
 | 
			
		||||
			focus,
 | 
			
		||||
			onInput,
 | 
			
		||||
			onKeydown,
 | 
			
		||||
			updated,
 | 
			
		||||
			i18n,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
	nextTick(() => {
 | 
			
		||||
		if (autofocus.value) {
 | 
			
		||||
			focus();
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,49 +9,41 @@
 | 
			
		|||
</Sortable>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent, defineAsyncComponent } from 'vue';
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { defineAsyncComponent } from 'vue';
 | 
			
		||||
import XSection from './els/page-editor.el.section.vue';
 | 
			
		||||
import XText from './els/page-editor.el.text.vue';
 | 
			
		||||
import XImage from './els/page-editor.el.image.vue';
 | 
			
		||||
import XNote from './els/page-editor.el.note.vue';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
	components: {
 | 
			
		||||
		Sortable: defineAsyncComponent(() => import('vuedraggable').then(x => x.default)),
 | 
			
		||||
		XSection, XText, XImage, XNote,
 | 
			
		||||
	},
 | 
			
		||||
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
 | 
			
		||||
 | 
			
		||||
	props: {
 | 
			
		||||
		modelValue: {
 | 
			
		||||
			type: Array,
 | 
			
		||||
			required: true,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
	modelValue: any[];
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
	emits: ['update:modelValue'],
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
	(ev: 'update:modelValue', value: any[]): void;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		updateItem(v) {
 | 
			
		||||
			const i = this.modelValue.findIndex(x => x.id === v.id);
 | 
			
		||||
			const newValue = [
 | 
			
		||||
				...this.modelValue.slice(0, i),
 | 
			
		||||
				v,
 | 
			
		||||
				...this.modelValue.slice(i + 1),
 | 
			
		||||
			];
 | 
			
		||||
			this.$emit('update:modelValue', newValue);
 | 
			
		||||
		},
 | 
			
		||||
function updateItem(v) {
 | 
			
		||||
	const i = props.modelValue.findIndex(x => x.id === v.id);
 | 
			
		||||
	const newValue = [
 | 
			
		||||
		...props.modelValue.slice(0, i),
 | 
			
		||||
		v,
 | 
			
		||||
		...props.modelValue.slice(i + 1),
 | 
			
		||||
	];
 | 
			
		||||
	emit('update:modelValue', newValue);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		removeItem(el) {
 | 
			
		||||
			const i = this.modelValue.findIndex(x => x.id === el.id);
 | 
			
		||||
			const newValue = [
 | 
			
		||||
				...this.modelValue.slice(0, i),
 | 
			
		||||
				...this.modelValue.slice(i + 1),
 | 
			
		||||
			];
 | 
			
		||||
			this.$emit('update:modelValue', newValue);
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
function removeItem(el) {
 | 
			
		||||
	const i = props.modelValue.findIndex(x => x.id === el.id);
 | 
			
		||||
	const newValue = [
 | 
			
		||||
		...props.modelValue.slice(0, i),
 | 
			
		||||
		...props.modelValue.slice(i + 1),
 | 
			
		||||
	];
 | 
			
		||||
	emit('update:modelValue', newValue);
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" module>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="cpjygsrt" :class="{ error: error != null, warn: warn != null }">
 | 
			
		||||
<div class="cpjygsrt">
 | 
			
		||||
	<header>
 | 
			
		||||
		<div class="title"><slot name="header"></slot></div>
 | 
			
		||||
		<div class="buttons">
 | 
			
		||||
| 
						 | 
				
			
			@ -16,58 +16,40 @@
 | 
			
		|||
			</button>
 | 
			
		||||
		</div>
 | 
			
		||||
	</header>
 | 
			
		||||
	<p v-show="showBody" v-if="error != null" class="error">{{ i18n.t('_pages.script.typeError', { slot: error.arg + 1, expect: i18n.t(`script.types.${error.expect}`), actual: i18n.t(`script.types.${error.actual}`) }) }}</p>
 | 
			
		||||
	<p v-show="showBody" v-if="warn != null" class="warn">{{ i18n.t('_pages.script.thereIsEmptySlot', { slot: warn.slot + 1 }) }}</p>
 | 
			
		||||
	<div v-show="showBody" class="body">
 | 
			
		||||
		<slot></slot>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent } from 'vue';
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import { i18n } from '@/i18n';
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
	props: {
 | 
			
		||||
		expanded: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			default: true,
 | 
			
		||||
		},
 | 
			
		||||
		removable: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			default: true,
 | 
			
		||||
		},
 | 
			
		||||
		draggable: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
		error: {
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: null,
 | 
			
		||||
		},
 | 
			
		||||
		warn: {
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: null,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	emits: ['toggle', 'remove'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			showBody: this.expanded,
 | 
			
		||||
			i18n,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		toggleContent(show: boolean) {
 | 
			
		||||
			this.showBody = show;
 | 
			
		||||
			this.$emit('toggle', show);
 | 
			
		||||
		},
 | 
			
		||||
		remove() {
 | 
			
		||||
			this.$emit('remove');
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
const props = withDefaults(defineProps<{
 | 
			
		||||
	expanded?: boolean;
 | 
			
		||||
	removable?: boolean;
 | 
			
		||||
	draggable?: boolean;
 | 
			
		||||
}>(), {
 | 
			
		||||
	expanded: true,
 | 
			
		||||
	removable: true,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
	(ev: 'toggle', show: boolean): void;
 | 
			
		||||
	(ev: 'remove'): void;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const showBody = ref(props.expanded);
 | 
			
		||||
 | 
			
		||||
function toggleContent(show: boolean) {
 | 
			
		||||
	showBody.value = show;
 | 
			
		||||
	emit('toggle', show);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function remove() {
 | 
			
		||||
	emit('remove');
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
| 
						 | 
				
			
			@ -128,20 +110,6 @@ export default defineComponent({
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	> .warn {
 | 
			
		||||
		color: #b19e49;
 | 
			
		||||
		margin: 0;
 | 
			
		||||
		padding: 16px 16px 0 16px;
 | 
			
		||||
		font-size: 14px;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	> .error {
 | 
			
		||||
		color: #f00;
 | 
			
		||||
		margin: 0;
 | 
			
		||||
		padding: 16px 16px 0 16px;
 | 
			
		||||
		font-size: 14px;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	> .body {
 | 
			
		||||
		::v-deep(.juejbjww), ::v-deep(.eiipwacr) {
 | 
			
		||||
			&:not(.inline):first-child {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,21 +0,0 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div>
 | 
			
		||||
	<MkSample/>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import { computed } from 'vue';
 | 
			
		||||
import MkSample from '@/components/MkSample.vue';
 | 
			
		||||
import { i18n } from '@/i18n';
 | 
			
		||||
import { definePageMetadata } from '@/scripts/page-metadata';
 | 
			
		||||
 | 
			
		||||
const headerActions = $computed(() => []);
 | 
			
		||||
 | 
			
		||||
const headerTabs = $computed(() => []);
 | 
			
		||||
 | 
			
		||||
definePageMetadata(computed(() => ({
 | 
			
		||||
	title: i18n.ts.preview,
 | 
			
		||||
	icon: 'ti ti-eye',
 | 
			
		||||
})));
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -242,9 +242,6 @@ export const routes = [{
 | 
			
		|||
}, {
 | 
			
		||||
	path: '/scratchpad',
 | 
			
		||||
	component: page(() => import('./pages/scratchpad.vue')),
 | 
			
		||||
}, {
 | 
			
		||||
	path: '/preview',
 | 
			
		||||
	component: page(() => import('./pages/preview.vue')),
 | 
			
		||||
}, {
 | 
			
		||||
	path: '/auth/:token',
 | 
			
		||||
	component: page(() => import('./pages/auth.vue')),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue