初始版本提交

This commit is contained in:
yaoyn
2024-02-05 09:15:37 +08:00
parent b52d4414be
commit 445292105f
1848 changed files with 236859 additions and 75 deletions

View File

@ -0,0 +1,793 @@
export default {
prefix: 'ant-design',
icons: [
'account-book-filled',
'account-book-outlined',
'account-book-twotone',
'aim-outlined',
'alert-filled',
'alert-outlined',
'alert-twotone',
'alibaba-outlined',
'align-center-outlined',
'align-left-outlined',
'align-right-outlined',
'alipay-circle-filled',
'alipay-circle-outlined',
'alipay-outlined',
'alipay-square-filled',
'aliwangwang-filled',
'aliwangwang-outlined',
'aliyun-outlined',
'amazon-circle-filled',
'amazon-outlined',
'amazon-square-filled',
'android-filled',
'android-outlined',
'ant-cloud-outlined',
'ant-design-outlined',
'apartment-outlined',
'api-filled',
'api-outlined',
'api-twotone',
'apple-filled',
'apple-outlined',
'appstore-add-outlined',
'appstore-filled',
'appstore-outlined',
'appstore-twotone',
'area-chart-outlined',
'arrow-down-outlined',
'arrow-left-outlined',
'arrow-right-outlined',
'arrow-up-outlined',
'arrows-alt-outlined',
'audio-filled',
'audio-muted-outlined',
'audio-outlined',
'audio-twotone',
'audit-outlined',
'backward-filled',
'backward-outlined',
'bank-filled',
'bank-outlined',
'bank-twotone',
'bar-chart-outlined',
'barcode-outlined',
'bars-outlined',
'behance-circle-filled',
'behance-outlined',
'behance-square-filled',
'behance-square-outlined',
'bell-filled',
'bell-outlined',
'bell-twotone',
'bg-colors-outlined',
'block-outlined',
'bold-outlined',
'book-filled',
'book-outlined',
'book-twotone',
'border-bottom-outlined',
'border-horizontal-outlined',
'border-inner-outlined',
'border-left-outlined',
'border-outer-outlined',
'border-outlined',
'border-right-outlined',
'border-top-outlined',
'border-verticle-outlined',
'borderless-table-outlined',
'box-plot-filled',
'box-plot-outlined',
'box-plot-twotone',
'branches-outlined',
'bug-filled',
'bug-outlined',
'bug-twotone',
'build-filled',
'build-outlined',
'build-twotone',
'bulb-filled',
'bulb-outlined',
'bulb-twotone',
'calculator-filled',
'calculator-outlined',
'calculator-twotone',
'calendar-filled',
'calendar-outlined',
'calendar-twotone',
'camera-filled',
'camera-outlined',
'camera-twotone',
'car-filled',
'car-outlined',
'car-twotone',
'caret-down-filled',
'caret-down-outlined',
'caret-left-filled',
'caret-left-outlined',
'caret-right-filled',
'caret-right-outlined',
'caret-up-filled',
'caret-up-outlined',
'carry-out-filled',
'carry-out-outlined',
'carry-out-twotone',
'check-circle-filled',
'check-circle-outlined',
'check-circle-twotone',
'check-outlined',
'check-square-filled',
'check-square-outlined',
'check-square-twotone',
'chrome-filled',
'chrome-outlined',
'ci-circle-filled',
'ci-circle-outlined',
'ci-circle-twotone',
'ci-outlined',
'ci-twotone',
'clear-outlined',
'clock-circle-filled',
'clock-circle-outlined',
'clock-circle-twotone',
'close-circle-filled',
'close-circle-outlined',
'close-circle-twotone',
'close-outlined',
'close-square-filled',
'close-square-outlined',
'close-square-twotone',
'cloud-download-outlined',
'cloud-filled',
'cloud-outlined',
'cloud-server-outlined',
'cloud-sync-outlined',
'cloud-twotone',
'cloud-upload-outlined',
'cluster-outlined',
'code-filled',
'code-outlined',
'code-sandbox-circle-filled',
'code-sandbox-outlined',
'code-sandbox-square-filled',
'code-twotone',
'codepen-circle-filled',
'codepen-circle-outlined',
'codepen-outlined',
'codepen-square-filled',
'coffee-outlined',
'column-height-outlined',
'column-width-outlined',
'comment-outlined',
'compass-filled',
'compass-outlined',
'compass-twotone',
'compress-outlined',
'console-sql-outlined',
'contacts-filled',
'contacts-outlined',
'contacts-twotone',
'container-filled',
'container-outlined',
'container-twotone',
'control-filled',
'control-outlined',
'control-twotone',
'copy-filled',
'copy-outlined',
'copy-twotone',
'copyright-circle-filled',
'copyright-circle-outlined',
'copyright-circle-twotone',
'copyright-outlined',
'copyright-twotone',
'credit-card-filled',
'credit-card-outlined',
'credit-card-twotone',
'crown-filled',
'crown-outlined',
'crown-twotone',
'customer-service-filled',
'customer-service-outlined',
'customer-service-twotone',
'dash-outlined',
'dashboard-filled',
'dashboard-outlined',
'dashboard-twotone',
'database-filled',
'database-outlined',
'database-twotone',
'delete-column-outlined',
'delete-filled',
'delete-outlined',
'delete-row-outlined',
'delete-twotone',
'delivered-procedure-outlined',
'deployment-unit-outlined',
'desktop-outlined',
'diff-filled',
'diff-outlined',
'diff-twotone',
'dingding-outlined',
'dingtalk-circle-filled',
'dingtalk-outlined',
'dingtalk-square-filled',
'disconnect-outlined',
'dislike-filled',
'dislike-outlined',
'dislike-twotone',
'dollar-circle-filled',
'dollar-circle-outlined',
'dollar-circle-twotone',
'dollar-outlined',
'dollar-twotone',
'dot-chart-outlined',
'double-left-outlined',
'double-right-outlined',
'down-circle-filled',
'down-circle-outlined',
'down-circle-twotone',
'down-outlined',
'down-square-filled',
'down-square-outlined',
'down-square-twotone',
'download-outlined',
'drag-outlined',
'dribbble-circle-filled',
'dribbble-outlined',
'dribbble-square-filled',
'dribbble-square-outlined',
'dropbox-circle-filled',
'dropbox-outlined',
'dropbox-square-filled',
'edit-filled',
'edit-outlined',
'edit-twotone',
'ellipsis-outlined',
'enter-outlined',
'environment-filled',
'environment-outlined',
'environment-twotone',
'euro-circle-filled',
'euro-circle-outlined',
'euro-circle-twotone',
'euro-outlined',
'euro-twotone',
'exception-outlined',
'exclamation-circle-filled',
'exclamation-circle-outlined',
'exclamation-circle-twotone',
'exclamation-outlined',
'expand-alt-outlined',
'expand-outlined',
'experiment-filled',
'experiment-outlined',
'experiment-twotone',
'export-outlined',
'eye-filled',
'eye-invisible-filled',
'eye-invisible-outlined',
'eye-invisible-twotone',
'eye-outlined',
'eye-twotone',
'facebook-filled',
'facebook-outlined',
'fall-outlined',
'fast-backward-filled',
'fast-backward-outlined',
'fast-forward-filled',
'fast-forward-outlined',
'field-binary-outlined',
'field-number-outlined',
'field-string-outlined',
'field-time-outlined',
'file-add-filled',
'file-add-outlined',
'file-add-twotone',
'file-done-outlined',
'file-excel-filled',
'file-excel-outlined',
'file-excel-twotone',
'file-exclamation-filled',
'file-exclamation-outlined',
'file-exclamation-twotone',
'file-filled',
'file-gif-outlined',
'file-image-filled',
'file-image-outlined',
'file-image-twotone',
'file-jpg-outlined',
'file-markdown-filled',
'file-markdown-outlined',
'file-markdown-twotone',
'file-outlined',
'file-pdf-filled',
'file-pdf-outlined',
'file-pdf-twotone',
'file-ppt-filled',
'file-ppt-outlined',
'file-ppt-twotone',
'file-protect-outlined',
'file-search-outlined',
'file-sync-outlined',
'file-text-filled',
'file-text-outlined',
'file-text-twotone',
'file-twotone',
'file-unknown-filled',
'file-unknown-outlined',
'file-unknown-twotone',
'file-word-filled',
'file-word-outlined',
'file-word-twotone',
'file-zip-filled',
'file-zip-outlined',
'file-zip-twotone',
'filter-filled',
'filter-outlined',
'filter-twotone',
'fire-filled',
'fire-outlined',
'fire-twotone',
'flag-filled',
'flag-outlined',
'flag-twotone',
'folder-add-filled',
'folder-add-outlined',
'folder-add-twotone',
'folder-filled',
'folder-open-filled',
'folder-open-outlined',
'folder-open-twotone',
'folder-outlined',
'folder-twotone',
'folder-view-outlined',
'font-colors-outlined',
'font-size-outlined',
'fork-outlined',
'form-outlined',
'format-painter-filled',
'format-painter-outlined',
'forward-filled',
'forward-outlined',
'frown-filled',
'frown-outlined',
'frown-twotone',
'fullscreen-exit-outlined',
'fullscreen-outlined',
'function-outlined',
'fund-filled',
'fund-outlined',
'fund-projection-screen-outlined',
'fund-twotone',
'fund-view-outlined',
'funnel-plot-filled',
'funnel-plot-outlined',
'funnel-plot-twotone',
'gateway-outlined',
'gif-outlined',
'gift-filled',
'gift-outlined',
'gift-twotone',
'github-filled',
'github-outlined',
'gitlab-filled',
'gitlab-outlined',
'global-outlined',
'gold-filled',
'gold-outlined',
'gold-twotone',
'golden-filled',
'google-circle-filled',
'google-outlined',
'google-plus-circle-filled',
'google-plus-outlined',
'google-plus-square-filled',
'google-square-filled',
'group-outlined',
'hdd-filled',
'hdd-outlined',
'hdd-twotone',
'heart-filled',
'heart-outlined',
'heart-twotone',
'heat-map-outlined',
'highlight-filled',
'highlight-outlined',
'highlight-twotone',
'history-outlined',
'home-filled',
'home-outlined',
'home-twotone',
'hourglass-filled',
'hourglass-outlined',
'hourglass-twotone',
'html5-filled',
'html5-outlined',
'html5-twotone',
'idcard-filled',
'idcard-outlined',
'idcard-twotone',
'ie-circle-filled',
'ie-outlined',
'ie-square-filled',
'import-outlined',
'inbox-outlined',
'info-circle-filled',
'info-circle-outlined',
'info-circle-twotone',
'info-outlined',
'insert-row-above-outlined',
'insert-row-below-outlined',
'insert-row-left-outlined',
'insert-row-right-outlined',
'instagram-filled',
'instagram-outlined',
'insurance-filled',
'insurance-outlined',
'insurance-twotone',
'interaction-filled',
'interaction-outlined',
'interaction-twotone',
'issues-close-outlined',
'italic-outlined',
'key-outlined',
'laptop-outlined',
'layout-filled',
'layout-outlined',
'layout-twotone',
'left-circle-filled',
'left-circle-outlined',
'left-circle-twotone',
'left-outlined',
'left-square-filled',
'left-square-outlined',
'left-square-twotone',
'like-filled',
'like-outlined',
'like-twotone',
'line-chart-outlined',
'line-height-outlined',
'line-outlined',
'link-outlined',
'linkedin-filled',
'linkedin-outlined',
'loading-3-quarters-outlined',
'loading-outlined',
'lock-filled',
'lock-outlined',
'lock-twotone',
'login-outlined',
'logout-outlined',
'mac-command-filled',
'mac-command-outlined',
'mail-filled',
'mail-outlined',
'mail-twotone',
'man-outlined',
'medicine-box-filled',
'medicine-box-outlined',
'medicine-box-twotone',
'medium-circle-filled',
'medium-outlined',
'medium-square-filled',
'medium-workmark-outlined',
'meh-filled',
'meh-outlined',
'meh-twotone',
'menu-fold-outlined',
'menu-outlined',
'menu-unfold-outlined',
'merge-cells-outlined',
'message-filled',
'message-outlined',
'message-twotone',
'minus-circle-filled',
'minus-circle-outlined',
'minus-circle-twotone',
'minus-outlined',
'minus-square-filled',
'minus-square-outlined',
'minus-square-twotone',
'mobile-filled',
'mobile-outlined',
'mobile-twotone',
'money-collect-filled',
'money-collect-outlined',
'money-collect-twotone',
'monitor-outlined',
'more-outlined',
'node-collapse-outlined',
'node-expand-outlined',
'node-index-outlined',
'notification-filled',
'notification-outlined',
'notification-twotone',
'number-outlined',
'one-to-one-outlined',
'ordered-list-outlined',
'paper-clip-outlined',
'partition-outlined',
'pause-circle-filled',
'pause-circle-outlined',
'pause-circle-twotone',
'pause-outlined',
'pay-circle-filled',
'pay-circle-outlined',
'percentage-outlined',
'phone-filled',
'phone-outlined',
'phone-twotone',
'pic-center-outlined',
'pic-left-outlined',
'pic-right-outlined',
'picture-filled',
'picture-outlined',
'picture-twotone',
'pie-chart-filled',
'pie-chart-outlined',
'pie-chart-twotone',
'play-circle-filled',
'play-circle-outlined',
'play-circle-twotone',
'play-square-filled',
'play-square-outlined',
'play-square-twotone',
'plus-circle-filled',
'plus-circle-outlined',
'plus-circle-twotone',
'plus-outlined',
'plus-square-filled',
'plus-square-outlined',
'plus-square-twotone',
'pound-circle-filled',
'pound-circle-outlined',
'pound-circle-twotone',
'pound-outlined',
'poweroff-outlined',
'printer-filled',
'printer-outlined',
'printer-twotone',
'profile-filled',
'profile-outlined',
'profile-twotone',
'project-filled',
'project-outlined',
'project-twotone',
'property-safety-filled',
'property-safety-outlined',
'property-safety-twotone',
'pull-request-outlined',
'pushpin-filled',
'pushpin-outlined',
'pushpin-twotone',
'qq-circle-filled',
'qq-outlined',
'qq-square-filled',
'qrcode-outlined',
'question-circle-filled',
'question-circle-outlined',
'question-circle-twotone',
'question-outlined',
'radar-chart-outlined',
'radius-bottomleft-outlined',
'radius-bottomright-outlined',
'radius-setting-outlined',
'radius-upleft-outlined',
'radius-upright-outlined',
'read-filled',
'read-outlined',
'reconciliation-filled',
'reconciliation-outlined',
'reconciliation-twotone',
'red-envelope-filled',
'red-envelope-outlined',
'red-envelope-twotone',
'reddit-circle-filled',
'reddit-outlined',
'reddit-square-filled',
'redo-outlined',
'reload-outlined',
'rest-filled',
'rest-outlined',
'rest-twotone',
'retweet-outlined',
'right-circle-filled',
'right-circle-outlined',
'right-circle-twotone',
'right-outlined',
'right-square-filled',
'right-square-outlined',
'right-square-twotone',
'rise-outlined',
'robot-filled',
'robot-outlined',
'rocket-filled',
'rocket-outlined',
'rocket-twotone',
'rollback-outlined',
'rotate-left-outlined',
'rotate-right-outlined',
'safety-certificate-filled',
'safety-certificate-outlined',
'safety-certificate-twotone',
'safety-outlined',
'save-filled',
'save-outlined',
'save-twotone',
'scan-outlined',
'schedule-filled',
'schedule-outlined',
'schedule-twotone',
'scissor-outlined',
'search-outlined',
'security-scan-filled',
'security-scan-outlined',
'security-scan-twotone',
'select-outlined',
'send-outlined',
'setting-filled',
'setting-outlined',
'setting-twotone',
'shake-outlined',
'share-alt-outlined',
'shop-filled',
'shop-outlined',
'shop-twotone',
'shopping-cart-outlined',
'shopping-filled',
'shopping-outlined',
'shopping-twotone',
'shrink-outlined',
'signal-filled',
'sisternode-outlined',
'sketch-circle-filled',
'sketch-outlined',
'sketch-square-filled',
'skin-filled',
'skin-outlined',
'skin-twotone',
'skype-filled',
'skype-outlined',
'slack-circle-filled',
'slack-outlined',
'slack-square-filled',
'slack-square-outlined',
'sliders-filled',
'sliders-outlined',
'sliders-twotone',
'small-dash-outlined',
'smile-filled',
'smile-outlined',
'smile-twotone',
'snippets-filled',
'snippets-outlined',
'snippets-twotone',
'solution-outlined',
'sort-ascending-outlined',
'sort-descending-outlined',
'sound-filled',
'sound-outlined',
'sound-twotone',
'split-cells-outlined',
'star-filled',
'star-outlined',
'star-twotone',
'step-backward-filled',
'step-backward-outlined',
'step-forward-filled',
'step-forward-outlined',
'stock-outlined',
'stop-filled',
'stop-outlined',
'stop-twotone',
'strikethrough-outlined',
'subnode-outlined',
'swap-left-outlined',
'swap-outlined',
'swap-right-outlined',
'switcher-filled',
'switcher-outlined',
'switcher-twotone',
'sync-outlined',
'table-outlined',
'tablet-filled',
'tablet-outlined',
'tablet-twotone',
'tag-filled',
'tag-outlined',
'tag-twotone',
'tags-filled',
'tags-outlined',
'tags-twotone',
'taobao-circle-filled',
'taobao-circle-outlined',
'taobao-outlined',
'taobao-square-filled',
'team-outlined',
'thunderbolt-filled',
'thunderbolt-outlined',
'thunderbolt-twotone',
'to-top-outlined',
'tool-filled',
'tool-outlined',
'tool-twotone',
'trademark-circle-filled',
'trademark-circle-outlined',
'trademark-circle-twotone',
'trademark-outlined',
'transaction-outlined',
'translation-outlined',
'trophy-filled',
'trophy-outlined',
'trophy-twotone',
'twitter-circle-filled',
'twitter-outlined',
'twitter-square-filled',
'underline-outlined',
'undo-outlined',
'ungroup-outlined',
'unlock-filled',
'unlock-outlined',
'unlock-twotone',
'unordered-list-outlined',
'up-circle-filled',
'up-circle-outlined',
'up-circle-twotone',
'up-outlined',
'up-square-filled',
'up-square-outlined',
'up-square-twotone',
'upload-outlined',
'usb-filled',
'usb-outlined',
'usb-twotone',
'user-add-outlined',
'user-delete-outlined',
'user-outlined',
'user-switch-outlined',
'usergroup-add-outlined',
'usergroup-delete-outlined',
'verified-outlined',
'vertical-align-bottom-outlined',
'vertical-align-middle-outlined',
'vertical-align-top-outlined',
'vertical-left-outlined',
'vertical-right-outlined',
'video-camera-add-outlined',
'video-camera-filled',
'video-camera-outlined',
'video-camera-twotone',
'wallet-filled',
'wallet-outlined',
'wallet-twotone',
'warning-filled',
'warning-outlined',
'warning-twotone',
'wechat-filled',
'wechat-outlined',
'weibo-circle-filled',
'weibo-circle-outlined',
'weibo-outlined',
'weibo-square-filled',
'weibo-square-outlined',
'whats-app-outlined',
'wifi-outlined',
'windows-filled',
'windows-outlined',
'woman-outlined',
'yahoo-filled',
'yahoo-outlined',
'youtube-filled',
'youtube-outlined',
'yuque-filled',
'yuque-outlined',
'zhihu-circle-filled',
'zhihu-outlined',
'zhihu-square-filled',
'zoom-in-outlined',
'zoom-out-outlined',
],
};

