toolbar, icons
This commit is contained in:
parent
2f68699913
commit
f081ecbfc7
@ -7,6 +7,7 @@
|
|||||||
],
|
],
|
||||||
"main": "./dist/editor.umd.cjs",
|
"main": "./dist/editor.umd.cjs",
|
||||||
"module": "./dist/editor.js",
|
"module": "./dist/editor.js",
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./dist/editor.js",
|
"import": "./dist/editor.js",
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
:selectionMap="selectionMap"
|
:selectionMap="selectionMap"
|
||||||
:depth="0"
|
:depth="0"
|
||||||
@select="selectItem"
|
@select="selectItem"
|
||||||
|
@toggle="toggleVisibility"
|
||||||
/>
|
/>
|
||||||
</SidebarPanel>
|
</SidebarPanel>
|
||||||
|
|
||||||
@ -62,6 +63,14 @@ const selectItem = (item: Object3D, ctrl: boolean) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleVisibility = (item: Object3D) =>
|
||||||
|
props.editor.events.emit('change', {
|
||||||
|
object: item,
|
||||||
|
property: 'visible',
|
||||||
|
value: !item.visible,
|
||||||
|
edited: true,
|
||||||
|
});
|
||||||
|
|
||||||
const update = (item: GameObject, property: string, value: unknown) => {
|
const update = (item: GameObject, property: string, value: unknown) => {
|
||||||
props.editor.events.emit('change', {
|
props.editor.events.emit('change', {
|
||||||
object: item,
|
object: item,
|
||||||
|
@ -1,26 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<Menu
|
<template v-for="item of toolbarItems">
|
||||||
id="file"
|
<Menu
|
||||||
:items="fileMenu"
|
:id="item.id"
|
||||||
:open-sibling="currentlyOpen"
|
:items="item.items"
|
||||||
@toggle="(state, reason) => toggleEvent('file', state, reason)"
|
:open-sibling="currentlyOpen"
|
||||||
>File</Menu
|
@toggle="(state, reason) => toggleEvent(item.id, state, reason)"
|
||||||
>
|
>{{ item.label }}</Menu
|
||||||
<Menu
|
>
|
||||||
id="edit"
|
</template>
|
||||||
:items="editMenu"
|
|
||||||
:open-sibling="currentlyOpen"
|
|
||||||
@toggle="(state, reason) => toggleEvent('edit', state, reason)"
|
|
||||||
>Edit</Menu
|
|
||||||
>
|
|
||||||
<Menu
|
|
||||||
id="add"
|
|
||||||
:items="addMenu"
|
|
||||||
:open-sibling="currentlyOpen"
|
|
||||||
@toggle="(state, reason) => toggleEvent('add', state, reason)"
|
|
||||||
>Add</Menu
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -29,6 +17,7 @@ import { computed, ref } from 'vue';
|
|||||||
import { Editor } from '../editor';
|
import { Editor } from '../editor';
|
||||||
import Menu from './menu/Menu.vue';
|
import Menu from './menu/Menu.vue';
|
||||||
import { instancableGameObjects } from '@freeblox/engine';
|
import { instancableGameObjects } from '@freeblox/engine';
|
||||||
|
import { useEditorEvents } from '../composables/use-editor-events';
|
||||||
|
|
||||||
const currentlyOpen = ref<string | undefined>(undefined);
|
const currentlyOpen = ref<string | undefined>(undefined);
|
||||||
|
|
||||||
@ -40,6 +29,8 @@ const emit = defineEmits<{
|
|||||||
(e: 'update'): void;
|
(e: 'update'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
// const { register } = useEditorEvents(props.editor);
|
||||||
|
|
||||||
const fileMenu = [
|
const fileMenu = [
|
||||||
{
|
{
|
||||||
id: 'new',
|
id: 'new',
|
||||||
@ -100,6 +91,24 @@ const addMenu = computed(() =>
|
|||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const toolbarItems = computed(() => [
|
||||||
|
{
|
||||||
|
id: 'file',
|
||||||
|
label: 'File',
|
||||||
|
items: fileMenu,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'edit',
|
||||||
|
label: 'Edit',
|
||||||
|
items: editMenu.value,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'add',
|
||||||
|
label: 'Add',
|
||||||
|
items: addMenu.value,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
const toggleEvent = (id: string, state: boolean, reason: 'user' | 'leave') => {
|
const toggleEvent = (id: string, state: boolean, reason: 'user' | 'leave') => {
|
||||||
if (state) currentlyOpen.value = id;
|
if (state) currentlyOpen.value = id;
|
||||||
else if (reason === 'user') currentlyOpen.value = undefined;
|
else if (reason === 'user') currentlyOpen.value = undefined;
|
||||||
|
@ -1,30 +1,50 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="button-bar">
|
<div class="button-bar-wrapper">
|
||||||
<button
|
<div class="button-bar">
|
||||||
v-for="mode of modes"
|
<button
|
||||||
type="button"
|
v-for="mode of modes"
|
||||||
@click="changeMode(mode.name)"
|
type="button"
|
||||||
:class="{ active: mode.name === currentMode, 'mode-button': true }"
|
@click="changeMode(mode.name)"
|
||||||
>
|
:class="{ active: mode.name === currentMode, 'mode-button': true }"
|
||||||
{{ mode.text }}
|
:title="mode.title"
|
||||||
</button>
|
>
|
||||||
|
<component :is="mode.icon" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="snap-ctrl">
|
||||||
|
<span>Snap</span>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="currentRotationSnap"
|
||||||
|
@change="changeRotationSnap"
|
||||||
|
v-if="currentMode === 'rotate'"
|
||||||
|
/>
|
||||||
|
<input type="text" v-model="currentSnap" @change="changeSnap" v-else />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onBeforeUnmount, onMounted, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { Editor, TransformModeEvent } from '../editor';
|
import { Editor, TransformModeEvent } from '../editor';
|
||||||
import { useEditorEvents } from '../composables/use-editor-events';
|
import { useEditorEvents } from '../composables/use-editor-events';
|
||||||
|
import TranslateSvg from '../icons/translate.svg.vue';
|
||||||
|
import RotateSvg from '../icons/rotate.svg.vue';
|
||||||
|
import ScaleSvg from '../icons/scale.svg.vue';
|
||||||
|
|
||||||
const currentMode = ref<TransformModeEvent>('translate');
|
const currentMode = ref<TransformModeEvent>('translate');
|
||||||
|
const currentSnap = ref<number>(0.5);
|
||||||
|
const currentRotationSnap = ref<number>(15);
|
||||||
|
|
||||||
const modes: {
|
const modes: {
|
||||||
name: TransformModeEvent;
|
name: TransformModeEvent;
|
||||||
text: string;
|
icon: any;
|
||||||
|
title: string;
|
||||||
}[] = [
|
}[] = [
|
||||||
{ name: 'translate', text: 'T' },
|
{ name: 'translate', icon: TranslateSvg, title: 'Move' },
|
||||||
{ name: 'rotate', text: 'R' },
|
{ name: 'rotate', icon: RotateSvg, title: 'Rotate' },
|
||||||
{ name: 'scale', text: 'S' },
|
{ name: 'scale', icon: ScaleSvg, title: 'Scale' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@ -41,26 +61,49 @@ function handleTransformMode(mode: TransformModeEvent) {
|
|||||||
currentMode.value = mode;
|
currentMode.value = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleRotationSnap(snap: number) {
|
||||||
|
currentRotationSnap.value = snap;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTransformSnap(snap: number) {
|
||||||
|
currentSnap.value = snap;
|
||||||
|
}
|
||||||
|
|
||||||
function changeMode(mode: TransformModeEvent) {
|
function changeMode(mode: TransformModeEvent) {
|
||||||
props.editor.events.emit('transformMode', mode);
|
props.editor.events.emit('transformMode', mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeSnap() {
|
||||||
|
const value = Number(currentSnap.value);
|
||||||
|
if (isNaN(value)) return;
|
||||||
|
props.editor.events.emit('transformSnap', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeRotationSnap() {
|
||||||
|
const value = Number(currentRotationSnap.value);
|
||||||
|
if (isNaN(value)) return;
|
||||||
|
props.editor.events.emit('transformRotationSnap', value);
|
||||||
|
}
|
||||||
|
|
||||||
register('transformMode', handleTransformMode);
|
register('transformMode', handleTransformMode);
|
||||||
|
register('transformSnap', handleTransformSnap);
|
||||||
|
register('transformRotationSnap', handleRotationSnap);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.button-bar {
|
.button-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: absolute;
|
align-items: center;
|
||||||
top: calc(32px + 36px);
|
|
||||||
left: 32px;
|
|
||||||
|
|
||||||
.mode-button {
|
.mode-button {
|
||||||
|
display: flex;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 8px;
|
padding: 6px;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
background-color: #efefef;
|
background-color: #efefef;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
@ -70,6 +113,42 @@ register('transformMode', handleTransformMode);
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.active,
|
||||||
|
&:hover,
|
||||||
|
&:focus-visible {
|
||||||
|
svg {
|
||||||
|
fill: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
fill: #727272;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(32px + 36px);
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.snap-ctrl {
|
||||||
|
background-color: #ddd;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-top: 4px;
|
||||||
|
border: 0;
|
||||||
|
width: 4rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -32,21 +32,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, watch } from 'vue';
|
import { computed, onMounted, watch } from 'vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { MenuItem } from '../../types/menu.interface';
|
||||||
|
|
||||||
type ToggleTrigger = 'user' | 'leave';
|
type ToggleTrigger = 'user' | 'leave';
|
||||||
|
|
||||||
const buttonRef = ref();
|
const buttonRef = ref();
|
||||||
const isOpen = ref(false);
|
const isOpen = ref(false);
|
||||||
|
|
||||||
export interface MenuItem {
|
|
||||||
id: string;
|
|
||||||
label?: string;
|
|
||||||
shortcut?: string;
|
|
||||||
onClick?: () => void;
|
|
||||||
component?: any;
|
|
||||||
children?: MenuItem[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -2,11 +2,23 @@
|
|||||||
<div class="sidebar-row">
|
<div class="sidebar-row">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
:class="{ selected: !!selected, 'sidebar-row-button': true }"
|
:class="{
|
||||||
|
selected: !!selected,
|
||||||
|
'sidebar-row-button': true,
|
||||||
|
hidden: !item.visible,
|
||||||
|
}"
|
||||||
:style="{ paddingLeft: buttonPadding }"
|
:style="{ paddingLeft: buttonPadding }"
|
||||||
@click="click($event)"
|
@click="click($event)"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
<span>{{ item.name }}</span>
|
||||||
|
<button
|
||||||
|
v-if="!(item as GameObject).virtual"
|
||||||
|
@click.prevent="toggleVisibility"
|
||||||
|
class="sidebar-row-toggle-visible"
|
||||||
|
>
|
||||||
|
<VisibleSvg v-if="item.visible" />
|
||||||
|
<HiddenSvg v-else />
|
||||||
|
</button>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="sidebar-row-children">
|
<div class="sidebar-row-children">
|
||||||
@ -16,6 +28,7 @@
|
|||||||
:selectionMap="selectionMap"
|
:selectionMap="selectionMap"
|
||||||
:depth="depth + 1"
|
:depth="depth + 1"
|
||||||
@select="(o, c) => emit('select', o, c)"
|
@select="(o, c) => emit('select', o, c)"
|
||||||
|
@toggle="(o) => emit('toggle', o)"
|
||||||
></SidebarRow>
|
></SidebarRow>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -25,6 +38,8 @@
|
|||||||
import { GameObject } from '@freeblox/engine';
|
import { GameObject } from '@freeblox/engine';
|
||||||
import { Object3D } from 'three';
|
import { Object3D } from 'three';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import VisibleSvg from '../../icons/visible.svg.vue';
|
||||||
|
import HiddenSvg from '../../icons/hidden.svg.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: Object3D;
|
item: Object3D;
|
||||||
@ -35,6 +50,7 @@ const props = defineProps<{
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update'): void;
|
(e: 'update'): void;
|
||||||
(e: 'select', item: Object3D, ctrl: boolean): void;
|
(e: 'select', item: Object3D, ctrl: boolean): void;
|
||||||
|
(e: 'toggle', item: Object3D): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const selected = computed(() => props.selectionMap?.includes(props.item.uuid));
|
const selected = computed(() => props.selectionMap?.includes(props.item.uuid));
|
||||||
@ -45,6 +61,8 @@ const click = ($event: MouseEvent) => {
|
|||||||
|
|
||||||
const filtered = (items: Object3D[]) =>
|
const filtered = (items: Object3D[]) =>
|
||||||
items.filter((item) => item instanceof GameObject);
|
items.filter((item) => item instanceof GameObject);
|
||||||
|
|
||||||
|
const toggleVisibility = () => emit('toggle', props.item);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -53,6 +71,10 @@ const filtered = (items: Object3D[]) =>
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
&-button {
|
&-button {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
@ -61,9 +83,27 @@ const filtered = (items: Object3D[]) =>
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.hidden {
|
||||||
|
font-style: italic;
|
||||||
|
color: #4b4b4b;
|
||||||
|
}
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
background-color: #bcefff;
|
background-color: #bcefff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-toggle-visible {
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -262,7 +262,7 @@ export class WorkspaceComponent extends EngineComponent {
|
|||||||
|
|
||||||
const transformRotationSnap = (value: number) => {
|
const transformRotationSnap = (value: number) => {
|
||||||
if (!this.transformControls) return;
|
if (!this.transformControls) return;
|
||||||
this.transformControls.setRotationSnap(value);
|
this.transformControls.setRotationSnap(MathUtils.degToRad(value));
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeListener = (change: ChangeEvent) => {
|
const changeListener = (change: ChangeEvent) => {
|
||||||
|
7
packages/editor/src/icons/hidden.svg.vue
Normal file
7
packages/editor/src/icons/hidden.svg.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960">
|
||||||
|
<path
|
||||||
|
d="m629-419-44-44q26-71-27-118t-115-24l-44-44q17-11 38-16t43-5q71 0 120.5 49.5T650-500q0 22-5.5 43.5T629-419Zm129 129-40-40q49-36 85.5-80.5T857-500q-50-111-150-175.5T490-740q-42 0-86 8t-69 19l-46-47q35-16 89.5-28T485-800q143 0 261.5 81.5T920-500q-26 64-67 117t-95 93Zm58 226L648-229q-35 14-79 21.5t-89 7.5q-146 0-265-81.5T40-500q20-52 55.5-101.5T182-696L56-822l42-43 757 757-39 44ZM223-654q-37 27-71.5 71T102-500q51 111 153.5 175.5T488-260q33 0 65-4t48-12l-64-64q-11 5-27 7.5t-30 2.5q-70 0-120-49t-50-121q0-15 2.5-30t7.5-27l-97-97Zm305 142Zm-116 58Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
7
packages/editor/src/icons/rotate.svg.vue
Normal file
7
packages/editor/src/icons/rotate.svg.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960">
|
||||||
|
<path
|
||||||
|
d="M480-80q-140 0-248-86T93-389h61q30 111 120.5 180T480-140q98 0 180.5-50.5T788-328H657v-61h223v229h-59v-109q-57 88-147 138.5T480-80Zm1-299q-42 0-72-30t-30-72q0-42 30-72t72-30q42 0 72 30t30 72q0 42-30 72t-72 30ZM80-572v-228h60v107q57-88 146.5-137.5T480-880q140 0 248.5 85.5T868-572h-61q-30-111-121-180t-206-69q-97 0-179 51T173-633h131v61H80Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
7
packages/editor/src/icons/scale.svg.vue
Normal file
7
packages/editor/src/icons/scale.svg.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960">
|
||||||
|
<path
|
||||||
|
d="M120-120v-300h60v198l558-558H540v-60h300v300h-60v-198L222-180h198v60H120Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
7
packages/editor/src/icons/translate.svg.vue
Normal file
7
packages/editor/src/icons/translate.svg.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960">
|
||||||
|
<path
|
||||||
|
d="M480-80 317-243l44-44 89 89v-189h60v189l89-89 44 44L480-80ZM238-322 80-480l159-159 44 44-85 85h189v60H198l84 84-44 44Zm484 0-44-44 84-84H574v-60h188l-84-84 44-44 158 158-158 158ZM450-574v-188l-84 84-44-44 158-158 158 158-44 44-84-84v188h-60Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
7
packages/editor/src/icons/visible.svg.vue
Normal file
7
packages/editor/src/icons/visible.svg.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960">
|
||||||
|
<path
|
||||||
|
d="M480.118-330Q551-330 600.5-379.618q49.5-49.617 49.5-120.5Q650-571 600.382-620.5q-49.617-49.5-120.5-49.5Q409-670 359.5-620.382q-49.5 49.617-49.5 120.5Q310-429 359.618-379.5q49.617 49.5 120.5 49.5Zm-.353-58Q433-388 400.5-420.735q-32.5-32.736-32.5-79.5Q368-547 400.735-579.5q32.736-32.5 79.5-32.5Q527-612 559.5-579.265q32.5 32.736 32.5 79.5Q592-453 559.265-420.5q-32.736 32.5-79.5 32.5ZM480-200q-146 0-264-83T40-500q58-134 176-217t264-83q146 0 264 83t176 217q-58 134-176 217t-264 83Zm0-300Zm-.169 240Q601-260 702.5-325.5 804-391 857-500q-53-109-154.331-174.5-101.332-65.5-222.5-65.5Q359-740 257.5-674.5 156-609 102-500q54 109 155.331 174.5 101.332 65.5 222.5 65.5Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
8
packages/editor/src/types/menu.interface.ts
Normal file
8
packages/editor/src/types/menu.interface.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export interface MenuItem {
|
||||||
|
id: string;
|
||||||
|
label?: string;
|
||||||
|
shortcut?: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
component?: any;
|
||||||
|
children?: MenuItem[];
|
||||||
|
}
|
@ -13,7 +13,8 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "preserve",
|
"allowJs": true,
|
||||||
|
"jsx": "preserve"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/**/*.ts",
|
"src/**/*.ts",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import dts from 'vite-plugin-dts'
|
import dts from 'vite-plugin-dts';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@ -10,7 +10,7 @@ export default defineConfig({
|
|||||||
entry: 'src/index.ts',
|
entry: 'src/index.ts',
|
||||||
name: 'Editor',
|
name: 'Editor',
|
||||||
fileName: 'editor',
|
fileName: 'editor',
|
||||||
formats: ['es', 'cjs', 'umd']
|
formats: ['es', 'cjs', 'umd'],
|
||||||
},
|
},
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: ['vue'],
|
external: ['vue'],
|
||||||
@ -20,5 +20,5 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user