|
<template> |
|
<div class="symbol-panel"> |
|
<Tabs |
|
:tabs="tabs" |
|
v-model:value="selectedSymbolKey" |
|
:tabsStyle="{ marginBottom: '8px' }" |
|
spaceBetween |
|
/> |
|
<div class="pool"> |
|
<div class="symbol-item" v-for="(item, index) in symbolPool" :key="index" @click="selectSymbol(item)"> |
|
<div class="symbol">{{item}}</div> |
|
</div> |
|
</div> |
|
</div> |
|
</template> |
|
|
|
<script lang="ts" setup> |
|
import { computed, ref } from 'vue' |
|
import { SYMBOL_LIST } from '@/configs/symbol' |
|
import emitter, { EmitterEvents } from '@/utils/emitter' |
|
import Tabs from '@/components/Tabs.vue' |
|
|
|
const selectedSymbolKey = ref(SYMBOL_LIST[0].key) |
|
const symbolPool = computed(() => { |
|
const selectedSymbol = SYMBOL_LIST.find(item => item.key === selectedSymbolKey.value) |
|
return selectedSymbol?.children || [] |
|
}) |
|
|
|
const tabs = SYMBOL_LIST.map(item => ({ |
|
key: item.key, |
|
label: item.label, |
|
})) |
|
|
|
const selectSymbol = (value: string) => { |
|
emitter.emit(EmitterEvents.RICH_TEXT_COMMAND, { action: { command: 'insert', value } }) |
|
} |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.symbol-panel { |
|
height: 100%; |
|
display: flex; |
|
flex-direction: column; |
|
|
|
.pool { |
|
padding: 5px 12px; |
|
margin: 0 -12px; |
|
flex: 1; |
|
font-size: 18px; |
|
|
|
@include overflow-overlay(); |
|
@include flex-grid-layout(); |
|
} |
|
.symbol-item { |
|
@include flex-grid-layout-children(5, 18%); |
|
|
|
height: 0; |
|
padding-bottom: 18%; |
|
position: relative; |
|
cursor: pointer; |
|
border: 1px solid $borderColor; |
|
|
|
&:hover { |
|
color: $themeColor; |
|
} |
|
|
|
.symbol { |
|
@include absolute-0(); |
|
|
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
background-color: #fff; |
|
} |
|
} |
|
} |
|
</style> |
|
|