View File

@ -0,0 +1,7 @@
import Icon from './src/Icon.vue';
import SvgIcon from './src/SvgIcon.vue';
import IconPicker from './src/IconPicker.vue';
export { Icon, IconPicker, SvgIcon };
export default Icon;

View File

@ -0,0 +1,121 @@
<template>
<SvgIcon
:size="size"
:name="getSvgIcon"
v-if="isSvgIcon"
:class="[$attrs.class, 'anticon']"
:spin="spin"
/>
<span
v-else
ref="elRef"
:class="[$attrs.class, 'app-iconify anticon', spin && 'app-iconify-spin']"
:style="getWrapStyle"
></span>
</template>
<script lang="ts">
import type { PropType } from 'vue';
import {
defineComponent,
ref,
watch,
onMounted,
nextTick,
unref,
computed,
CSSProperties,
} from 'vue';
import SvgIcon from './SvgIcon.vue';
import Iconify from '@purge-icons/generated';
import { isString } from '/@/utils/is';
import { propTypes } from '/@/utils/propTypes';
const SVG_END_WITH_FLAG = '|svg';
export default defineComponent({
name: 'Icon',
components: { SvgIcon },
props: {
// icon name
icon: propTypes.string,
// icon color
color: propTypes.string,
// icon size
size: {
type: [String, Number] as PropType<string | number>,
default: 16,
},
spin: propTypes.bool.def(false),
prefix: propTypes.string.def(''),
},
setup(props) {
const elRef = ref<ElRef>(null);
const isSvgIcon = computed(() => props.icon?.endsWith(SVG_END_WITH_FLAG));
const getSvgIcon = computed(() => props.icon.replace(SVG_END_WITH_FLAG, ''));
const getIconRef = computed(() => `${props.prefix ? props.prefix + ':' : ''}${props.icon}`);
const update = async () => {
if (unref(isSvgIcon)) return;
const el = unref(elRef);
if (!el) return;
await nextTick();
const icon = unref(getIconRef);
if (!icon) return;
const svg = Iconify.renderSVG(icon, {});
if (svg) {
el.textContent = '';
el.appendChild(svg);
} else {
const span = document.createElement('span');
span.className = 'iconify';
span.dataset.icon = icon;
el.textContent = '';
el.appendChild(span);
}
};
const getWrapStyle = computed((): CSSProperties => {
const { size, color } = props;
let fs = size;
if (isString(size)) {
fs = parseInt(size, 10);
}
return {
fontSize: `${fs}px`,
color: color,
display: 'inline-flex',
};
});
watch(() => props.icon, update, { flush: 'post' });
onMounted(update);
return { elRef, getWrapStyle, isSvgIcon, getSvgIcon };
},
});
</script>
<style lang="less">
.app-iconify {
display: inline-block;
// vertical-align: middle;
&-spin {
svg {
animation: loadingCircle 1s infinite linear;
}
}
}
span.iconify {
display: block;
min-width: 1em;
min-height: 1em;
background-color: @iconify-bg-color;
border-radius: 100%;
}
</style>

