@qynpm/ui 1.0.36 → 1.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +22 -6
  2. package/dist/index.cjs +2 -2
  3. package/dist/index.mjs +4 -4
  4. package/dist/qy-action-bar/index.cjs +1 -1
  5. package/dist/qy-action-bar/index.mjs +1 -1
  6. package/dist/qy-dialog/index.cjs +1 -1
  7. package/dist/qy-dialog/index.mjs +1 -1
  8. package/dist/qy-form-section/index.cjs +1 -1
  9. package/dist/qy-form-section/index.mjs +1 -1
  10. package/dist/qy-fullscreen/index.cjs +1 -1
  11. package/dist/qy-fullscreen/index.mjs +1 -1
  12. package/dist/qy-icon/index.cjs +1 -1
  13. package/dist/qy-icon/index.mjs +2 -2
  14. package/dist/qy-icon-picker/index.cjs +2 -2
  15. package/dist/qy-icon-picker/index.mjs +2 -2
  16. package/dist/qy-image-upload/index.cjs +1 -1
  17. package/dist/qy-image-upload/index.mjs +1 -1
  18. package/dist/qy-legacy-selection-dialog/index.cjs +1 -1
  19. package/dist/qy-legacy-selection-dialog/index.mjs +1 -1
  20. package/dist/qy-record-quote-search/index.cjs +1 -1
  21. package/dist/qy-record-quote-search/index.mjs +1 -1
  22. package/dist/qy-remark-image/index.cjs +1 -1
  23. package/dist/qy-remark-image/index.mjs +1 -1
  24. package/dist/qy-remote-select/index.cjs +1 -1
  25. package/dist/qy-remote-select/index.mjs +1 -1
  26. package/dist/qy-search-input/index.cjs +1 -1
  27. package/dist/qy-search-input/index.mjs +1 -1
  28. package/dist/qy-selection-dialog/index.cjs +1 -1
  29. package/dist/qy-selection-dialog/index.mjs +1 -1
  30. package/dist/shared/{index-D654b42n.mjs → index-3KGa3jVi.mjs} +3 -3
  31. package/dist/shared/{index-DY-CA7Vr.mjs → index-BF6f9QDU.mjs} +1 -1
  32. package/dist/shared/{index-Bi9wgcgT.cjs → index-BQEymEbE.cjs} +1 -1
  33. package/dist/shared/{index-3qEac4h8.cjs → index-BTbiht5h.cjs} +1 -1
  34. package/dist/shared/{index-S8HW36Mc.mjs → index-Crr3HB8g.mjs} +1 -1
  35. package/dist/shared/index-D8kce2jH.cjs +1 -0
  36. package/dist/shared/{index-aIqtIYsu.cjs → index-Di_xbC7d.cjs} +1 -1
  37. package/dist/shared/index-Dm8kY2v6.mjs +285 -0
  38. package/dist/shared/index.vue_vue_type_style_index_0_lang-CAW_QOyJ.cjs +1 -0
  39. package/dist/shared/index.vue_vue_type_style_index_0_lang-Dr9Elmzn.mjs +317 -0
  40. package/package.json +4 -3
  41. package/qy-icon/index.d.ts +9 -6
  42. package/dist/shared/index-AMu0L6uU.cjs +0 -1
  43. package/dist/shared/index-C91mzAI3.mjs +0 -254
  44. package/dist/shared/index.vue_vue_type_style_index_0_lang-BcZb1U13.cjs +0 -1
  45. package/dist/shared/index.vue_vue_type_style_index_0_lang-CIcZet5j.mjs +0 -286
