CatPtain's picture
Upload 339 files
89ce340 verified
<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>