@lumal/icons-vue 0.0.2-beta → 0.0.3-beta

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @lumal/icons-vue
2
+
3
+ ## 0.0.3-beta (2026-10-16)
4
+
5
+ ### Patch Changes
6
+
7
+ - 修复直接传入 component、Iconify 和 local-svg 图标定义时的分支解析。
8
+ - 图标选择弹窗增加 Teleport、键盘焦点约束与焦点恢复,并使用 useTemplateRef。
9
+ - 明确 SVG 仅接受可信静态资源,格式校验不等于安全净化。
10
+
11
+ ## 0.0.2-beta (2026-08-01)
12
+
13
+ - Version bump only, to stay in lockstep with the other @lumal packages.
package/README.md CHANGED
@@ -14,3 +14,5 @@ import '@lumal/icons-vue/style.css'
14
14
  ```
15
15
 
16
16
  SVG 改色、渐变、合成、Data URI 和注册表等纯 TypeScript 能力由 `@lumal/icons` 提供。
17
+
18
+ `LumalIcon` 接受注册名或直接 `IconDefinition`(component / iconify / local-svg)。SVG 使用 HTML 渲染,仅接受可信静态资源;注册和渲染不自动净化,单色格式校验不是完整 sanitizer。图标选择弹窗通过 Teleport 挂载到 body,约束 Tab、支持 Escape,并在关闭/卸载时恢复焦点。
@@ -1,2 +1,2 @@
1
- .lumal-icon[data-v-d5c4f92d]{width:var(--lumal-icon-size);height:var(--lumal-icon-size);vertical-align:-.125em;justify-content:center;align-items:center;line-height:1;display:inline-flex}.lumal-icon__svg[data-v-d5c4f92d],.lumal-icon__component[data-v-d5c4f92d]{width:100%;height:100%}.lumal-icon__svg[data-v-d5c4f92d] svg{width:100%;height:100%;display:block}.lumal-icon-picker[data-v-937c0d9c]{gap:12px;display:grid}.lumal-icon-picker__toolbar[data-v-937c0d9c]{grid-template-columns:minmax(0,1fr) minmax(140px,200px);gap:12px;display:grid}.lumal-icon-picker__field[data-v-937c0d9c]{gap:6px;display:grid}.lumal-icon-picker__field-label[data-v-937c0d9c],.lumal-icon-picker__summary[data-v-937c0d9c],.lumal-icon-picker__empty[data-v-937c0d9c]{color:var(--el-text-color-secondary,CanvasText);font-size:13px}.lumal-icon-picker__field input[data-v-937c0d9c],.lumal-icon-picker__field select[data-v-937c0d9c],.lumal-icon-picker__pagination button[data-v-937c0d9c]{border:1px solid var(--el-border-color,currentColor);border-radius:var(--lumal-radius-base,8px);min-height:44px;color:var(--el-text-color-primary,CanvasText);background:var(--el-bg-color,Canvas);padding:0 12px}.lumal-icon-picker__summary[data-v-937c0d9c],.lumal-icon-picker__empty[data-v-937c0d9c]{margin:0}.lumal-icon-picker__grid[data-v-937c0d9c]{grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:8px;display:grid}.lumal-icon-picker__item[data-v-937c0d9c]{border:1px solid var(--el-border-color-lighter,currentColor);border-radius:var(--lumal-radius-small,6px);min-width:44px;min-height:52px;color:var(--el-text-color-regular,CanvasText);background:var(--el-bg-color,Canvas);cursor:pointer;transition:border-color var(--lumal-motion-fast,.16s), background-color var(--lumal-motion-fast,.16s);flex-direction:column;justify-content:center;align-items:center;gap:6px;padding:8px;display:inline-flex}.lumal-icon-picker__item[data-v-937c0d9c]:hover,.lumal-icon-picker__item.is-selected[data-v-937c0d9c]{border-color:var(--el-color-primary,Highlight);background:var(--el-color-primary-light-9,Canvas)}.lumal-icon-picker__item[data-v-937c0d9c]:focus-visible,.lumal-icon-picker__field input[data-v-937c0d9c]:focus-visible,.lumal-icon-picker__field select[data-v-937c0d9c]:focus-visible,.lumal-icon-picker__pagination button[data-v-937c0d9c]:focus-visible{outline:2px solid var(--el-color-primary,Highlight);outline-offset:2px}.lumal-icon-picker__item span[data-v-937c0d9c]{text-overflow:ellipsis;white-space:nowrap;max-width:100%;font-size:11px;overflow:hidden}.lumal-icon-picker__pagination[data-v-937c0d9c]{justify-content:center;align-items:center;gap:12px;display:flex}.lumal-icon-picker__pagination button[data-v-937c0d9c]:disabled{cursor:not-allowed;opacity:.5}@media (width<=640px){.lumal-icon-picker__toolbar[data-v-937c0d9c]{grid-template-columns:minmax(0,1fr)}}@media (prefers-reduced-motion:reduce){.lumal-icon-picker__item[data-v-937c0d9c]{transition:none}}.lumal-icon-picker-dialog[data-v-9bd629e7]{z-index:var(--lumal-z-dialog,500);background:color-mix(in srgb, CanvasText 48%, transparent);justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.lumal-icon-picker-dialog__body[data-v-9bd629e7]{border-radius:var(--lumal-radius-large,12px);width:min(680px,100%);max-height:min(680px,88dvh);color:var(--el-text-color-primary,CanvasText);background:var(--el-bg-color,Canvas);box-shadow:var(--lumal-shadow-dialog,0 18px 48px color-mix(in srgb, CanvasText 18%, transparent));display:grid;overflow:hidden}.lumal-icon-picker-dialog__header[data-v-9bd629e7],.lumal-icon-picker-dialog__footer[data-v-9bd629e7]{justify-content:space-between;align-items:center;gap:12px;min-height:56px;padding:12px 20px;display:flex}.lumal-icon-picker-dialog__header[data-v-9bd629e7]{border-bottom:1px solid var(--el-border-color-lighter,currentColor)}.lumal-icon-picker-dialog__header h3[data-v-9bd629e7]{margin:0;font-size:17px}.lumal-icon-picker-dialog__content[data-v-9bd629e7]{min-height:0;padding:20px;overflow:auto}.lumal-icon-picker-dialog__footer[data-v-9bd629e7]{border-top:1px solid var(--el-border-color-lighter,currentColor);justify-content:flex-end}.lumal-icon-picker-dialog button[data-v-9bd629e7]{border:1px solid var(--el-border-color,currentColor);border-radius:var(--lumal-radius-base,8px);min-width:44px;min-height:44px;color:inherit;background:var(--el-bg-color,Canvas);cursor:pointer;padding:0 14px}.lumal-icon-picker-dialog button.is-primary[data-v-9bd629e7]{border-color:var(--el-color-primary,Highlight);color:var(--el-color-white,HighlightText);background:var(--el-color-primary,Highlight)}.lumal-icon-picker-dialog button[data-v-9bd629e7]:disabled{cursor:not-allowed;opacity:.5}@media (width<=640px){.lumal-icon-picker-dialog[data-v-9bd629e7]{align-items:flex-end;padding:0}.lumal-icon-picker-dialog__body[data-v-9bd629e7]{border-radius:var(--lumal-radius-large,12px) var(--lumal-radius-large,12px) 0 0;max-height:92dvh}}
1
+ .lumal-icon[data-v-f5cc1719]{width:var(--lumal-icon-size);height:var(--lumal-icon-size);vertical-align:-.125em;justify-content:center;align-items:center;line-height:1;display:inline-flex}.lumal-icon__svg[data-v-f5cc1719],.lumal-icon__component[data-v-f5cc1719]{width:100%;height:100%}.lumal-icon__svg[data-v-f5cc1719] svg{width:100%;height:100%;display:block}.lumal-icon-picker[data-v-937c0d9c]{gap:12px;display:grid}.lumal-icon-picker__toolbar[data-v-937c0d9c]{grid-template-columns:minmax(0,1fr) minmax(140px,200px);gap:12px;display:grid}.lumal-icon-picker__field[data-v-937c0d9c]{gap:6px;display:grid}.lumal-icon-picker__field-label[data-v-937c0d9c],.lumal-icon-picker__summary[data-v-937c0d9c],.lumal-icon-picker__empty[data-v-937c0d9c]{color:var(--el-text-color-secondary,CanvasText);font-size:13px}.lumal-icon-picker__field input[data-v-937c0d9c],.lumal-icon-picker__field select[data-v-937c0d9c],.lumal-icon-picker__pagination button[data-v-937c0d9c]{border:1px solid var(--el-border-color,currentColor);border-radius:var(--lumal-radius-base,8px);min-height:44px;color:var(--el-text-color-primary,CanvasText);background:var(--el-bg-color,Canvas);padding:0 12px}.lumal-icon-picker__summary[data-v-937c0d9c],.lumal-icon-picker__empty[data-v-937c0d9c]{margin:0}.lumal-icon-picker__grid[data-v-937c0d9c]{grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:8px;display:grid}.lumal-icon-picker__item[data-v-937c0d9c]{border:1px solid var(--el-border-color-lighter,currentColor);border-radius:var(--lumal-radius-small,6px);min-width:44px;min-height:52px;color:var(--el-text-color-regular,CanvasText);background:var(--el-bg-color,Canvas);cursor:pointer;transition:border-color var(--lumal-motion-fast,.16s), background-color var(--lumal-motion-fast,.16s);flex-direction:column;justify-content:center;align-items:center;gap:6px;padding:8px;display:inline-flex}.lumal-icon-picker__item[data-v-937c0d9c]:hover,.lumal-icon-picker__item.is-selected[data-v-937c0d9c]{border-color:var(--el-color-primary,Highlight);background:var(--el-color-primary-light-9,Canvas)}.lumal-icon-picker__item[data-v-937c0d9c]:focus-visible,.lumal-icon-picker__field input[data-v-937c0d9c]:focus-visible,.lumal-icon-picker__field select[data-v-937c0d9c]:focus-visible,.lumal-icon-picker__pagination button[data-v-937c0d9c]:focus-visible{outline:2px solid var(--el-color-primary,Highlight);outline-offset:2px}.lumal-icon-picker__item span[data-v-937c0d9c]{text-overflow:ellipsis;white-space:nowrap;max-width:100%;font-size:11px;overflow:hidden}.lumal-icon-picker__pagination[data-v-937c0d9c]{justify-content:center;align-items:center;gap:12px;display:flex}.lumal-icon-picker__pagination button[data-v-937c0d9c]:disabled{cursor:not-allowed;opacity:.5}@media (width<=640px){.lumal-icon-picker__toolbar[data-v-937c0d9c]{grid-template-columns:minmax(0,1fr)}}@media (prefers-reduced-motion:reduce){.lumal-icon-picker__item[data-v-937c0d9c]{transition:none}}.lumal-icon-picker-dialog[data-v-a6a04d17]{z-index:var(--lumal-z-dialog,500);background:color-mix(in srgb, CanvasText 48%, transparent);justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.lumal-icon-picker-dialog__body[data-v-a6a04d17]{border-radius:var(--lumal-radius-large,12px);width:min(680px,100%);max-height:min(680px,88dvh);color:var(--el-text-color-primary,CanvasText);background:var(--el-bg-color,Canvas);box-shadow:var(--lumal-shadow-dialog,0 18px 48px color-mix(in srgb, CanvasText 18%, transparent));display:grid;overflow:hidden}.lumal-icon-picker-dialog__header[data-v-a6a04d17],.lumal-icon-picker-dialog__footer[data-v-a6a04d17]{justify-content:space-between;align-items:center;gap:12px;min-height:56px;padding:12px 20px;display:flex}.lumal-icon-picker-dialog__header[data-v-a6a04d17]{border-bottom:1px solid var(--el-border-color-lighter,currentColor)}.lumal-icon-picker-dialog__header h3[data-v-a6a04d17]{margin:0;font-size:17px}.lumal-icon-picker-dialog__content[data-v-a6a04d17]{min-height:0;padding:20px;overflow:auto}.lumal-icon-picker-dialog__footer[data-v-a6a04d17]{border-top:1px solid var(--el-border-color-lighter,currentColor);justify-content:flex-end}.lumal-icon-picker-dialog button[data-v-a6a04d17]{border:1px solid var(--el-border-color,currentColor);border-radius:var(--lumal-radius-base,8px);min-width:44px;min-height:44px;color:inherit;background:var(--el-bg-color,Canvas);cursor:pointer;padding:0 14px}.lumal-icon-picker-dialog button.is-primary[data-v-a6a04d17]{border-color:var(--el-color-primary,Highlight);color:var(--el-color-white,HighlightText);background:var(--el-color-primary,Highlight)}.lumal-icon-picker-dialog button[data-v-a6a04d17]:disabled{cursor:not-allowed;opacity:.5}@media (width<=640px){.lumal-icon-picker-dialog[data-v-a6a04d17]{align-items:flex-end;padding:0}.lumal-icon-picker-dialog__body[data-v-a6a04d17]{border-radius:var(--lumal-radius-large,12px) var(--lumal-radius-large,12px) 0 0;max-height:92dvh}}
2
2
  /*$vite$:1*/
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("vue"),t=require("@iconify/vue"),n=require("@lumal/icons");function r(){let t=(0,e.shallowRef)(0);(0,e.onScopeDispose)((0,n.subscribeIconRegistry)(()=>{t.value+=1}));let r=(0,e.computed)(()=>(t.value,(0,n.getRegisteredIconDefinitions)())),i=(0,e.computed)(()=>(t.value,(0,n.getRegisteredIconGroups)()));function a(e){return t.value,(0,n.resolveIconDefinition)(e)}return{groups:i,icons:r,resolve:a}}var i=[`title`],a=[`innerHTML`],o=(0,e.defineComponent)({__name:`LumalIcon`,props:{name:{},icon:{},size:{},color:{},gradient:{},title:{}},setup(o){let s=o,c=`lumal-icon-gradient-${(0,e.useId)()}`,l=r(),u=(0,e.computed)(()=>{if(s.name)return l.resolve(s.name)}),d=(0,e.computed)(()=>{let e=s.icon,t=u.value?.svgText??(typeof e==`string`&&e.trim().startsWith(`<svg`)?e:``)??(typeof e==`object`&&e&&`svgText`in e?String(e.svgText??``):``);return t?s.gradient?(0,n.applySvgGradient)(t,{...s.gradient,id:s.gradient.id??c}):(0,n.recolorSvgString)(t,s.color):``}),f=(0,e.computed)(()=>{let e=u.value?.component;if(typeof e==`function`||typeof e==`object`&&e)return e;if(typeof s.icon==`object`&&s.icon&&`component`in s.icon){let e=s.icon.component;return typeof e==`function`||typeof e==`object`&&e?e:void 0}return typeof s.icon==`function`||typeof s.icon==`object`?s.icon:void 0}),p=(0,e.computed)(()=>{if(u.value?.source===`iconify`)return u.value.icon;if(typeof s.icon==`object`&&s.icon&&`source`in s.icon&&s.icon.source===`iconify`)return s.icon.icon}),m=(0,e.computed)(()=>({"--lumal-icon-size":typeof s.size==`number`?`${s.size}px`:s.size??`1em`,color:s.color})),h=(0,e.computed)(()=>!!(d.value||f.value||p.value)),g=(0,e.computed)(()=>s.title??u.value?.label);return(n,r)=>h.value?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,{key:0,class:`lumal-icon`,style:(0,e.normalizeStyle)(m.value),title:g.value,"aria-hidden":`true`},[f.value?((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)(f.value),{key:0,class:`lumal-icon__component`})):p.value?((0,e.openBlock)(),(0,e.createBlock)((0,e.unref)(t.Icon),{key:1,class:`lumal-icon__component`,icon:p.value},null,8,[`icon`])):((0,e.openBlock)(),(0,e.createElementBlock)(`span`,{key:2,class:`lumal-icon__svg`,innerHTML:d.value},null,8,a))],12,i)):(0,e.createCommentVNode)(``,!0)}}),s=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},c=s(o,[[`__scopeId`,`data-v-d5c4f92d`]]),l={class:`lumal-icon-picker`},u={class:`lumal-icon-picker__toolbar`},d={key:0,class:`lumal-icon-picker__field`},f={key:1,class:`lumal-icon-picker__field`},p=[`value`],m={class:`lumal-icon-picker__summary`,role:`status`},h={key:0,class:`lumal-icon-picker__grid`,role:`listbox`,"aria-label":`图标列表`},g=[`aria-label`,`aria-selected`,`title`,`onClick`],_={key:0},v={key:1,class:`lumal-icon-picker__empty`},y={key:2,class:`lumal-icon-picker__pagination`},b=[`disabled`],x=[`disabled`],S=s((0,e.defineComponent)({__name:`LumalIconPicker`,props:(0,e.mergeModels)({group:{default:``},pageSize:{default:48},searchable:{type:Boolean,default:!0},showLabels:{type:Boolean,default:!1},storageKey:{default:``}},{modelValue:{},modelModifiers:{}}),emits:(0,e.mergeModels)([`select`],[`update:modelValue`]),setup(t,{emit:n}){let i=t,a=n,o=(0,e.useModel)(t,`modelValue`),s=(0,e.ref)(``),S=(0,e.ref)(i.group),C=(0,e.ref)(1),w=(0,e.computed)(()=>Math.max(1,i.pageSize)),T=r(),E=T.icons,D=(0,e.computed)(()=>{let e=T.groups.value,t=new Set(e.map(e=>e.key)),n=E.value.map(e=>e.group).filter(e=>typeof e==`string`&&!t.has(e)).filter((e,t,n)=>n.indexOf(e)===t).map(e=>({key:e,label:e}));return[...e,...n]}),O=(0,e.computed)(()=>{let e=s.value.trim().toLocaleLowerCase();return E.value.filter(t=>{let n=!S.value||t.group===S.value,r=!e||t.key.toLocaleLowerCase().includes(e)||t.label?.toLocaleLowerCase().includes(e);return n&&r})}),k=(0,e.computed)(()=>Math.max(1,Math.ceil(O.value.length/w.value))),A=(0,e.computed)(()=>{let e=(C.value-1)*w.value;return O.value.slice(e,e+w.value)});(0,e.watch)([s,S,w],()=>{C.value=1}),(0,e.watch)(()=>i.group,e=>{S.value=e}),(0,e.watch)(k,e=>{C.value=Math.min(C.value,e)}),i.storageKey&&typeof localStorage<`u`&&!o.value&&(o.value=localStorage.getItem(i.storageKey)??void 0);function j(e){o.value=e.key,i.storageKey&&typeof localStorage<`u`&&localStorage.setItem(i.storageKey,e.key),a(`select`,e)}return(n,r)=>((0,e.openBlock)(),(0,e.createElementBlock)(`div`,l,[(0,e.createElementVNode)(`div`,u,[t.searchable?((0,e.openBlock)(),(0,e.createElementBlock)(`label`,d,[r[4]||=(0,e.createElementVNode)(`span`,{class:`lumal-icon-picker__field-label`},`搜索图标`,-1),(0,e.withDirectives)((0,e.createElementVNode)(`input`,{"onUpdate:modelValue":r[0]||=e=>s.value=e,type:`search`,placeholder:`输入名称或 key`},null,512),[[e.vModelText,s.value]])])):(0,e.createCommentVNode)(``,!0),D.value.length?((0,e.openBlock)(),(0,e.createElementBlock)(`label`,f,[r[6]||=(0,e.createElementVNode)(`span`,{class:`lumal-icon-picker__field-label`},`图标分组`,-1),(0,e.withDirectives)((0,e.createElementVNode)(`select`,{"onUpdate:modelValue":r[1]||=e=>S.value=e},[r[5]||=(0,e.createElementVNode)(`option`,{value:``},`全部分组`,-1),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(D.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)(`option`,{key:t.key,value:t.key},(0,e.toDisplayString)(t.label),9,p))),128))],512),[[e.vModelSelect,S.value]])])):(0,e.createCommentVNode)(``,!0)]),(0,e.createElementVNode)(`p`,m,` 共 `+(0,e.toDisplayString)(O.value.length)+` 个图标 `,1),A.value.length?((0,e.openBlock)(),(0,e.createElementBlock)(`div`,h,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(A.value,n=>((0,e.openBlock)(),(0,e.createElementBlock)(`button`,{key:n.key,class:(0,e.normalizeClass)([`lumal-icon-picker__item`,{"is-selected":o.value===n.key}]),type:`button`,role:`option`,"aria-label":n.label||n.key,"aria-selected":o.value===n.key,title:n.label||n.key,onClick:e=>j(n)},[(0,e.createVNode)(c,{name:n.key},null,8,[`name`]),t.showLabels?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,_,(0,e.toDisplayString)(n.label||n.key),1)):(0,e.createCommentVNode)(``,!0)],10,g))),128))])):((0,e.openBlock)(),(0,e.createElementBlock)(`p`,v,` 未找到匹配图标 `)),k.value>1?((0,e.openBlock)(),(0,e.createElementBlock)(`footer`,y,[(0,e.createElementVNode)(`button`,{type:`button`,disabled:C.value<=1,onClick:r[2]||=e=>--C.value},` 上一页 `,8,b),(0,e.createElementVNode)(`span`,null,`第 `+(0,e.toDisplayString)(C.value)+` / `+(0,e.toDisplayString)(k.value)+` 页`,1),(0,e.createElementVNode)(`button`,{type:`button`,disabled:C.value>=k.value,onClick:r[3]||=e=>C.value+=1},` 下一页 `,8,x)])):(0,e.createCommentVNode)(``,!0)]))}}),[[`__scopeId`,`data-v-937c0d9c`]]),C=[`aria-label`],w={class:`lumal-icon-picker-dialog__header`},T={class:`lumal-icon-picker-dialog__content`},E={class:`lumal-icon-picker-dialog__footer`},D=[`disabled`],O=s((0,e.defineComponent)({__name:`LumalIconPickerDialog`,props:(0,e.mergeModels)({cancelText:{default:`取消`},confirmText:{default:`确认选择`},title:{default:`选择图标`}},{visible:{type:Boolean,default:!1},visibleModifiers:{},modelValue:{},modelModifiers:{}}),emits:(0,e.mergeModels)([`cancel`,`confirm`],[`update:visible`,`update:modelValue`]),setup(t,{emit:n}){let r=n,i=(0,e.useModel)(t,`visible`),a=(0,e.useModel)(t,`modelValue`),o=(0,e.ref)(``),s=(0,e.ref)();(0,e.watch)(i,async t=>{t&&(o.value=a.value??``,await(0,e.nextTick)(),s.value?.focus())},{immediate:!0});function c(){i.value=!1,r(`cancel`)}function l(){o.value&&(a.value=o.value,i.value=!1,r(`confirm`,o.value))}return(n,r)=>i.value?((0,e.openBlock)(),(0,e.createElementBlock)(`div`,{key:0,class:`lumal-icon-picker-dialog`,role:`presentation`,onMousedown:(0,e.withModifiers)(c,[`self`])},[(0,e.createElementVNode)(`section`,{ref_key:`dialogRef`,ref:s,class:`lumal-icon-picker-dialog__body`,role:`dialog`,"aria-modal":`true`,"aria-label":t.title,tabindex:`-1`,onKeydown:(0,e.withKeys)(c,[`esc`])},[(0,e.createElementVNode)(`header`,w,[(0,e.createElementVNode)(`h3`,null,(0,e.toDisplayString)(t.title),1),(0,e.createElementVNode)(`button`,{type:`button`,"aria-label":`关闭图标选择器`,onClick:c},` × `)]),(0,e.createElementVNode)(`div`,T,[(0,e.createVNode)(S,{modelValue:o.value,"onUpdate:modelValue":r[0]||=e=>o.value=e},null,8,[`modelValue`])]),(0,e.createElementVNode)(`footer`,E,[(0,e.createElementVNode)(`button`,{type:`button`,onClick:c},(0,e.toDisplayString)(t.cancelText),1),(0,e.createElementVNode)(`button`,{type:`button`,class:`is-primary`,disabled:!o.value,onClick:l},(0,e.toDisplayString)(t.confirmText),9,D)])],40,C)],32)):(0,e.createCommentVNode)(``,!0)}}),[[`__scopeId`,`data-v-9bd629e7`]]);exports.LumalIcon=c,exports.LumalIconPicker=S,exports.LumalIconPickerDialog=O,exports.useIconRegistry=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("vue"),t=require("@iconify/vue"),n=require("@lumal/icons");function r(){let t=(0,e.shallowRef)(0);(0,e.onScopeDispose)((0,n.subscribeIconRegistry)(()=>{t.value+=1}));let r=(0,e.computed)(()=>(t.value,(0,n.getRegisteredIconDefinitions)())),i=(0,e.computed)(()=>(t.value,(0,n.getRegisteredIconGroups)()));function a(e){return t.value,(0,n.resolveIconDefinition)(e)}return{groups:i,icons:r,resolve:a}}var i=[`title`],a=[`innerHTML`],o=(0,e.defineComponent)({__name:`LumalIcon`,props:{name:{},icon:{},size:{},color:{},gradient:{},title:{}},setup(o){let s=o,c=`lumal-icon-gradient-${(0,e.useId)()}`,l=r(),u=(0,e.computed)(()=>{let e=s.name?l.resolve(s.name):void 0;if(e)return e;let t=s.icon;return t&&typeof t==`object`&&`source`in t&&`key`in t?t:void 0}),d=(0,e.computed)(()=>{let e=s.icon,t=u.value?.svgText??(typeof e==`string`&&e.trim().startsWith(`<svg`)?e:``);return t?s.gradient?(0,n.applySvgGradient)(t,{...s.gradient,id:s.gradient.id??c}):(0,n.recolorSvgString)(t,s.color):``}),f=(0,e.computed)(()=>{if(u.value){let t=u.value.source===`component`?u.value.component:void 0;return typeof t==`function`||typeof t==`object`&&t?(0,e.toRaw)(t):void 0}return typeof s.icon==`function`||typeof s.icon==`object`?(0,e.toRaw)(s.icon):void 0}),p=(0,e.computed)(()=>{if(u.value?.source===`iconify`)return u.value.icon}),m=(0,e.computed)(()=>({"--lumal-icon-size":typeof s.size==`number`?`${s.size}px`:s.size??`1em`,color:s.color})),h=(0,e.computed)(()=>!!(d.value||f.value||p.value)),g=(0,e.computed)(()=>s.title??u.value?.label);return(n,r)=>h.value?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,{key:0,class:`lumal-icon`,style:(0,e.normalizeStyle)(m.value),title:g.value,"aria-hidden":`true`},[f.value?((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)(f.value),{key:0,class:`lumal-icon__component`})):p.value?((0,e.openBlock)(),(0,e.createBlock)((0,e.unref)(t.Icon),{key:1,class:`lumal-icon__component`,icon:p.value},null,8,[`icon`])):((0,e.openBlock)(),(0,e.createElementBlock)(`span`,{key:2,class:`lumal-icon__svg`,innerHTML:d.value},null,8,a))],12,i)):(0,e.createCommentVNode)(``,!0)}}),s=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},c=s(o,[[`__scopeId`,`data-v-f5cc1719`]]),l={class:`lumal-icon-picker`},u={class:`lumal-icon-picker__toolbar`},d={key:0,class:`lumal-icon-picker__field`},f={key:1,class:`lumal-icon-picker__field`},p=[`value`],m={class:`lumal-icon-picker__summary`,role:`status`},h={key:0,class:`lumal-icon-picker__grid`,role:`listbox`,"aria-label":`图标列表`},g=[`aria-label`,`aria-selected`,`title`,`onClick`],_={key:0},v={key:1,class:`lumal-icon-picker__empty`},y={key:2,class:`lumal-icon-picker__pagination`},b=[`disabled`],x=[`disabled`],S=s((0,e.defineComponent)({__name:`LumalIconPicker`,props:(0,e.mergeModels)({group:{default:``},pageSize:{default:48},searchable:{type:Boolean,default:!0},showLabels:{type:Boolean,default:!1},storageKey:{default:``}},{modelValue:{},modelModifiers:{}}),emits:(0,e.mergeModels)([`select`],[`update:modelValue`]),setup(t,{emit:n}){let i=t,a=n,o=(0,e.useModel)(t,`modelValue`),s=(0,e.ref)(``),S=(0,e.ref)(i.group),C=(0,e.ref)(1),w=(0,e.computed)(()=>Math.max(1,i.pageSize)),T=r(),E=T.icons,D=(0,e.computed)(()=>{let e=T.groups.value,t=new Set(e.map(e=>e.key)),n=E.value.map(e=>e.group).filter(e=>typeof e==`string`&&!t.has(e)).filter((e,t,n)=>n.indexOf(e)===t).map(e=>({key:e,label:e}));return[...e,...n]}),O=(0,e.computed)(()=>{let e=s.value.trim().toLocaleLowerCase();return E.value.filter(t=>{let n=!S.value||t.group===S.value,r=!e||t.key.toLocaleLowerCase().includes(e)||t.label?.toLocaleLowerCase().includes(e);return n&&r})}),k=(0,e.computed)(()=>Math.max(1,Math.ceil(O.value.length/w.value))),A=(0,e.computed)(()=>{let e=(C.value-1)*w.value;return O.value.slice(e,e+w.value)});(0,e.watch)([s,S,w],()=>{C.value=1}),(0,e.watch)(()=>i.group,e=>{S.value=e}),(0,e.watch)(k,e=>{C.value=Math.min(C.value,e)}),i.storageKey&&typeof localStorage<`u`&&!o.value&&(o.value=localStorage.getItem(i.storageKey)??void 0);function j(e){o.value=e.key,i.storageKey&&typeof localStorage<`u`&&localStorage.setItem(i.storageKey,e.key),a(`select`,e)}return(n,r)=>((0,e.openBlock)(),(0,e.createElementBlock)(`div`,l,[(0,e.createElementVNode)(`div`,u,[t.searchable?((0,e.openBlock)(),(0,e.createElementBlock)(`label`,d,[r[4]||=(0,e.createElementVNode)(`span`,{class:`lumal-icon-picker__field-label`},`搜索图标`,-1),(0,e.withDirectives)((0,e.createElementVNode)(`input`,{"onUpdate:modelValue":r[0]||=e=>s.value=e,type:`search`,placeholder:`输入名称或 key`},null,512),[[e.vModelText,s.value]])])):(0,e.createCommentVNode)(``,!0),D.value.length?((0,e.openBlock)(),(0,e.createElementBlock)(`label`,f,[r[6]||=(0,e.createElementVNode)(`span`,{class:`lumal-icon-picker__field-label`},`图标分组`,-1),(0,e.withDirectives)((0,e.createElementVNode)(`select`,{"onUpdate:modelValue":r[1]||=e=>S.value=e},[r[5]||=(0,e.createElementVNode)(`option`,{value:``},`全部分组`,-1),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(D.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)(`option`,{key:t.key,value:t.key},(0,e.toDisplayString)(t.label),9,p))),128))],512),[[e.vModelSelect,S.value]])])):(0,e.createCommentVNode)(``,!0)]),(0,e.createElementVNode)(`p`,m,` 共 `+(0,e.toDisplayString)(O.value.length)+` 个图标 `,1),A.value.length?((0,e.openBlock)(),(0,e.createElementBlock)(`div`,h,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(A.value,n=>((0,e.openBlock)(),(0,e.createElementBlock)(`button`,{key:n.key,class:(0,e.normalizeClass)([`lumal-icon-picker__item`,{"is-selected":o.value===n.key}]),type:`button`,role:`option`,"aria-label":n.label||n.key,"aria-selected":o.value===n.key,title:n.label||n.key,onClick:e=>j(n)},[(0,e.createVNode)(c,{name:n.key},null,8,[`name`]),t.showLabels?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,_,(0,e.toDisplayString)(n.label||n.key),1)):(0,e.createCommentVNode)(``,!0)],10,g))),128))])):((0,e.openBlock)(),(0,e.createElementBlock)(`p`,v,` 未找到匹配图标 `)),k.value>1?((0,e.openBlock)(),(0,e.createElementBlock)(`footer`,y,[(0,e.createElementVNode)(`button`,{type:`button`,disabled:C.value<=1,onClick:r[2]||=e=>--C.value},` 上一页 `,8,b),(0,e.createElementVNode)(`span`,null,`第 `+(0,e.toDisplayString)(C.value)+` / `+(0,e.toDisplayString)(k.value)+` 页`,1),(0,e.createElementVNode)(`button`,{type:`button`,disabled:C.value>=k.value,onClick:r[3]||=e=>C.value+=1},` 下一页 `,8,x)])):(0,e.createCommentVNode)(``,!0)]))}}),[[`__scopeId`,`data-v-937c0d9c`]]),C=[`aria-label`],w={class:`lumal-icon-picker-dialog__header`},T={class:`lumal-icon-picker-dialog__content`},E={class:`lumal-icon-picker-dialog__footer`},D=[`disabled`],O=s((0,e.defineComponent)({__name:`LumalIconPickerDialog`,props:(0,e.mergeModels)({cancelText:{default:`取消`},confirmText:{default:`确认选择`},title:{default:`选择图标`}},{visible:{type:Boolean,default:!1},visibleModifiers:{},modelValue:{},modelModifiers:{}}),emits:(0,e.mergeModels)([`cancel`,`confirm`],[`update:visible`,`update:modelValue`]),setup(t,{emit:n}){let r=n,i=(0,e.useModel)(t,`visible`),a=(0,e.useModel)(t,`modelValue`),o=(0,e.shallowRef)(``),s=(0,e.useTemplateRef)(`dialogRef`),c;function l(e){i.value&&s.value&&!s.value.contains(e.target)&&s.value.focus()}function u(e){if(e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),d()),e.key!==`Tab`)return;let t=[...s.value?.querySelectorAll(`button, input, select, textarea, a[href], [tabindex]`)??[]].filter(e=>e.tabIndex>=0&&!e.matches(`:disabled`)&&!e.closest(`[hidden], [inert]`)),n=t[0],r=t.at(-1);(!n||(e.shiftKey?document.activeElement===n||document.activeElement===s.value:document.activeElement===r||document.activeElement===s.value))&&(e.preventDefault(),(e.shiftKey?r:n)?.focus())}(0,e.watch)(i,async t=>{if(!(typeof document>`u`)){if(!t){document.removeEventListener(`focusin`,l);let t=c;await(0,e.nextTick)(),!i.value&&t?.isConnected&&t.focus();return}c=document.activeElement instanceof HTMLElement?document.activeElement:void 0,o.value=a.value??``,await(0,e.nextTick)(),i.value&&(s.value?.focus(),document.addEventListener(`focusin`,l))}},{immediate:!0}),(0,e.onBeforeUnmount)(()=>{document.removeEventListener(`focusin`,l),c?.isConnected&&c.focus()});function d(){i.value=!1,r(`cancel`)}function f(){o.value&&(a.value=o.value,i.value=!1,r(`confirm`,o.value))}return(n,r)=>((0,e.openBlock)(),(0,e.createBlock)(e.Teleport,{to:`body`},[i.value?((0,e.openBlock)(),(0,e.createElementBlock)(`div`,{key:0,class:`lumal-icon-picker-dialog`,role:`presentation`,onMousedown:(0,e.withModifiers)(d,[`self`])},[(0,e.createElementVNode)(`section`,{ref_key:`dialogRef`,ref:s,class:`lumal-icon-picker-dialog__body`,role:`dialog`,"aria-modal":`true`,"aria-label":t.title,tabindex:`-1`,onKeydown:u},[(0,e.createElementVNode)(`header`,w,[(0,e.createElementVNode)(`h3`,null,(0,e.toDisplayString)(t.title),1),(0,e.createElementVNode)(`button`,{type:`button`,"aria-label":`关闭图标选择器`,onClick:d},` × `)]),(0,e.createElementVNode)(`div`,T,[(0,e.createVNode)(S,{modelValue:o.value,"onUpdate:modelValue":r[0]||=e=>o.value=e},null,8,[`modelValue`])]),(0,e.createElementVNode)(`footer`,E,[(0,e.createElementVNode)(`button`,{type:`button`,onClick:d},(0,e.toDisplayString)(t.cancelText),1),(0,e.createElementVNode)(`button`,{type:`button`,class:`is-primary`,disabled:!o.value,onClick:f},(0,e.toDisplayString)(t.confirmText),9,D)])],40,C)],32)):(0,e.createCommentVNode)(``,!0)]))}}),[[`__scopeId`,`data-v-a6a04d17`]]);exports.LumalIcon=c,exports.LumalIconPicker=S,exports.LumalIconPickerDialog=O,exports.useIconRegistry=r;
package/dist/index.js CHANGED
@@ -1,25 +1,25 @@
1
- import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createVNode as o, defineComponent as s, mergeModels as c, nextTick as l, normalizeClass as u, normalizeStyle as d, onScopeDispose as f, openBlock as p, ref as m, renderList as h, resolveDynamicComponent as g, shallowRef as _, toDisplayString as v, unref as y, useId as b, useModel as x, vModelSelect as S, vModelText as C, watch as w, withDirectives as T, withKeys as E, withModifiers as D } from "vue";
2
- import { Icon as O } from "@iconify/vue";
3
- import { applySvgGradient as k, getRegisteredIconDefinitions as A, getRegisteredIconGroups as j, recolorSvgString as M, resolveIconDefinition as N, subscribeIconRegistry as ee } from "@lumal/icons";
1
+ import { Fragment as e, Teleport as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createVNode as s, defineComponent as c, mergeModels as l, nextTick as u, normalizeClass as d, normalizeStyle as f, onBeforeUnmount as p, onScopeDispose as m, openBlock as h, ref as g, renderList as _, resolveDynamicComponent as v, shallowRef as y, toDisplayString as b, toRaw as x, unref as S, useId as C, useModel as w, useTemplateRef as T, vModelSelect as E, vModelText as D, watch as O, withDirectives as k, withModifiers as A } from "vue";
2
+ import { Icon as j } from "@iconify/vue";
3
+ import { applySvgGradient as M, getRegisteredIconDefinitions as ee, getRegisteredIconGroups as te, recolorSvgString as N, resolveIconDefinition as P, subscribeIconRegistry as F } from "@lumal/icons";
4
4
  //#region src/composables/useIconRegistry.ts
5
- function P() {
6
- let e = _(0);
7
- f(ee(() => {
5
+ function I() {
6
+ let e = y(0);
7
+ m(F(() => {
8
8
  e.value += 1;
9
9
  }));
10
- let n = t(() => (e.value, A())), r = t(() => (e.value, j()));
10
+ let t = n(() => (e.value, ee())), r = n(() => (e.value, te()));
11
11
  function i(t) {
12
- return e.value, N(t);
12
+ return e.value, P(t);
13
13
  }
14
14
  return {
15
15
  groups: r,
16
- icons: n,
16
+ icons: t,
17
17
  resolve: i
18
18
  };
19
19
  }
20
20
  //#endregion
21
21
  //#region src/components/LumalIcon.vue?vue&type=script&setup=true&lang.ts
22
- var F = ["title"], I = ["innerHTML"], L = /*@__PURE__*/ s({
22
+ var L = ["title"], R = ["innerHTML"], z = /*@__PURE__*/ c({
23
23
  __name: "LumalIcon",
24
24
  props: {
25
25
  name: {},
@@ -30,80 +30,80 @@ var F = ["title"], I = ["innerHTML"], L = /*@__PURE__*/ s({
30
30
  title: {}
31
31
  },
32
32
  setup(e) {
33
- let a = e, o = `lumal-icon-gradient-${b()}`, s = P(), c = t(() => {
34
- if (a.name) return s.resolve(a.name);
35
- }), l = t(() => {
36
- let e = a.icon, t = c.value?.svgText ?? (typeof e == "string" && e.trim().startsWith("<svg") ? e : "") ?? (typeof e == "object" && e && "svgText" in e ? String(e.svgText ?? "") : "");
37
- return t ? a.gradient ? k(t, {
38
- ...a.gradient,
39
- id: a.gradient.id ?? o
40
- }) : M(t, a.color) : "";
41
- }), u = t(() => {
42
- let e = c.value?.component;
43
- if (typeof e == "function" || typeof e == "object" && e) return e;
44
- if (typeof a.icon == "object" && a.icon && "component" in a.icon) {
45
- let e = a.icon.component;
46
- return typeof e == "function" || typeof e == "object" && e ? e : void 0;
33
+ let t = e, o = `lumal-icon-gradient-${C()}`, s = I(), c = n(() => {
34
+ let e = t.name ? s.resolve(t.name) : void 0;
35
+ if (e) return e;
36
+ let n = t.icon;
37
+ return n && typeof n == "object" && "source" in n && "key" in n ? n : void 0;
38
+ }), l = n(() => {
39
+ let e = t.icon, n = c.value?.svgText ?? (typeof e == "string" && e.trim().startsWith("<svg") ? e : "");
40
+ return n ? t.gradient ? M(n, {
41
+ ...t.gradient,
42
+ id: t.gradient.id ?? o
43
+ }) : N(n, t.color) : "";
44
+ }), u = n(() => {
45
+ if (c.value) {
46
+ let e = c.value.source === "component" ? c.value.component : void 0;
47
+ return typeof e == "function" || typeof e == "object" && e ? x(e) : void 0;
47
48
  }
48
- return typeof a.icon == "function" || typeof a.icon == "object" ? a.icon : void 0;
49
- }), f = t(() => {
49
+ return typeof t.icon == "function" || typeof t.icon == "object" ? x(t.icon) : void 0;
50
+ }), d = n(() => {
50
51
  if (c.value?.source === "iconify") return c.value.icon;
51
- if (typeof a.icon == "object" && a.icon && "source" in a.icon && a.icon.source === "iconify") return a.icon.icon;
52
- }), m = t(() => ({
53
- "--lumal-icon-size": typeof a.size == "number" ? `${a.size}px` : a.size ?? "1em",
54
- color: a.color
55
- })), h = t(() => !!(l.value || u.value || f.value)), _ = t(() => a.title ?? c.value?.label);
56
- return (e, t) => h.value ? (p(), i("span", {
52
+ }), p = n(() => ({
53
+ "--lumal-icon-size": typeof t.size == "number" ? `${t.size}px` : t.size ?? "1em",
54
+ color: t.color
55
+ })), m = n(() => !!(l.value || u.value || d.value)), g = n(() => t.title ?? c.value?.label);
56
+ return (e, t) => m.value ? (h(), a("span", {
57
57
  key: 0,
58
58
  class: "lumal-icon",
59
- style: d(m.value),
60
- title: _.value,
59
+ style: f(p.value),
60
+ title: g.value,
61
61
  "aria-hidden": "true"
62
- }, [u.value ? (p(), n(g(u.value), {
62
+ }, [u.value ? (h(), r(v(u.value), {
63
63
  key: 0,
64
64
  class: "lumal-icon__component"
65
- })) : f.value ? (p(), n(y(O), {
65
+ })) : d.value ? (h(), r(S(j), {
66
66
  key: 1,
67
67
  class: "lumal-icon__component",
68
- icon: f.value
69
- }, null, 8, ["icon"])) : (p(), i("span", {
68
+ icon: d.value
69
+ }, null, 8, ["icon"])) : (h(), a("span", {
70
70
  key: 2,
71
71
  class: "lumal-icon__svg",
72
72
  innerHTML: l.value
73
- }, null, 8, I))], 12, F)) : r("", !0);
73
+ }, null, 8, R))], 12, L)) : i("", !0);
74
74
  }
75
- }), R = (e, t) => {
75
+ }), B = (e, t) => {
76
76
  let n = e.__vccOpts || e;
77
77
  for (let [e, r] of t) n[e] = r;
78
78
  return n;
79
- }, z = /*#__PURE__*/ R(L, [["__scopeId", "data-v-d5c4f92d"]]), B = { class: "lumal-icon-picker" }, V = { class: "lumal-icon-picker__toolbar" }, H = {
79
+ }, V = /*#__PURE__*/ B(z, [["__scopeId", "data-v-f5cc1719"]]), H = { class: "lumal-icon-picker" }, U = { class: "lumal-icon-picker__toolbar" }, W = {
80
80
  key: 0,
81
81
  class: "lumal-icon-picker__field"
82
- }, U = {
82
+ }, G = {
83
83
  key: 1,
84
84
  class: "lumal-icon-picker__field"
85
- }, W = ["value"], G = {
85
+ }, K = ["value"], q = {
86
86
  class: "lumal-icon-picker__summary",
87
87
  role: "status"
88
- }, K = {
88
+ }, J = {
89
89
  key: 0,
90
90
  class: "lumal-icon-picker__grid",
91
91
  role: "listbox",
92
92
  "aria-label": "图标列表"
93
- }, q = [
93
+ }, Y = [
94
94
  "aria-label",
95
95
  "aria-selected",
96
96
  "title",
97
97
  "onClick"
98
- ], J = { key: 0 }, Y = {
98
+ ], X = { key: 0 }, Z = {
99
99
  key: 1,
100
100
  class: "lumal-icon-picker__empty"
101
- }, X = {
101
+ }, ne = {
102
102
  key: 2,
103
103
  class: "lumal-icon-picker__pagination"
104
- }, Z = ["disabled"], Q = ["disabled"], $ = /*#__PURE__*/ R(/* @__PURE__ */ s({
104
+ }, re = ["disabled"], ie = ["disabled"], Q = /*#__PURE__*/ B(/* @__PURE__ */ c({
105
105
  __name: "LumalIconPicker",
106
- props: /*@__PURE__*/ c({
106
+ props: /*@__PURE__*/ l({
107
107
  group: { default: "" },
108
108
  pageSize: { default: 48 },
109
109
  searchable: {
@@ -119,76 +119,76 @@ var F = ["title"], I = ["innerHTML"], L = /*@__PURE__*/ s({
119
119
  modelValue: {},
120
120
  modelModifiers: {}
121
121
  }),
122
- emits: /*@__PURE__*/ c(["select"], ["update:modelValue"]),
123
- setup(n, { emit: s }) {
124
- let c = n, l = s, d = x(n, "modelValue"), f = m(""), g = m(c.group), _ = m(1), y = t(() => Math.max(1, c.pageSize)), b = P(), E = b.icons, D = t(() => {
125
- let e = b.groups.value, t = new Set(e.map((e) => e.key)), n = E.value.map((e) => e.group).filter((e) => typeof e == "string" && !t.has(e)).filter((e, t, n) => n.indexOf(e) === t).map((e) => ({
122
+ emits: /*@__PURE__*/ l(["select"], ["update:modelValue"]),
123
+ setup(t, { emit: r }) {
124
+ let c = t, l = r, u = w(t, "modelValue"), f = g(""), p = g(c.group), m = g(1), v = n(() => Math.max(1, c.pageSize)), y = I(), x = y.icons, S = n(() => {
125
+ let e = y.groups.value, t = new Set(e.map((e) => e.key)), n = x.value.map((e) => e.group).filter((e) => typeof e == "string" && !t.has(e)).filter((e, t, n) => n.indexOf(e) === t).map((e) => ({
126
126
  key: e,
127
127
  label: e
128
128
  }));
129
129
  return [...e, ...n];
130
- }), O = t(() => {
130
+ }), C = n(() => {
131
131
  let e = f.value.trim().toLocaleLowerCase();
132
- return E.value.filter((t) => {
133
- let n = !g.value || t.group === g.value, r = !e || t.key.toLocaleLowerCase().includes(e) || t.label?.toLocaleLowerCase().includes(e);
132
+ return x.value.filter((t) => {
133
+ let n = !p.value || t.group === p.value, r = !e || t.key.toLocaleLowerCase().includes(e) || t.label?.toLocaleLowerCase().includes(e);
134
134
  return n && r;
135
135
  });
136
- }), k = t(() => Math.max(1, Math.ceil(O.value.length / y.value))), A = t(() => {
137
- let e = (_.value - 1) * y.value;
138
- return O.value.slice(e, e + y.value);
136
+ }), T = n(() => Math.max(1, Math.ceil(C.value.length / v.value))), A = n(() => {
137
+ let e = (m.value - 1) * v.value;
138
+ return C.value.slice(e, e + v.value);
139
139
  });
140
- w([
140
+ O([
141
141
  f,
142
- g,
143
- y
142
+ p,
143
+ v
144
144
  ], () => {
145
- _.value = 1;
146
- }), w(() => c.group, (e) => {
147
- g.value = e;
148
- }), w(k, (e) => {
149
- _.value = Math.min(_.value, e);
150
- }), c.storageKey && typeof localStorage < "u" && !d.value && (d.value = localStorage.getItem(c.storageKey) ?? void 0);
145
+ m.value = 1;
146
+ }), O(() => c.group, (e) => {
147
+ p.value = e;
148
+ }), O(T, (e) => {
149
+ m.value = Math.min(m.value, e);
150
+ }), c.storageKey && typeof localStorage < "u" && !u.value && (u.value = localStorage.getItem(c.storageKey) ?? void 0);
151
151
  function j(e) {
152
- d.value = e.key, c.storageKey && typeof localStorage < "u" && localStorage.setItem(c.storageKey, e.key), l("select", e);
152
+ u.value = e.key, c.storageKey && typeof localStorage < "u" && localStorage.setItem(c.storageKey, e.key), l("select", e);
153
153
  }
154
- return (t, s) => (p(), i("div", B, [
155
- a("div", V, [n.searchable ? (p(), i("label", H, [s[4] ||= a("span", { class: "lumal-icon-picker__field-label" }, "搜索图标", -1), T(a("input", {
156
- "onUpdate:modelValue": s[0] ||= (e) => f.value = e,
154
+ return (n, r) => (h(), a("div", H, [
155
+ o("div", U, [t.searchable ? (h(), a("label", W, [r[4] ||= o("span", { class: "lumal-icon-picker__field-label" }, "搜索图标", -1), k(o("input", {
156
+ "onUpdate:modelValue": r[0] ||= (e) => f.value = e,
157
157
  type: "search",
158
158
  placeholder: "输入名称或 key"
159
- }, null, 512), [[C, f.value]])])) : r("", !0), D.value.length ? (p(), i("label", U, [s[6] ||= a("span", { class: "lumal-icon-picker__field-label" }, "图标分组", -1), T(a("select", { "onUpdate:modelValue": s[1] ||= (e) => g.value = e }, [s[5] ||= a("option", { value: "" }, "全部分组", -1), (p(!0), i(e, null, h(D.value, (e) => (p(), i("option", {
159
+ }, null, 512), [[D, f.value]])])) : i("", !0), S.value.length ? (h(), a("label", G, [r[6] ||= o("span", { class: "lumal-icon-picker__field-label" }, "图标分组", -1), k(o("select", { "onUpdate:modelValue": r[1] ||= (e) => p.value = e }, [r[5] ||= o("option", { value: "" }, "全部分组", -1), (h(!0), a(e, null, _(S.value, (e) => (h(), a("option", {
160
160
  key: e.key,
161
161
  value: e.key
162
- }, v(e.label), 9, W))), 128))], 512), [[S, g.value]])])) : r("", !0)]),
163
- a("p", G, " 共 " + v(O.value.length) + " 个图标 ", 1),
164
- A.value.length ? (p(), i("div", K, [(p(!0), i(e, null, h(A.value, (e) => (p(), i("button", {
162
+ }, b(e.label), 9, K))), 128))], 512), [[E, p.value]])])) : i("", !0)]),
163
+ o("p", q, " 共 " + b(C.value.length) + " 个图标 ", 1),
164
+ A.value.length ? (h(), a("div", J, [(h(!0), a(e, null, _(A.value, (e) => (h(), a("button", {
165
165
  key: e.key,
166
- class: u(["lumal-icon-picker__item", { "is-selected": d.value === e.key }]),
166
+ class: d(["lumal-icon-picker__item", { "is-selected": u.value === e.key }]),
167
167
  type: "button",
168
168
  role: "option",
169
169
  "aria-label": e.label || e.key,
170
- "aria-selected": d.value === e.key,
170
+ "aria-selected": u.value === e.key,
171
171
  title: e.label || e.key,
172
172
  onClick: (t) => j(e)
173
- }, [o(z, { name: e.key }, null, 8, ["name"]), n.showLabels ? (p(), i("span", J, v(e.label || e.key), 1)) : r("", !0)], 10, q))), 128))])) : (p(), i("p", Y, " 未找到匹配图标 ")),
174
- k.value > 1 ? (p(), i("footer", X, [
175
- a("button", {
173
+ }, [s(V, { name: e.key }, null, 8, ["name"]), t.showLabels ? (h(), a("span", X, b(e.label || e.key), 1)) : i("", !0)], 10, Y))), 128))])) : (h(), a("p", Z, " 未找到匹配图标 ")),
174
+ T.value > 1 ? (h(), a("footer", ne, [
175
+ o("button", {
176
176
  type: "button",
177
- disabled: _.value <= 1,
178
- onClick: s[2] ||= (e) => --_.value
179
- }, " 上一页 ", 8, Z),
180
- a("span", null, "第 " + v(_.value) + " / " + v(k.value) + " 页", 1),
181
- a("button", {
177
+ disabled: m.value <= 1,
178
+ onClick: r[2] ||= (e) => --m.value
179
+ }, " 上一页 ", 8, re),
180
+ o("span", null, "第 " + b(m.value) + " / " + b(T.value) + " 页", 1),
181
+ o("button", {
182
182
  type: "button",
183
- disabled: _.value >= k.value,
184
- onClick: s[3] ||= (e) => _.value += 1
185
- }, " 下一页 ", 8, Q)
186
- ])) : r("", !0)
183
+ disabled: m.value >= T.value,
184
+ onClick: r[3] ||= (e) => m.value += 1
185
+ }, " 下一页 ", 8, ie)
186
+ ])) : i("", !0)
187
187
  ]));
188
188
  }
189
- }), [["__scopeId", "data-v-937c0d9c"]]), te = ["aria-label"], ne = { class: "lumal-icon-picker-dialog__header" }, re = { class: "lumal-icon-picker-dialog__content" }, ie = { class: "lumal-icon-picker-dialog__footer" }, ae = ["disabled"], oe = /*#__PURE__*/ R(/* @__PURE__ */ s({
189
+ }), [["__scopeId", "data-v-937c0d9c"]]), ae = ["aria-label"], oe = { class: "lumal-icon-picker-dialog__header" }, $ = { class: "lumal-icon-picker-dialog__content" }, se = { class: "lumal-icon-picker-dialog__footer" }, ce = ["disabled"], le = /*#__PURE__*/ B(/* @__PURE__ */ c({
190
190
  __name: "LumalIconPickerDialog",
191
- props: /*@__PURE__*/ c({
191
+ props: /*@__PURE__*/ l({
192
192
  cancelText: { default: "取消" },
193
193
  confirmText: { default: "确认选择" },
194
194
  title: { default: "选择图标" }
@@ -201,53 +201,71 @@ var F = ["title"], I = ["innerHTML"], L = /*@__PURE__*/ s({
201
201
  modelValue: {},
202
202
  modelModifiers: {}
203
203
  }),
204
- emits: /*@__PURE__*/ c(["cancel", "confirm"], ["update:visible", "update:modelValue"]),
205
- setup(e, { emit: t }) {
206
- let n = t, s = x(e, "visible"), c = x(e, "modelValue"), u = m(""), d = m();
207
- w(s, async (e) => {
208
- e && (u.value = c.value ?? "", await l(), d.value?.focus());
209
- }, { immediate: !0 });
210
- function f() {
211
- s.value = !1, n("cancel");
204
+ emits: /*@__PURE__*/ l(["cancel", "confirm"], ["update:visible", "update:modelValue"]),
205
+ setup(e, { emit: n }) {
206
+ let c = n, l = w(e, "visible"), d = w(e, "modelValue"), f = y(""), m = T("dialogRef"), g;
207
+ function _(e) {
208
+ l.value && m.value && !m.value.contains(e.target) && m.value.focus();
212
209
  }
213
- function h() {
214
- u.value && (c.value = u.value, s.value = !1, n("confirm", u.value));
210
+ function v(e) {
211
+ if (e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), x()), e.key !== "Tab") return;
212
+ let t = [...m.value?.querySelectorAll("button, input, select, textarea, a[href], [tabindex]") ?? []].filter((e) => e.tabIndex >= 0 && !e.matches(":disabled") && !e.closest("[hidden], [inert]")), n = t[0], r = t.at(-1);
213
+ (!n || (e.shiftKey ? document.activeElement === n || document.activeElement === m.value : document.activeElement === r || document.activeElement === m.value)) && (e.preventDefault(), (e.shiftKey ? r : n)?.focus());
215
214
  }
216
- return (t, n) => s.value ? (p(), i("div", {
215
+ O(l, async (e) => {
216
+ if (!(typeof document > "u")) {
217
+ if (!e) {
218
+ document.removeEventListener("focusin", _);
219
+ let e = g;
220
+ await u(), !l.value && e?.isConnected && e.focus();
221
+ return;
222
+ }
223
+ g = document.activeElement instanceof HTMLElement ? document.activeElement : void 0, f.value = d.value ?? "", await u(), l.value && (m.value?.focus(), document.addEventListener("focusin", _));
224
+ }
225
+ }, { immediate: !0 }), p(() => {
226
+ document.removeEventListener("focusin", _), g?.isConnected && g.focus();
227
+ });
228
+ function x() {
229
+ l.value = !1, c("cancel");
230
+ }
231
+ function S() {
232
+ f.value && (d.value = f.value, l.value = !1, c("confirm", f.value));
233
+ }
234
+ return (n, c) => (h(), r(t, { to: "body" }, [l.value ? (h(), a("div", {
217
235
  key: 0,
218
236
  class: "lumal-icon-picker-dialog",
219
237
  role: "presentation",
220
- onMousedown: D(f, ["self"])
221
- }, [a("section", {
238
+ onMousedown: A(x, ["self"])
239
+ }, [o("section", {
222
240
  ref_key: "dialogRef",
223
- ref: d,
241
+ ref: m,
224
242
  class: "lumal-icon-picker-dialog__body",
225
243
  role: "dialog",
226
244
  "aria-modal": "true",
227
245
  "aria-label": e.title,
228
246
  tabindex: "-1",
229
- onKeydown: E(f, ["esc"])
247
+ onKeydown: v
230
248
  }, [
231
- a("header", ne, [a("h3", null, v(e.title), 1), a("button", {
249
+ o("header", oe, [o("h3", null, b(e.title), 1), o("button", {
232
250
  type: "button",
233
251
  "aria-label": "关闭图标选择器",
234
- onClick: f
252
+ onClick: x
235
253
  }, " × ")]),
236
- a("div", re, [o($, {
237
- modelValue: u.value,
238
- "onUpdate:modelValue": n[0] ||= (e) => u.value = e
254
+ o("div", $, [s(Q, {
255
+ modelValue: f.value,
256
+ "onUpdate:modelValue": c[0] ||= (e) => f.value = e
239
257
  }, null, 8, ["modelValue"])]),
240
- a("footer", ie, [a("button", {
258
+ o("footer", se, [o("button", {
241
259
  type: "button",
242
- onClick: f
243
- }, v(e.cancelText), 1), a("button", {
260
+ onClick: x
261
+ }, b(e.cancelText), 1), o("button", {
244
262
  type: "button",
245
263
  class: "is-primary",
246
- disabled: !u.value,
247
- onClick: h
248
- }, v(e.confirmText), 9, ae)])
249
- ], 40, te)], 32)) : r("", !0);
264
+ disabled: !f.value,
265
+ onClick: S
266
+ }, b(e.confirmText), 9, ce)])
267
+ ], 40, ae)], 32)) : i("", !0)]));
250
268
  }
251
- }), [["__scopeId", "data-v-9bd629e7"]]);
269
+ }), [["__scopeId", "data-v-a6a04d17"]]);
252
270
  //#endregion
253
- export { z as LumalIcon, $ as LumalIconPicker, oe as LumalIconPickerDialog, P as useIconRegistry };
271
+ export { V as LumalIcon, Q as LumalIconPicker, le as LumalIconPickerDialog, I as useIconRegistry };
@@ -1 +1 @@
1
- {"version":3,"file":"LumalIcon.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIcon.vue"],"names":[],"mappings":"AAuIA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAMpC,kDAAkD;AAClD,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,GAAG,MAAM,CAAA;IACrD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;AAyJF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"LumalIcon.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIcon.vue"],"names":[],"mappings":"AA+HA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAMpC,kDAAkD;AAClD,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,GAAG,MAAM,CAAA;IACrD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;AAiJF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1 +1 @@
1
- {"version":3,"file":"LumalIconPickerDialog.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIconPickerDialog.vue"],"names":[],"mappings":"AAkLA,mDAAmD;AACnD,KAAK,WAAW,GAAG;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;AA+CF,KAAK,gBAAgB,GAAG;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAWF,KAAK,iBAAiB,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAqGxD,QAAA,MAAM,YAAY;;;;;;;;;;;WAnKR,MAAM;gBAFD,MAAM;iBACL,MAAM;6EAwKpB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"LumalIconPickerDialog.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIconPickerDialog.vue"],"names":[],"mappings":"AA+NA,mDAAmD;AACnD,KAAK,WAAW,GAAG;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;AA0FF,KAAK,gBAAgB,GAAG;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAWF,KAAK,iBAAiB,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAoHxD,QAAA,MAAM,YAAY;;;;;;;;;;;WA7NR,MAAM;gBAFD,MAAM;iBACL,MAAM;6EAkOpB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lumal/icons-vue",
3
3
  "type": "module",
4
- "version": "0.0.2-beta",
4
+ "version": "0.0.3-beta",
5
5
  "description": "Vue components and reactive adapters for @lumal/icons.",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -29,6 +29,7 @@
29
29
  "module": "./dist/index.js",
30
30
  "types": "./dist/src/index.d.ts",
31
31
  "files": [
32
+ "CHANGELOG.md",
32
33
  "README.md",
33
34
  "dist"
34
35
  ],
@@ -37,7 +38,7 @@
37
38
  "vue": "^3.5.0"
38
39
  },
39
40
  "dependencies": {
40
- "@lumal/icons": "0.0.2-beta"
41
+ "@lumal/icons": "0.0.3-beta"
41
42
  },
42
43
  "scripts": {
43
44
  "build": "vite build --config vite.config.ts && vue-tsc -p tsconfig.json --emitDeclarationOnly --outDir dist && node ../../scripts/clean-package-dist.mjs dist",