@@ -0,0 +1,285 @@
1
+ import { defineComponent as D, useAttrs as q, useSlots as B, inject as V, computed as y, markRaw as M, toRaw as F, ref as W, watchEffect as O, openBlock as I, createElementBlock as _, mergeProps as Y, unref as Q, createBlock as A, resolveDynamicComponent as N, createElementVNode as Z, normalizeClass as G, renderSlot as H, normalizeProps as J, guardReactiveProps as U, createCommentVNode as X } from "vue";
2
+ import { _ as ee } from "./_plugin-vue_export-helper-CHgC5LLL.mjs";
3
+ const R = Symbol("QyIconRegistry"), E = /* @__PURE__ */ new WeakMap();
4
+ function C(e) {
5
+ const r = [], o = /* @__PURE__ */ new Map();
6
+ for (const s of (e == null ? void 0 : e.icons) ?? []) {
7
+ const n = w(s == null ? void 0 : s.name);
8
+ if (!n)
9
+ throw new Error("QyIcon definition name must not be empty.");
10
+ const a = b(n);
11
+ if (o.has(a))
12
+ throw new Error(`Duplicate icon name "${n}".`);
13
+ const i = re(s, n);
14
+ r.push(i), o.set(a, i);
15
+ }
16
+ const c = [], f = /* @__PURE__ */ new Map();
17
+ for (const s of x(e == null ? void 0 : e.aliases)) {
18
+ const n = w(s.name), a = w(s.target), i = b(n), v = b(a);
19
+ if (!n)
20
+ throw new Error("QyIcon alias name must not be empty.");
21
+ if (!a)
22
+ throw new Error(`QyIcon alias "${n}" target must not be empty.`);
23
+ if (o.has(i))
24
+ throw new Error(`Icon alias "${n}" conflicts with a canonical icon name.`);
25
+ if (f.has(i))
26
+ throw new Error(`Duplicate icon alias "${n}".`);
27
+ const p = o.get(v);
28
+ if (!p)
29
+ throw new Error(`Icon alias "${n}" target "${a}" not found.`);
30
+ f.set(i, b(p.name)), c.push(Object.freeze({ name: n, target: p.name }));
31
+ }
32
+ let l = Object.freeze({
33
+ definitions: Object.freeze(r),
34
+ aliases: Object.freeze(c),
35
+ byName: o,
36
+ aliasTargets: f
37
+ }), m, u = !1;
38
+ const d = () => {
39
+ if (!e.loader) return m ?? (m = Promise.resolve());
40
+ u = !1;
41
+ let s;
42
+ try {
43
+ s = e.loader();
44
+ } catch (n) {
45
+ s = Promise.reject(n);
46
+ }
47
+ return m = Promise.resolve(s).then((n) => {
48
+ let a;
49
+ try {
50
+ a = C({
51
+ icons: [...l.definitions, ...n.icons],
52
+ aliases: [...l.aliases, ...x(n.aliases)]
53
+ });
54
+ } catch (i) {
55
+ const v = i instanceof Error ? i.message : String(i);
56
+ throw new Error(`Icon registry load conflict: ${v}`);
57
+ }
58
+ l = E.get(a), E.set(h, l);
59
+ }).catch((n) => {
60
+ throw u = !0, n;
61
+ }), m;
62
+ }, h = Object.freeze({
63
+ resolve(s) {
64
+ const n = b(w(s)), a = l.aliasTargets.get(n) ?? n, i = l.byName.get(a);
65
+ return i ? P(i) : void 0;
66
+ },
67
+ has(s) {
68
+ const n = b(w(s));
69
+ return l.byName.has(l.aliasTargets.get(n) ?? n);
70
+ },
71
+ list() {
72
+ return Object.freeze(l.definitions.map(P));
73
+ },
74
+ load() {
75
+ return m ?? d();
76
+ },
77
+ retry() {
78
+ return u ? d() : Promise.reject(new Error("QyIcon registry retry is only available after a failed load."));
79
+ }
80
+ });
81
+ return E.set(h, l), h;
82
+ }
83
+ function ue(...e) {
84
+ const r = [], o = [];
85
+ for (const c of e) {
86
+ const f = E.get(c);
87
+ if (!f)
88
+ throw new TypeError("mergeQyIconRegistries accepts only QyIcon registries created by this package.");
89
+ r.push(...f.definitions), o.push(...f.aliases);
90
+ }
91
+ try {
92
+ return C({ icons: r, aliases: o });
93
+ } catch (c) {
94
+ const f = c instanceof Error ? c.message : String(c);
95
+ throw new Error(`Icon registry merge conflict: ${f}`);
96
+ }
97
+ }
98
+ function fe(e) {
99
+ if (!E.has(e))
100
+ throw new TypeError("createQyIconPlugin accepts only a QyIcon registry created by this package.");
101
+ return Object.freeze({
102
+ install(r) {
103
+ r.provide(R, e);
104
+ }
105
+ });
106
+ }
107
+ function w(e) {
108
+ const r = typeof e == "string" || typeof e == "number" ? String(e).trim() : "";
109
+ if (!r) return "";
110
+ const o = /^#icon-(.+)$/i.exec(r);
111
+ if (o) return o[1].trim();
112
+ const c = /^icon-\[([^\[\]]+?)--([^\[\]]+?)\]$/i.exec(r);
113
+ return c ? `iconify:${c[1]}:${c[2]}` : r;
114
+ }
115
+ function b(e) {
116
+ return e.toLocaleLowerCase();
117
+ }
118
+ function x(e) {
119
+ return e ? Array.isArray(e) ? [...e] : Object.entries(e).map(([r, o]) => ({ name: r, target: o })) : [];
120
+ }
121
+ function re(e, r) {
122
+ const o = {
123
+ ...e.label === void 0 ? {} : { label: te(e.label, r) },
124
+ ...e.keywords === void 0 ? {} : { keywords: oe(e.keywords, r) }
125
+ };
126
+ switch (e.source) {
127
+ case "symbol":
128
+ return z({
129
+ name: r,
130
+ source: "symbol",
131
+ value: k("symbol", e.value, r),
132
+ ...o
133
+ });
134
+ case "component":
135
+ return z({
136
+ name: r,
137
+ source: "component",
138
+ value: k("component", e.value, r),
139
+ ...o
140
+ });
141
+ case "class":
142
+ return z({
143
+ name: r,
144
+ source: "class",
145
+ value: k("class", e.value, r),
146
+ ...o
147
+ });
148
+ default:
149
+ throw new Error(`QyIcon definition "${r}" has unsupported source "${String(e.source)}".`);
150
+ }
151
+ }
152
+ function k(e, r, o) {
153
+ if (e === "symbol") {
154
+ if (typeof r != "string" || !/^#[^\s#]+$/.test(r))
155
+ throw new Error(`QyIcon symbol "${o}" must be a same-document #fragment.`);
156
+ return r;
157
+ }
158
+ if (e === "component") {
159
+ if (typeof r != "object" && typeof r != "function" || r === null)
160
+ throw new Error(`QyIcon component "${o}" must be a Vue component.`);
161
+ return r;
162
+ }
163
+ if (e !== "class")
164
+ throw new Error(`QyIcon definition "${o}" has unsupported source "${String(e)}".`);
165
+ if (typeof r != "string" || !r.trim() || !/^[A-Za-z0-9_:.\/\[\]%-]+(?:\s+[A-Za-z0-9_:.\/\[\]%-]+)*$/.test(r.trim()))
166
+ throw new Error(`QyIcon class "${o}" must be a trusted static class string.`);
167
+ return r.trim();
168
+ }
169
+ function te(e, r) {
170
+ if (typeof e != "string")
171
+ throw new Error(`QyIcon label "${r}" must be a string.`);
172
+ return e;
173
+ }
174
+ function oe(e, r) {
175
+ if (!Array.isArray(e) || e.some((o) => typeof o != "string"))
176
+ throw new Error(`QyIcon keywords "${r}" must be strings.`);
177
+ return Object.freeze([...e]);
178
+ }
179
+ function z(e) {
180
+ return e.keywords && !Object.isFrozen(e.keywords) && (e = { ...e, keywords: Object.freeze([...e.keywords]) }), Object.freeze(e);
181
+ }
182
+ function P(e) {
183
+ return z({
184
+ ...e,
185
+ ...e.keywords ? { keywords: [...e.keywords] } : {}
186
+ });
187
+ }
188
+ const ne = ["role", "aria-label", "aria-hidden", "data-qy-icon-missing"], se = {
189
+ key: 1,
190
+ "aria-hidden": "true",
191
+ focusable: "false"
192
+ }, ae = ["href", "xlink:href"], ie = /* @__PURE__ */ D({
193
+ name: "QyIcon",
194
+ inheritAttrs: !1,
195
+ __name: "index",
196
+ props: {
197
+ name: {},
198
+ icon: {},
199
+ size: { default: "1em" },
200
+ color: { default: "currentColor" },
201
+ spin: { type: Boolean, default: !1 },
202
+ label: {}
203
+ },
204
+ setup(e) {
205
+ const r = e, o = q(), c = B(), f = V(R, null), l = y(
206
+ () => r.icon ? M(F(r.icon)) : void 0
207
+ ), m = y(
208
+ () => r.name === void 0 || r.name === null ? "" : w(r.name)
209
+ ), u = y(() => {
210
+ if (!(r.icon || !f || !m.value))
211
+ return f.resolve(m.value);
212
+ }), d = W(null), h = y(() => !!(!r.icon && m.value && !u.value)), s = y(() => {
213
+ const t = typeof r.label == "string" ? r.label.trim() : "";
214
+ if (t) return t;
215
+ const g = o["aria-label"];
216
+ return L(g) ? String(g) : "";
217
+ }), n = y(() => s.value ? "img" : o.role), a = y(() => K(r.size)), i = y(() => ({
218
+ width: a.value,
219
+ height: a.value,
220
+ fontSize: a.value,
221
+ color: r.color || "currentColor"
222
+ })), v = y(() => {
223
+ const t = {};
224
+ for (const [g, $] of Object.entries(o))
225
+ T(g) && (t[g] = $);
226
+ return t;
227
+ }), p = y(() => Object.freeze({ name: m.value }));
228
+ O(() => {
229
+ const t = u.value;
230
+ d.value && (t == null ? void 0 : t.source) === "symbol" && (d.value.setAttributeNS(
231
+ "http://www.w3.org/1999/xlink",
232
+ "xlink:href",
233
+ t.value
234
+ ), d.value.setAttribute("xlink:href", t.value));
235
+ }), O(() => {
236
+ });
237
+ function K(t) {
238
+ return typeof t == "number" ? Number.isFinite(t) && t > 0 ? `${t}px` : "1em" : t.trim() || "1em";
239
+ }
240
+ function L(t) {
241
+ return typeof t == "string" ? t.trim().length > 0 : t != null && t !== !1;
242
+ }
243
+ function T(t) {
244
+ return t !== "class" && t !== "style" && t !== "role" && t !== "aria-label" && t !== "aria-hidden" && t !== "data-qy-icon-missing" && (t === "id" || t === "title" || t.startsWith("data-") || t.startsWith("aria-"));
245
+ }
246
+ return (t, g) => {
247
+ var $, S, j;
248
+ return I(), _("span", Y(v.value, {
249
+ class: ["qy-icon", [Q(o).class, { "is-spin": r.spin }]],
250
+ style: [Q(o).style, i.value],
251
+ role: n.value,
252
+ "aria-label": s.value || void 0,
253
+ "aria-hidden": s.value ? void 0 : "true",
254
+ "data-qy-icon-missing": h.value ? m.value : void 0
255
+ }), [
256
+ l.value ? (I(), A(N(l.value), {
257
+ key: 0,
258
+ "aria-hidden": "true"
259
+ })) : (($ = u.value) == null ? void 0 : $.source) === "symbol" ? (I(), _("svg", se, [
260
+ Z("use", {
261
+ ref_key: "symbolElement",
262
+ ref: d,
263
+ href: u.value.value,
264
+ "xlink:href": u.value.value
265
+ }, null, 8, ae)
266
+ ])) : ((S = u.value) == null ? void 0 : S.source) === "component" ? (I(), A(N(u.value.value), {
267
+ key: 2,
268
+ "aria-hidden": "true"
269
+ })) : ((j = u.value) == null ? void 0 : j.source) === "class" ? (I(), _("span", {
270
+ key: 3,
271
+ class: G(["qy-icon__class", u.value.value]),
272
+ "aria-hidden": "true"
273
+ }, null, 2)) : h.value && Q(c).fallback ? H(t.$slots, "fallback", J(U(p.value)), void 0, !0, 4) : X("", !0)
274
+ ], 16, ne);
275
+ };
276
+ }
277
+ }), me = /* @__PURE__ */ ee(ie, [["__scopeId", "data-v-e4e9c6ae"]]);
278
+ export {
279
+ me as I,
280
+ R as Q,
281
+ C as a,
282
+ fe as c,
283
+ ue as m,
284
+ w as n
285
+ };
@@ -0,0 +1 @@
1
+ "use strict";const e=require("vue"),Q=require("./index-BQEymEbE.cjs"),T=require("./index-nSFTxVz8.cjs"),J=require("../qy-popover/index.cjs"),S=require("./index-D8kce2jH.cjs");function X(l,f){const v=f==null?"":String(f),n=l&&v?l.resolve(v):void 0;return Object.freeze({value:v,known:!!n,canonicalName:n==null?void 0:n.name,definition:n})}function Z(l,f,v=""){const n=(l==null?void 0:l.list())??[],c=f===void 0?void 0:new Set(f.map(r=>{var p;return(p=l==null?void 0:l.resolve(r))==null?void 0:p.name}).filter(r=>!!r).map(z)),d=String(v).trim().toLocaleLowerCase();return Object.freeze(n.filter(r=>c&&!c.has(z(r.name))?!1:d?[r.name,r.label,...r.keywords??[]].some(p=>typeof p=="string"&&p.toLocaleLowerCase().includes(d)):!0))}function z(l){return S.normalizeQyIconName(l).toLocaleLowerCase()}const ee={class:"qy-icon-picker"},ae=["onKeydown"],ne={class:"qy-icon-picker__preview","aria-hidden":"true"},oe={key:1,class:"qy-icon-picker__missing","aria-hidden":"true"},te=["id"],le={class:"qy-icon-picker__search","data-testid":"qy-icon-picker-search"},re={key:0,class:"qy-icon-picker__state","data-testid":"qy-icon-picker-loading",role:"status"},ie={key:1,class:"qy-icon-picker__state qy-icon-picker__state--error","data-testid":"qy-icon-picker-error",role:"alert"},ce=["aria-label"],ue=["id","data-qy-icon-option","data-qy-icon-active","aria-selected","tabindex","onClick","onFocus","onKeydown"],se={class:"qy-icon-picker__option-label"},de={key:3,class:"qy-icon-picker__empty"};let pe=0;const fe=e.defineComponent({name:"QyIconPicker",__name:"index",props:{modelValue:{default:""},allowedNames:{},disabled:{type:Boolean,default:!1},clearable:{type:Boolean,default:!1},size:{default:"default"},placeholder:{default:"点击选择图标"},searchPlaceholder:{default:"搜索图标名称、标签或关键词"},emptyText:{default:"暂无匹配图标"},panelWidth:{default:540},open:{type:Boolean,default:void 0},id:{},ariaLabel:{}},emits:["update:modelValue","change","clear","update:open","open-change"],setup(l,{expose:f,emit:v}){const n=l,c=v,d=e.inject(S.QY_ICON_REGISTRY_KEY,null),r=e.ref(""),p=e.ref(!1),i=e.ref(-1),w=e.ref([]),m=e.ref(!1),g=e.ref(""),V=e.ref(0);let x=!1;const h=e.ref(null),L=e.ref(null),q=e.ref("pointer"),$=`qy-icon-picker-${++pe}`,y=e.computed(()=>X(d,n.modelValue)),s=e.computed(()=>(V.value,Z(d,n.allowedNames,r.value))),_=e.computed(()=>n.open!==void 0),k=e.computed(()=>_.value?n.open===!0:p.value),M=e.computed(()=>"click"),B=e.computed(()=>`${n.id||$}-panel`);e.watch(k,(a,o)=>{!a||o||(r.value="",i.value=F(),w.value=[],!x&&d&&(x=!0,K(d.load())),q.value==="keyboard"&&e.nextTick(()=>{var t,u;return(u=(t=L.value)==null?void 0:t.focus)==null?void 0:u.call(t)}))});function K(a){m.value=!0,g.value="",a.then(()=>{m.value=!1,V.value++},o=>{m.value=!1,g.value=o instanceof Error?o.message:String(o)})}function A(){!d||m.value||K(d.retry())}e.watch(s,()=>{if(!s.value.length){i.value=-1;return}i.value>=s.value.length&&(i.value=0),i.value<0&&(i.value=0)});function P(){n.disabled||(q.value="keyboard",C("keyboard"))}function D(a){n.disabled||_.value&&n.open!==!1||(a.stopImmediatePropagation(),C("pointer"))}function O(a){I(a)}function U(a){a===k.value&&(_.value||(p.value=a),c("open-change",a),a||e.nextTick(()=>{var o,t;return(t=(o=h.value)==null?void 0:o.focus)==null?void 0:t.call(o)}))}function I(a){a&&n.disabled||a!==k.value&&(_.value||(p.value=a),c("update:open",a))}function C(a="programmatic"){q.value=a,I(!0)}function E(){I(!1),e.nextTick(()=>{var a,o;return(o=(a=h.value)==null?void 0:a.focus)==null?void 0:o.call(a)})}function R(){n.disabled||(c("update:modelValue",""),c("change",""),c("clear"))}function N(a){n.disabled||(c("update:modelValue",a.name),c("change",a.name),E())}function j(a){if(a.key==="Escape"){a.preventDefault(),E();return}if(!s.value.length||!["ArrowDown","ArrowUp","ArrowLeft","ArrowRight"].includes(a.key))return;a.preventDefault();const o=a.key==="ArrowUp"||a.key==="ArrowLeft"?-1:1,t=s.value.length;i.value=(i.value+o+t)%t,e.nextTick(()=>{var u;return(u=w.value[i.value])==null?void 0:u.focus()})}function F(){const a=y.value.canonicalName;if(!a)return s.value.length?0:-1;const o=s.value.findIndex(({name:t})=>t===a);return o>=0?o:s.value.length?0:-1}function Y(a,o){a instanceof HTMLElement&&(w.value[o]=a)}function W(a){return`${B.value}-${encodeURIComponent(a)}`}function G(){var a,o;(o=(a=h.value)==null?void 0:a.focus)==null||o.call(a)}function H(){var a,o;(o=(a=h.value)==null?void 0:a.blur)==null||o.call(a)}return f({focus:G,blur:H,open:C,close:E}),(a,o)=>(e.openBlock(),e.createElementBlock("div",ee,[e.createVNode(e.unref(J.QyPopover),{ref:"popoverRef",class:"qy-icon-picker__popover",open:k.value,trigger:M.value,placement:"bottom-start",width:n.panelWidth,"show-delay":0,"hide-delay":0,disabled:n.disabled||_.value&&n.open===!1,"onUpdate:open":O,onOpenChange:U},{reference:e.withCtx(()=>[e.createElementVNode("div",{class:"qy-icon-picker__trigger","data-testid":"qy-icon-picker-trigger",onClick:D,onKeydown:[e.withKeys(e.withModifiers(P,["prevent"]),["enter"]),e.withKeys(e.withModifiers(P,["prevent"]),["space"])]},[e.createVNode(e.unref(T.QyInput),{ref_key:"triggerRef",ref:h,id:n.id,"model-value":y.value.value,size:n.size,disabled:n.disabled,clearable:n.clearable,readonly:"",placeholder:n.placeholder,"aria-label":n.ariaLabel,"aria-haspopup":"listbox","aria-expanded":k.value?"true":"false","aria-controls":B.value,onClear:R},{prefix:e.withCtx(()=>[e.createElementVNode("span",ne,[y.value.definition?(e.openBlock(),e.createBlock(e.unref(Q.QyIcon),{key:0,name:y.value.definition.name,size:18},null,8,["name"])):(e.openBlock(),e.createElementBlock("span",oe,"?"))])]),suffix:e.withCtx(()=>[n.clearable&&y.value.value?(e.openBlock(),e.createElementBlock("button",{key:0,type:"button",class:"qy-icon-picker__clear","data-testid":"qy-icon-picker-clear","aria-label":"清空图标",onClick:e.withModifiers(R,["stop","prevent"])},[...o[1]||(o[1]=[e.createElementVNode("span",{"aria-hidden":"true"},"×",-1)])])):e.createCommentVNode("",!0)]),_:1},8,["id","model-value","size","disabled","clearable","placeholder","aria-label","aria-expanded","aria-controls"])],40,ae)]),default:e.withCtx(()=>[k.value?(e.openBlock(),e.createElementBlock("div",{key:0,id:B.value,class:"qy-icon-picker__panel",onKeydown:j},[e.createElementVNode("div",le,[e.createVNode(e.unref(T.QyInput),{ref_key:"searchRef",ref:L,modelValue:r.value,"onUpdate:modelValue":o[0]||(o[0]=t=>r.value=t),type:"search",clearable:"",placeholder:n.searchPlaceholder,"aria-label":"搜索图标"},null,8,["modelValue","placeholder"])]),m.value?(e.openBlock(),e.createElementBlock("div",re," 正在加载图标… ")):g.value?(e.openBlock(),e.createElementBlock("div",ie,[e.createElementVNode("span",null,e.toDisplayString(g.value),1),e.createElementVNode("button",{type:"button","data-testid":"qy-icon-picker-retry",onClick:A}," 重试 ")])):s.value.length?(e.openBlock(),e.createElementBlock("div",{key:2,class:"qy-icon-picker__grid",role:"listbox","aria-label":n.ariaLabel||"图标列表"},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.value,(t,u)=>(e.openBlock(),e.createElementBlock("div",{id:W(t.name),key:t.name,ref_for:!0,ref:b=>Y(b,u),class:e.normalizeClass(["qy-icon-picker__option",{"is-active":i.value===u}]),"data-qy-icon-option":t.name,"data-qy-icon-active":i.value===u?"true":void 0,role:"option","aria-selected":y.value.canonicalName===t.name?"true":"false",tabindex:i.value===u?0:-1,onClick:b=>N(t),onFocus:b=>i.value=u,onKeydown:[e.withKeys(e.withModifiers(b=>N(t),["prevent"]),["enter"]),e.withKeys(e.withModifiers(b=>N(t),["prevent"]),["space"])]},[e.createVNode(e.unref(Q.QyIcon),{name:t.name,size:18,"aria-hidden":"true"},null,8,["name"]),e.createElementVNode("span",se,e.toDisplayString(t.label||t.name),1)],42,ue))),128))],8,ce)):(e.openBlock(),e.createElementBlock("div",de,[e.renderSlot(a.$slots,"empty",{},()=>[e.createTextVNode(e.toDisplayString(n.emptyText),1)])]))],40,te)):e.createCommentVNode("",!0)]),_:3},8,["open","trigger","width","disabled"])]))}});exports._sfc_main=fe;
@@ -0,0 +1,317 @@
1
+ import { defineComponent as ue, inject as se, ref as d, computed as b, watch as M, nextTick as Q, openBlock as u, createElementBlock as p, createVNode as R, unref as C, withCtx as z, createElementVNode as h, toDisplayString as S, Fragment as de, renderList as pe, withKeys as K, withModifiers as L, normalizeClass as fe, renderSlot as ve, createTextVNode as ye, createCommentVNode as Y, createBlock as me } from "vue";
2
+ import { Q as W } from "./index-BF6f9QDU.mjs";
3
+ import { Q as G } from "./index-JjHutKmT.mjs";
4
+ import { QyPopover as he } from "../qy-popover/index.mjs";
5
+ import { n as _e, Q as ke } from "./index-Dm8kY2v6.mjs";
6
+ function be(l, y) {
7
+ const m = y == null ? "" : String(y), a = l && m ? l.resolve(m) : void 0;
8
+ return Object.freeze({
9
+ value: m,
10
+ known: !!a,
11
+ canonicalName: a == null ? void 0 : a.name,
12
+ definition: a
13
+ });
14
+ }
15
+ function ge(l, y, m = "") {
16
+ const a = (l == null ? void 0 : l.list()) ?? [], i = y === void 0 ? void 0 : new Set(
17
+ y.map((t) => {
18
+ var v;
19
+ return (v = l == null ? void 0 : l.resolve(t)) == null ? void 0 : v.name;
20
+ }).filter((t) => !!t).map(H)
21
+ ), f = String(m).trim().toLocaleLowerCase();
22
+ return Object.freeze(
23
+ a.filter((t) => i && !i.has(H(t.name)) ? !1 : f ? [
24
+ t.name,
25
+ t.label,
26
+ ...t.keywords ?? []
27
+ ].some(
28
+ (v) => typeof v == "string" && v.toLocaleLowerCase().includes(f)
29
+ ) : !0)
30
+ );
31
+ }
32
+ function H(l) {
33
+ return _e(l).toLocaleLowerCase();
34
+ }
35
+ const qe = { class: "qy-icon-picker" }, we = ["onKeydown"], Ie = {
36
+ class: "qy-icon-picker__preview",
37
+ "aria-hidden": "true"
38
+ }, Ce = {
39
+ key: 1,
40
+ class: "qy-icon-picker__missing",
41
+ "aria-hidden": "true"
42
+ }, Le = ["id"], Pe = {
43
+ class: "qy-icon-picker__search",
44
+ "data-testid": "qy-icon-picker-search"
45
+ }, Qe = {
46
+ key: 0,
47
+ class: "qy-icon-picker__state",
48
+ "data-testid": "qy-icon-picker-loading",
49
+ role: "status"
50
+ }, Re = {
51
+ key: 1,
52
+ class: "qy-icon-picker__state qy-icon-picker__state--error",
53
+ "data-testid": "qy-icon-picker-error",
54
+ role: "alert"
55
+ }, ze = ["aria-label"], Ke = ["id", "data-qy-icon-option", "data-qy-icon-active", "aria-selected", "tabindex", "onClick", "onFocus", "onKeydown"], Ne = { class: "qy-icon-picker__option-label" }, xe = {
56
+ key: 3,
57
+ class: "qy-icon-picker__empty"
58
+ };
59
+ let Ve = 0;
60
+ const Ae = /* @__PURE__ */ ue({
61
+ name: "QyIconPicker",
62
+ __name: "index",
63
+ props: {
64
+ modelValue: { default: "" },
65
+ allowedNames: {},
66
+ disabled: { type: Boolean, default: !1 },
67
+ clearable: { type: Boolean, default: !1 },
68
+ size: { default: "default" },
69
+ placeholder: { default: "点击选择图标" },
70
+ searchPlaceholder: { default: "搜索图标名称、标签或关键词" },
71
+ emptyText: { default: "暂无匹配图标" },
72
+ panelWidth: { default: 540 },
73
+ open: { type: Boolean, default: void 0 },
74
+ id: {},
75
+ ariaLabel: {}
76
+ },
77
+ emits: ["update:modelValue", "change", "clear", "update:open", "open-change"],
78
+ setup(l, { expose: y, emit: m }) {
79
+ const a = l, i = m, f = se(ke, null), t = d(""), v = d(!1), r = d(-1), N = d([]), g = d(!1), P = d(""), A = d(0);
80
+ let O = !1;
81
+ const q = d(null), U = d(null), x = d("pointer"), J = `qy-icon-picker-${++Ve}`, _ = b(
82
+ () => be(f, a.modelValue)
83
+ ), s = b(() => (A.value, ge(f, a.allowedNames, t.value))), w = b(() => a.open !== void 0), k = b(
84
+ () => w.value ? a.open === !0 : v.value
85
+ ), X = b(() => "click"), V = b(() => `${a.id || J}-panel`);
86
+ M(
87
+ k,
88
+ (e, n) => {
89
+ !e || n || (t.value = "", r.value = le(), N.value = [], !O && f && (O = !0, D(f.load())), x.value === "keyboard" && Q(() => {
90
+ var o, c;
91
+ return (c = (o = U.value) == null ? void 0 : o.focus) == null ? void 0 : c.call(o);
92
+ }));
93
+ }
94
+ );
95
+ function D(e) {
96
+ g.value = !0, P.value = "", e.then(
97
+ () => {
98
+ g.value = !1, A.value++;
99
+ },
100
+ (n) => {
101
+ g.value = !1, P.value = n instanceof Error ? n.message : String(n);
102
+ }
103
+ );
104
+ }
105
+ function Z() {
106
+ !f || g.value || D(f.retry());
107
+ }
108
+ M(s, () => {
109
+ if (!s.value.length) {
110
+ r.value = -1;
111
+ return;
112
+ }
113
+ r.value >= s.value.length && (r.value = 0), r.value < 0 && (r.value = 0);
114
+ });
115
+ function j() {
116
+ a.disabled || (x.value = "keyboard", $("keyboard"));
117
+ }
118
+ function ee(e) {
119
+ a.disabled || w.value && a.open !== !1 || (e.stopImmediatePropagation(), $("pointer"));
120
+ }
121
+ function ae(e) {
122
+ T(e);
123
+ }
124
+ function ne(e) {
125
+ e === k.value && (w.value || (v.value = e), i("open-change", e), e || Q(() => {
126
+ var n, o;
127
+ return (o = (n = q.value) == null ? void 0 : n.focus) == null ? void 0 : o.call(n);
128
+ }));
129
+ }
130
+ function T(e) {
131
+ e && a.disabled || e !== k.value && (w.value || (v.value = e), i("update:open", e));
132
+ }
133
+ function $(e = "programmatic") {
134
+ x.value = e, T(!0);
135
+ }
136
+ function B() {
137
+ T(!1), Q(() => {
138
+ var e, n;
139
+ return (n = (e = q.value) == null ? void 0 : e.focus) == null ? void 0 : n.call(e);
140
+ });
141
+ }
142
+ function F() {
143
+ a.disabled || (i("update:modelValue", ""), i("change", ""), i("clear"));
144
+ }
145
+ function E(e) {
146
+ a.disabled || (i("update:modelValue", e.name), i("change", e.name), B());
147
+ }
148
+ function oe(e) {
149
+ if (e.key === "Escape") {
150
+ e.preventDefault(), B();
151
+ return;
152
+ }
153
+ if (!s.value.length || !["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight"].includes(e.key)) return;
154
+ e.preventDefault();
155
+ const n = e.key === "ArrowUp" || e.key === "ArrowLeft" ? -1 : 1, o = s.value.length;
156
+ r.value = (r.value + n + o) % o, Q(() => {
157
+ var c;
158
+ return (c = N.value[r.value]) == null ? void 0 : c.focus();
159
+ });
160
+ }
161
+ function le() {
162
+ const e = _.value.canonicalName;
163
+ if (!e) return s.value.length ? 0 : -1;
164
+ const n = s.value.findIndex(({ name: o }) => o === e);
165
+ return n >= 0 ? n : s.value.length ? 0 : -1;
166
+ }
167
+ function te(e, n) {
168
+ e instanceof HTMLElement && (N.value[n] = e);
169
+ }
170
+ function re(e) {
171
+ return `${V.value}-${encodeURIComponent(e)}`;
172
+ }
173
+ function ie() {
174
+ var e, n;
175
+ (n = (e = q.value) == null ? void 0 : e.focus) == null || n.call(e);
176
+ }
177
+ function ce() {
178
+ var e, n;
179
+ (n = (e = q.value) == null ? void 0 : e.blur) == null || n.call(e);
180
+ }
181
+ return y({ focus: ie, blur: ce, open: $, close: B }), (e, n) => (u(), p("div", qe, [
182
+ R(C(he), {
183
+ ref: "popoverRef",
184
+ class: "qy-icon-picker__popover",
185
+ open: k.value,
186
+ trigger: X.value,
187
+ placement: "bottom-start",
188
+ width: a.panelWidth,
189
+ "show-delay": 0,
190
+ "hide-delay": 0,
191
+ disabled: a.disabled || w.value && a.open === !1,
192
+ "onUpdate:open": ae,
193
+ onOpenChange: ne
194
+ }, {
195
+ reference: z(() => [
196
+ h("div", {
197
+ class: "qy-icon-picker__trigger",
198
+ "data-testid": "qy-icon-picker-trigger",
199
+ onClick: ee,
200
+ onKeydown: [
201
+ K(L(j, ["prevent"]), ["enter"]),
202
+ K(L(j, ["prevent"]), ["space"])
203
+ ]
204
+ }, [
205
+ R(C(G), {
206
+ ref_key: "triggerRef",
207
+ ref: q,
208
+ id: a.id,
209
+ "model-value": _.value.value,
210
+ size: a.size,
211
+ disabled: a.disabled,
212
+ clearable: a.clearable,
213
+ readonly: "",
214
+ placeholder: a.placeholder,
215
+ "aria-label": a.ariaLabel,
216
+ "aria-haspopup": "listbox",
217
+ "aria-expanded": k.value ? "true" : "false",
218
+ "aria-controls": V.value,
219
+ onClear: F
220
+ }, {
221
+ prefix: z(() => [
222
+ h("span", Ie, [
223
+ _.value.definition ? (u(), me(C(W), {
224
+ key: 0,
225
+ name: _.value.definition.name,
226
+ size: 18
227
+ }, null, 8, ["name"])) : (u(), p("span", Ce, "?"))
228
+ ])
229
+ ]),
230
+ suffix: z(() => [
231
+ a.clearable && _.value.value ? (u(), p("button", {
232
+ key: 0,
233
+ type: "button",
234
+ class: "qy-icon-picker__clear",
235
+ "data-testid": "qy-icon-picker-clear",
236
+ "aria-label": "清空图标",
237
+ onClick: L(F, ["stop", "prevent"])
238
+ }, [...n[1] || (n[1] = [
239
+ h("span", { "aria-hidden": "true" }, "×", -1)
240
+ ])])) : Y("", !0)
241
+ ]),
242
+ _: 1
243
+ }, 8, ["id", "model-value", "size", "disabled", "clearable", "placeholder", "aria-label", "aria-expanded", "aria-controls"])
244
+ ], 40, we)
245
+ ]),
246
+ default: z(() => [
247
+ k.value ? (u(), p("div", {
248
+ key: 0,
249
+ id: V.value,
250
+ class: "qy-icon-picker__panel",
251
+ onKeydown: oe
252
+ }, [
253
+ h("div", Pe, [
254
+ R(C(G), {
255
+ ref_key: "searchRef",
256
+ ref: U,
257
+ modelValue: t.value,
258
+ "onUpdate:modelValue": n[0] || (n[0] = (o) => t.value = o),
259
+ type: "search",
260
+ clearable: "",
261
+ placeholder: a.searchPlaceholder,
262
+ "aria-label": "搜索图标"
263
+ }, null, 8, ["modelValue", "placeholder"])
264
+ ]),
265
+ g.value ? (u(), p("div", Qe, " 正在加载图标… ")) : P.value ? (u(), p("div", Re, [
266
+ h("span", null, S(P.value), 1),
267
+ h("button", {
268
+ type: "button",
269
+ "data-testid": "qy-icon-picker-retry",
270
+ onClick: Z
271
+ }, " 重试 ")
272
+ ])) : s.value.length ? (u(), p("div", {
273
+ key: 2,
274
+ class: "qy-icon-picker__grid",
275
+ role: "listbox",
276
+ "aria-label": a.ariaLabel || "图标列表"
277
+ }, [
278
+ (u(!0), p(de, null, pe(s.value, (o, c) => (u(), p("div", {
279
+ id: re(o.name),
280
+ key: o.name,
281
+ ref_for: !0,
282
+ ref: (I) => te(I, c),
283
+ class: fe(["qy-icon-picker__option", { "is-active": r.value === c }]),
284
+ "data-qy-icon-option": o.name,
285
+ "data-qy-icon-active": r.value === c ? "true" : void 0,
286
+ role: "option",
287
+ "aria-selected": _.value.canonicalName === o.name ? "true" : "false",
288
+ tabindex: r.value === c ? 0 : -1,
289
+ onClick: (I) => E(o),
290
+ onFocus: (I) => r.value = c,
291
+ onKeydown: [
292
+ K(L((I) => E(o), ["prevent"]), ["enter"]),
293
+ K(L((I) => E(o), ["prevent"]), ["space"])
294
+ ]
295
+ }, [
296
+ R(C(W), {
297
+ name: o.name,
298
+ size: 18,
299
+ "aria-hidden": "true"
300
+ }, null, 8, ["name"]),
301
+ h("span", Ne, S(o.label || o.name), 1)
302
+ ], 42, Ke))), 128))
303
+ ], 8, ze)) : (u(), p("div", xe, [
304
+ ve(e.$slots, "empty", {}, () => [
305
+ ye(S(a.emptyText), 1)
306
+ ])
307
+ ]))
308
+ ], 40, Le)) : Y("", !0)
309
+ ]),
310
+ _: 3
311
+ }, 8, ["open", "trigger", "width", "disabled"])
312
+ ]));
313
+ }
314
+ });
315
+ export {
316
+ Ae as _
317
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qynpm/ui",
3
- "version": "1.0.36",
3
+ "version": "1.0.37",
4
4
  "description": "起印公共 UI 组件包。",
5
5
  "author": "qy",
6
6
  "license": "MIT",
@@ -456,7 +456,7 @@
456
456
  "clsx": ">=2.0.0"
457
457
  },
