Browse Source

refactor(IconPicker): 样式及逻辑调整

dev
刘凯 1 year ago
parent
commit
3cdcc93095
  1. 55
      src/components/Icon/src/IconPicker.vue

55
src/components/Icon/src/IconPicker.vue

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, watch, watchEffect } from 'vue' import { ref, watch, watchEffect } from 'vue'
import { Empty, Input, Pagination, Popover } from 'ant-design-vue' import { Empty, Input, Popover } from 'ant-design-vue'
import { useDebounceFn } from '@vueuse/core' import { useDebounceFn } from '@vueuse/core'
import svgIcons from 'virtual:svg-icons-names' import svgIcons from 'virtual:svg-icons-names'
import SvgIcon from './SvgIcon.vue' import SvgIcon from './SvgIcon.vue'
@ -8,7 +8,6 @@ import { getIcons } from './icons'
import { useDesign } from '@/hooks/web/useDesign' import { useDesign } from '@/hooks/web/useDesign'
import { ScrollContainer } from '@/components/Container' import { ScrollContainer } from '@/components/Container'
import { usePagination } from '@/hooks/web/usePagination'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { copyText } from '@/utils/copyTextToClipboard' import { copyText } from '@/utils/copyTextToClipboard'
@ -39,15 +38,13 @@ const icons = isSvgMode ? getSvgIcons() : getIcons()
const currentSelect = ref('') const currentSelect = ref('')
const open = ref(false) const open = ref(false)
const currentList = ref(icons) const currentList = ref(icons.slice(0, props.pageSize))
const { t } = useI18n() const { t } = useI18n()
const { prefixCls } = useDesign('icon-picker') const { prefixCls } = useDesign('icon-picker')
const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100) const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100)
const { getPaginationList, getTotal, setCurrentPage } = usePagination(currentList, props.pageSize)
watchEffect(() => { watchEffect(() => {
currentSelect.value = props.value currentSelect.value = props.value
}) })
@ -60,24 +57,27 @@ watch(
}, },
) )
function handlePageChange(page: number) {
setCurrentPage(page)
}
function handleClick(icon: string) { function handleClick(icon: string) {
currentSelect.value = icon currentSelect.value = icon
if (props.copy) if (props.copy)
copyText(icon, t('component.icon.copy')) copyText(icon, t('component.icon.copy'))
} }
const hiddenLoadMore = ref(false)
function loadMoreIcons() {
currentList.value = icons.slice(0, currentList.value.length + props.pageSize)
hiddenLoadMore.value = currentList.value.length >= icons.length
}
function handleSearchChange(e: ChangeEvent) { function handleSearchChange(e: ChangeEvent) {
const value = e.target.value const value = e.target.value
if (!value) { if (!value) {
setCurrentPage(1) hiddenLoadMore.value = false
currentList.value = icons currentList.value = icons.slice(0, props.pageSize)
return return
} }
currentList.value = icons.filter(item => item.includes(value)) currentList.value = icons.filter(item => item.includes(value))
hiddenLoadMore.value = true
} }
</script> </script>
@ -90,32 +90,37 @@ function handleSearchChange(e: ChangeEvent) {
<Popover v-model="open" placement="bottomLeft" trigger="click" :overlay-class-name="`${prefixCls}-popover`"> <Popover v-model="open" placement="bottomLeft" trigger="click" :overlay-class-name="`${prefixCls}-popover`">
<template #title> <template #title>
<div class="flex justify-between"> <div class="flex justify-between">
<Input :placeholder="t('component.icon.search')" allow-clear @change="debounceHandleSearchChange" /> <Input placeholder="Search" allow-clear @change="debounceHandleSearchChange">
<template #prefix>
<span class="i-ant-design:search-outlined text-gray-600" />
</template>
</Input>
</div> </div>
</template> </template>
<template #content> <template #content>
<div v-if="getPaginationList.length"> <div v-if="currentList.length">
<ScrollContainer class="border border-t-0 border-solid"> <ScrollContainer>
<ul class="flex flex-wrap px-2"> <ul class="grid grid-cols-8 gap-y-2">
<li <li
v-for="icon in getPaginationList" :key="icon" v-for="icon in currentList" :key="icon"
:class="currentSelect === icon ? 'border border-primary' : ''" :class="currentSelect === icon ? '!text-primary' : ''"
class="mr-1 mt-1 w-1/8 flex cursor-pointer items-center justify-center border border-solid p-2 hover:border-primary" class="cursor-pointer text-center text-gray-600"
:title="icon" @click="handleClick(icon)" :title="icon" @click="handleClick(icon)"
> >
<!-- <Icon :icon="icon" :prefix="prefix" /> -->
<SvgIcon v-if="isSvgMode" :name="icon" /> <SvgIcon v-if="isSvgMode" :name="icon" />
<span v-else :class="icon" /> <span v-else :class="icon" class="text-18px" />
</li> </li>
</ul> </ul>
<div v-if="!hiddenLoadMore" class="mt-4 text-center text-gray-600">
<a-button size="small" @click="loadMoreIcons">
Load More
</a-button>
</div>
</ScrollContainer> </ScrollContainer>
<div v-if="getTotal >= pageSize" class="flex items-center justify-center py-2">
<Pagination show-less-items size="small" :page-size="pageSize" :total="getTotal" @change="handlePageChange" />
</div>
</div> </div>
<template v-else> <template v-else>
<div class="p-5"> <div class="p-5 text-gray-600">
<Empty /> <Empty />
</div> </div>
</template> </template>
@ -124,7 +129,7 @@ function handleSearchChange(e: ChangeEvent) {
<span v-if="isSvgMode && currentSelect" class="flex cursor-pointer items-center px-2 py-1"> <span v-if="isSvgMode && currentSelect" class="flex cursor-pointer items-center px-2 py-1">
<SvgIcon :name="currentSelect" /> <SvgIcon :name="currentSelect" />
</span> </span>
<span v-else :class="currentSelect || 'i-ion:apps-outline'" class="cursor-pointer px-4 py-2" /> <span v-else :class="currentSelect || 'i-ion:apps-outline'" class="cursor-pointer px-4 py-2 text-gray-600" />
</Popover> </Popover>
</template> </template>
</Input> </Input>