From 4490d5eeeb4389f94f90c9c45a30343324db2250 Mon Sep 17 00:00:00 2001 From: kailong321200875 <321200875@qq.com> Date: Sun, 24 Sep 2023 10:29:13 +0800 Subject: [PATCH] feat: IconPicker --- scripts/icon.ts | 13 +- src/components/IconPicker/src/IconPicker.vue | 161 ++++++++++++++++++- src/views/Components/IconPicker.vue | 11 +- types/components.d.ts | 4 +- 4 files changed, 174 insertions(+), 15 deletions(-) diff --git a/scripts/icon.ts b/scripts/icon.ts index e4a953fc8..27c33e56a 100644 --- a/scripts/icon.ts +++ b/scripts/icon.ts @@ -29,9 +29,9 @@ async function generateIcon() { // name: 'useType', // choices: [ // { key: 'local', value: 'local', name: 'Local' }, - // { key: 'onLine', value: 'onLine', name: 'OnLine' }, + // { key: 'onLine', value: 'onLine', name: 'OnLine' } // ], - // message: 'How to use icons?', + // message: 'How to use icons?' // }, { type: 'list', @@ -39,16 +39,11 @@ async function generateIcon() { choices: choices, message: 'Select the icon set that needs to be generated?' } - // { - // type: 'input', - // name: 'output', - // message: 'Select the icon set that needs to be generated?', - // default: 'src/components/Icon/data', - // }, ]) // ↓命令行问答的答案 .then(async (answers) => { const { iconSet } = answers + // const isOnLine = useType === 'onLine' const outputDir = path.resolve(process.cwd(), 'src/components/IconPicker/src/data') fs.ensureDir(outputDir) const genCollections = collections.filter((item) => [iconSet].includes(item.id)) @@ -67,8 +62,6 @@ async function generateIcon() { prefixSet.push(prefix) } } - // 将vite的缓存清空 - // fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite')) console.log( `✨ ${chalk.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]` ) diff --git a/src/components/IconPicker/src/IconPicker.vue b/src/components/IconPicker/src/IconPicker.vue index 70844e930..a98785bf8 100644 --- a/src/components/IconPicker/src/IconPicker.vue +++ b/src/components/IconPicker/src/IconPicker.vue @@ -2,10 +2,167 @@ import epIcons from './data/icons.ep' import antIcons from './data/icons.ant-design' import tIcons from './data/icons.tdesign' +import { useDesign } from '@/hooks/web/useDesign' +import { ElInput, ElPopover, ElScrollbar, ElTabs, ElTabPane, ElPagination } from 'element-plus' +import { useAppStore } from '@/store/modules/app' +import { computed, CSSProperties, ref, unref, watch } from 'vue' +import { nextTick } from 'vue' -console.log(epIcons, antIcons, tIcons) +const modelValue = defineModel() + +const appStore = useAppStore() + +const size = computed(() => appStore.getCurrentSize) + +const iconSize = computed(() => { + return size.value === 'small' + ? 'var(--el-component-size-small)' + : size.value === 'large' + ? 'var(--el-component-size-large)' + : 'var(--el-component-size)' +}) + +const iconWrapStyle = computed((): CSSProperties => { + return { + width: iconSize.value, + height: iconSize.value, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + boxShadow: '0 0 0 1px var(--el-input-border-color,var(--el-border-color)) inset', + position: 'relative', + left: '-1px', + cursor: 'pointer' + } +}) + +const { getPrefixCls } = useDesign() + +const prefixCls = getPrefixCls('icon-picker') + +const icons = [epIcons, antIcons, tIcons] + +const iconName = ref(icons[0].prefix) + +const currentIconNameIndex = computed(() => { + return icons.findIndex((item) => item.prefix === iconName.value) +}) + +const tabChange = () => { + currentPage.value = 1 +} + +const pageSize = ref(63) + +const currentPage = ref(1) + +const filterIcons = (icons: string[]) => { + const start = (currentPage.value - 1) * pageSize.value + const end = currentPage.value * pageSize.value + return icons.slice(start, end) +} + +watch( + () => modelValue.value, + (val) => { + init(val) + }, + { + immediate: true + } +) + +async function init(icon?: string) { + if (!icon) return + const iconInfo = icon.split(':') + iconName.value = iconInfo[0] + const wrapIndex = icons.findIndex((item) => item.prefix === iconInfo[0]) + // 查询当前icon的索引 + const index = icons[wrapIndex].icons.findIndex((item) => item === icon) + // 计算当前icon的页码 + await nextTick() + currentPage.value = Math.ceil((index + 1) / pageSize.value) +} + +const popoverShow = () => { + init(unref(modelValue)) +} + +const iconSelect = (icon: string) => { + modelValue.value = icon +} + + diff --git a/src/views/Components/IconPicker.vue b/src/views/Components/IconPicker.vue index 59fc460c3..8da8d4bd4 100644 --- a/src/views/Components/IconPicker.vue +++ b/src/views/Components/IconPicker.vue @@ -1,7 +1,16 @@ diff --git a/types/components.d.ts b/types/components.d.ts index 33f73392c..14c4eea88 100644 --- a/types/components.d.ts +++ b/types/components.d.ts @@ -1,7 +1,7 @@ declare module 'vue' { export interface GlobalComponents { - Icon: typeof import('../components/Icon/src/Icon.vue')['default'] - Permission: typeof import('../components/Permission/src/Permission.vue')['default'] + Icon: (typeof import('../components/Icon/src/Icon.vue'))['default'] + Permission: (typeof import('../components/Permission/src/Permission.vue'))['default'] } }