View File

@ -0,0 +1,198 @@
<template>
<a-input
:disabled="disabled"
:style="{ width }"
:placeholder="t('点击选择图标')"
:class="prefixCls"
:readonly="readonly"
v-model:value="currentSelect"
>
<template #addonAfter>
<a-popover
placement="bottomLeft"
trigger="click"
v-model="visible"
:overlayClassName="`${prefixCls}-popover`"
>
<template #title>
<div class="flex justify-between">
<a-input :placeholder="t('搜索图标')" @change="debounceHandleSearchChange" allowClear />
</div>
</template>
<template #content>
<div v-if="getPaginationList.length">
<ScrollContainer class="border border-solid border-t-0">
<ul class="flex flex-wrap px-2">
<li
v-for="icon in getPaginationList"
:key="icon"
:class="currentSelect === icon ? 'border border-primary' : ''"
class="p-2 w-1/8 cursor-pointer mr-1 mt-1 flex justify-center items-center border border-solid hover:border-primary"
@click="handleClick(icon)"
:title="icon"
>
<!-- <Icon :icon="icon" :prefix="prefix" /> -->
<SvgIcon v-if="isSvgMode" :name="icon" />
<Icon :icon="icon" v-else />
</li>
</ul>
</ScrollContainer>
<div class="flex py-2 items-center" v-if="getTotal >= pageSize">
<a-pagination
size="small"
:pageSize="pageSize"
:total="getTotal"
:show-size-changer="false"
@change="handlePageChange"
/>
</div>
</div>
<template v-else
><div class="p-5"><a-empty /></div>
</template>
</template>
<span class="cursor-pointer px-2 py-1 flex items-center" v-if="isSvgMode && currentSelect">
<SvgIcon :name="currentSelect" />
</span>
<Icon
:icon="currentSelect || 'ant-design:ellipsis-outlined'"
class="cursor-pointer px-2 py-1"
v-else
/>
</a-popover>
</template>
</a-input>
</template>
<script lang="ts" setup>
import { ref, watchEffect, watch, unref, useAttrs } from 'vue';
import { useDesign } from '/@/hooks/web/useDesign';
import { ScrollContainer } from '/@/components/Container';
import { Input, Popover, Pagination, Empty } from 'ant-design-vue';
import Icon from './Icon.vue';
import SvgIcon from './SvgIcon.vue';
import iconsData from '../data/icons.data';
import { propTypes } from '/@/utils/propTypes';
import { usePagination } from '/@/hooks/web/usePagination';
import { useDebounceFn } from '@vueuse/core';
import { useI18n } from '/@/hooks/web/useI18n';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
import { useMessage } from '/@/hooks/web/useMessage';
import svgIcons from 'virtual:svg-icons-names';
// 没有使用别名引入是因为WebStorm当前版本还不能正确识别会报unused警告
const AInput = Input;
const APopover = Popover;
const APagination = Pagination;
const AEmpty = Empty;
function getIcons() {
const data = iconsData as any;
const prefix: string = data?.prefix ?? '';
let result: string[] = [];
if (prefix) {
result = (data?.icons ?? []).map((item) => `${prefix}:${item}`);
} else if (Array.isArray(iconsData)) {
result = iconsData as string[];
}
return result;
}
function getSvgIcons() {
return svgIcons.map((icon) => icon.replace('icon-', ''));
}
const props = defineProps({
value: propTypes.string,
width: propTypes.string.def('100%'),
pageSize: propTypes.number.def(140),
copy: propTypes.bool.def(false),
mode: propTypes.oneOf(['svg', 'iconify']).def('iconify'),
disabled: propTypes.bool.def(true),
readonly: propTypes.bool.def(true),
});
const emit = defineEmits(['change', 'update:value']);
const isSvgMode = props.mode === 'svg';
const icons = isSvgMode ? getSvgIcons() : getIcons();
const currentSelect = ref('');
const visible = ref(false);
const currentList = ref(icons);
const attrs = useAttrs();
const { t } = useI18n();
const { prefixCls } = useDesign('icon-picker');
const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100);
const { clipboardRef, isSuccessRef } = useCopyToClipboard(props.value);
const { createMessage } = useMessage();
const { getPaginationList, getTotal, setCurrentPage } = usePagination(
currentList,
props.pageSize,
);
watchEffect(() => {
currentSelect.value = props.value;
});
watch(
() => currentSelect.value,
(v) => {
emit('update:value', v);
return emit('change', v);
},
);
function handlePageChange(page: number) {
setCurrentPage(page);
}
function handleClick(icon: string) {
if (attrs.disabled) {
return;
}
currentSelect.value = icon;
if (props.copy) {
clipboardRef.value = icon;
if (unref(isSuccessRef)) {
createMessage.success(t('复制图标成功!'));
}
}
}
function handleSearchChange(e: ChangeEvent) {
const value = e.target.value;
if (!value) {
setCurrentPage(1);
currentList.value = icons;
return;
}
currentList.value = icons.filter((item) => item.includes(value));
}
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-icon-picker';
.@{prefix-cls} {
.ant-input-group-addon {
padding: 0;
}
&-popover {
width: 400px;
.ant-popover-inner-content {
padding: 0;
}
.scrollbar {
height: 280px;
}
}
}
</style>

