File size: 3,646 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
<template>
<div class="toolbar">
<Tabs
:tabs="currentTabs"
:value="toolbarState"
card
@update:value="key => setToolbarState(key as ToolbarStates)"
/>
<div class="content">
<component :is="currentPanelComponent"></component>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore } from '@/store'
import { ToolbarStates } from '@/types/toolbar'
import ElementStylePanel from './ElementStylePanel/index.vue'
import ElementPositionPanel from './ElementPositionPanel.vue'
import ElementAnimationPanel from './ElementAnimationPanel.vue'
import SlideDesignPanel from './SlideDesignPanel/index.vue'
import SlideAnimationPanel from './SlideAnimationPanel.vue'
import MultiPositionPanel from './MultiPositionPanel.vue'
import MultiStylePanel from './MultiStylePanel.vue'
import SymbolPanel from './SymbolPanel.vue'
import Tabs from '@/components/Tabs.vue'
interface ElementTabs {
label: string
key: ToolbarStates
}
const mainStore = useMainStore()
const { activeElementIdList, activeElementList, activeGroupElementId, handleElement, toolbarState } = storeToRefs(mainStore)
const elementTabs = computed<ElementTabs[]>(() => {
if (handleElement.value?.type === 'text') {
return [
{ label: '样式', key: ToolbarStates.EL_STYLE },
{ label: '符号', key: ToolbarStates.SYMBOL },
{ label: '位置', key: ToolbarStates.EL_POSITION },
{ label: '动画', key: ToolbarStates.EL_ANIMATION },
]
}
return [
{ label: '样式', key: ToolbarStates.EL_STYLE },
{ label: '位置', key: ToolbarStates.EL_POSITION },
{ label: '动画', key: ToolbarStates.EL_ANIMATION },
]
})
const slideTabs = [
{ label: '设计', key: ToolbarStates.SLIDE_DESIGN },
{ label: '切换', key: ToolbarStates.SLIDE_ANIMATION },
{ label: '动画', key: ToolbarStates.EL_ANIMATION },
]
const multiSelectTabs = [
{ label: '样式(多选)', key: ToolbarStates.MULTI_STYLE },
{ label: '位置(多选)', key: ToolbarStates.MULTI_POSITION },
]
const setToolbarState = (value: ToolbarStates) => {
mainStore.setToolbarState(value)
}
const currentTabs = computed(() => {
if (!activeElementIdList.value.length) return slideTabs
else if (activeElementIdList.value.length > 1) {
if (!activeGroupElementId.value) return multiSelectTabs
const activeGroupElement = activeElementList.value.find(item => item.id === activeGroupElementId.value)
if (activeGroupElement) return elementTabs.value
return multiSelectTabs
}
return elementTabs.value
})
watch(currentTabs, () => {
const currentTabsValue: ToolbarStates[] = currentTabs.value.map(tab => tab.key)
if (!currentTabsValue.includes(toolbarState.value)) {
mainStore.setToolbarState(currentTabsValue[0])
}
})
const currentPanelComponent = computed(() => {
const panelMap = {
[ToolbarStates.EL_STYLE]: ElementStylePanel,
[ToolbarStates.EL_POSITION]: ElementPositionPanel,
[ToolbarStates.EL_ANIMATION]: ElementAnimationPanel,
[ToolbarStates.SLIDE_DESIGN]: SlideDesignPanel,
[ToolbarStates.SLIDE_ANIMATION]: SlideAnimationPanel,
[ToolbarStates.MULTI_STYLE]: MultiStylePanel,
[ToolbarStates.MULTI_POSITION]: MultiPositionPanel,
[ToolbarStates.SYMBOL]: SymbolPanel,
}
return panelMap[toolbarState.value] || null
})
</script>
<style lang="scss" scoped>
.toolbar {
border-left: solid 1px $borderColor;
background-color: #fff;
display: flex;
flex-direction: column;
}
.content {
padding: 12px;
font-size: 13px;
@include overflow-overlay();
}
</style> |