Browse Source

perf(IconPicker): input trigger popover by click (#3278)

bowen 1 year ago
parent
commit
2bbc2d2811
1 changed files with 35 additions and 16 deletions
  1. 35 16
      src/components/Icon/src/IconPicker.vue

+ 35 - 16
src/components/Icon/src/IconPicker.vue

@@ -1,10 +1,11 @@
 <template>
   <a-input
-    disabled
+    readonly
     :style="{ width }"
     :placeholder="t('component.icon.placeholder')"
     :class="prefixCls"
     v-model:value="currentSelect"
+    @click="triggerPopover"
   >
     <template #addonAfter>
       <a-popover
@@ -56,10 +57,19 @@
           </template>
         </template>
 
-        <span class="cursor-pointer px-2 py-1 flex items-center" v-if="isSvgMode && currentSelect">
-          <SvgIcon :name="currentSelect" />
-        </span>
-        <Icon :icon="currentSelect || 'ion:apps-outline'" class="cursor-pointer px-2 py-1" v-else />
+        <div ref="trigger">
+          <span
+            class="cursor-pointer px-2 py-1 flex items-center"
+            v-if="isSvgMode && currentSelect"
+          >
+            <SvgIcon :name="currentSelect" />
+          </span>
+          <Icon
+            :icon="currentSelect || 'ion:apps-outline'"
+            class="cursor-pointer px-2 py-1"
+            v-else
+          />
+        </div>
       </a-popover>
     </template>
   </a-input>
@@ -78,6 +88,7 @@
   import { useI18n } from '/@/hooks/web/useI18n';
   import svgIcons from 'virtual:svg-icons-names';
   import { copyText } from '/@/utils/copyTextToClipboard';
+
   // 没有使用别名引入,是因为WebStorm当前版本还不能正确识别,会报unused警告
   const AInput = Input;
   const APopover = Popover;
@@ -85,15 +96,8 @@
   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;
+    const prefix = iconsData.prefix;
+    return iconsData.icons.map((icon) => `${prefix}:${icon}`);
   }
 
   function getSvgIcons() {
@@ -116,6 +120,11 @@
     mode: 'iconify',
   });
 
+  // Don't inherit FormItem disabled、placeholder...
+  defineOptions({
+    inheritAttrs: false,
+  });
+
   const emit = defineEmits(['change', 'update:value']);
 
   const isSvgMode = props.mode === 'svg';
@@ -124,6 +133,13 @@
   const currentSelect = ref('');
   const visible = ref(false);
   const currentList = ref(icons);
+  const trigger = ref<HTMLDivElement>();
+
+  const triggerPopover = () => {
+    if (trigger.value) {
+      trigger.value.click();
+    }
+  };
 
   const { t } = useI18n();
   const { prefixCls } = useDesign('icon-picker');
@@ -143,10 +159,9 @@
     () => currentSelect.value,
     (v) => {
       emit('update:value', v);
-      return emit('change', v);
+      emit('change', v);
     },
   );
-
   function handlePageChange(page: number) {
     setCurrentPage(page);
   }
@@ -177,6 +192,10 @@
       padding: 0;
     }
 
+    .ant-input {
+      cursor: pointer;
+    }
+
     &-popover {
       width: 300px;