View File

@ -0,0 +1,65 @@
<template>
<svg
:class="[prefixCls, $attrs.class, spin && 'svg-icon-spin']"
:style="getStyle"
aria-hidden="true"
>
<use :xlink:href="symbolId" />
</svg>
</template>
<script lang="ts">
import type { CSSProperties } from 'vue';
import { defineComponent, computed } from 'vue';
import { useDesign } from '/@/hooks/web/useDesign';
export default defineComponent({
name: 'SvgIcon',
props: {
prefix: {
type: String,
default: 'icon',
},
name: {
type: String,
required: true,
},
size: {
type: [Number, String],
default: 16,
},
spin: {
type: Boolean,
default: false,
},
},
setup(props) {
const { prefixCls } = useDesign('svg-icon');
const symbolId = computed(() => `#${props.prefix}-${props.name}`);
const getStyle = computed((): CSSProperties => {
const { size } = props;
let s = `${size}`;
s = `${s.replace('px', '')}px`;
return {
width: s,
height: s,
};
});
return { symbolId, prefixCls, getStyle };
},
});
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-svg-icon';
.@{prefix-cls} {
display: inline-block;
overflow: hidden;
vertical-align: -0.15em;
fill: currentColor;
}
.svg-icon-spin {
animation: loadingCircle 1s infinite linear;
}
</style>