458
458
  "dependencies": {
459
- "@qynpm/hooks": "^1.0.4",
459
+ "@qynpm/hooks": "^1.0.6",
460
460
  "js-cookie": "^3.0.5",
461
461
  "lodash-es": "^4.17.21",
462
462
  "mitt": "^3.0.1"
@@ -477,7 +477,8 @@
477
477
  "unplugin-vue-components": "^0.27.0",
478
478
  "vite": "^5.0.0",
479
479
  "vite-plugin-css-injected-by-js": "^3.5.2",
480
- "vitest": "^3.2.2"
480
+ "vitest": "^3.2.2",
481
+ "@qynpm/hooks": "1.0.6"
481
482
  },
482
483
  "scripts": {
483
484
  "dev": "vite",
@@ -57,16 +57,19 @@ export type QyIconAliases =
57
57
  | Readonly<Record<string, string | number>>
58
58
  | readonly QyIconAlias[]
59
59
 
60
- export type QyIconRegistryOptions = Readonly<{
61
- icons: readonly QyIconDefinitionInput[]
62
- aliases?: QyIconAliases
63
- }>
60
+ export type QyIconRegistryOptions = Readonly<{
61
+ icons: readonly QyIconDefinitionInput[]
62
+ aliases?: QyIconAliases
63
+ loader?: () => Promise<QyIconRegistryOptions>
64
+ }>
64
65
 
65
66
  export interface QyIconRegistry {
66
67
  resolve(name: string | number): QyIconDefinition | undefined
67
68
  has(name: string | number): boolean
68
- list(): readonly QyIconDefinition[]
69
- }
69
+ list(): readonly QyIconDefinition[]
70
+ load(): Promise<void>
71
+ retry(): Promise<void>
72
+ }
70
73
 
71
74
  export interface QyIconAttrs {
72
75
  class?: string