@lumal/icons-vue 0.0.3-beta → 0.0.5-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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @lumal/icons-vue
2
2
 
3
+ ## 0.0.5-beta (2026-10-20)
4
+
5
+ ### Patch Changes
6
+
7
+ - 同步内部图标依赖和 fixed-group 版本至 0.0.5-beta,保持现有公开 API。
8
+
9
+ ## 0.0.4-beta (2026-10-20)
10
+
11
+ ### Minor Changes
12
+
13
+ - LumalIcon 增加 morph 和 morphSpring,复用通用转换并动态加载官方 Vue 绑定;SSR、减少动画或加载失败时保留静态图标。
14
+ - 图标选择器及弹窗公开 group-select 插槽与类型,允许消费应用接入 UI 分组控件,不在图标包中依赖 Element Plus。
15
+
16
+ ### Patch Changes
17
+
18
+ - 修复名称换行、弹窗分页与尺寸布局,补充选择回写、组件复用和动画清理测试。
19
+ - 同步 @lumal/icons 至 0.0.4-beta,保持静态图标不加载 Morphicons 引擎。
20
+
3
21
  ## 0.0.3-beta (2026-10-16)
4
22
 
5
23
  ### Patch Changes
package/README.md CHANGED
@@ -15,4 +15,43 @@ import '@lumal/icons-vue/style.css'
15
15
 
16
16
  SVG 改色、渐变、合成、Data URI 和注册表等纯 TypeScript 能力由 `@lumal/icons` 提供。
17
17
 
18
+ ## 选择器布局
19
+
20
+ `LumalIconPicker` 的 `pageSize` 默认 48;启用 `showLabels` 时格子会加宽,名称完整换行显示。搜索和原生分组控件高度一致,默认 32px,可跟随 `--el-component-size` 调整,不引入 Element Plus 运行时。
21
+
22
+ `LumalIconPickerDialog` 每页 48 个图标,桌面为 8 列,小屏幕为 6 或 4 列,完整页面不会出现不足一行的尾行;末页按实际剩余数量展示。Admin 图标库默认每页 72 个,可切换到 96 个。
23
+
24
+ 弹窗高度随视口限制固定,搜索、分组切换或末页图标变少不会改变外框高度;头尾固定,中间内容独立滚动,并预留滚动条宽度。
25
+
26
+ ## 分组控件适配
27
+
28
+ `LumalIconPicker` 默认使用原生分组下拉框,不强制依赖 Element Plus。`LumalIconPicker` 与 `LumalIconPickerDialog` 都提供 `group-select` 插槽,接收 `{ modelValue, groups, setGroup }`;类型 `LumalIconPickerGroupSelectSlotProps` 从本包导出。
29
+
30
+ Vue + Element Plus 应用可在该插槽内使用 `ElSelect` / `ElOption`,将 `modelValue` 作为当前值,并在更新时调用 `setGroup`。弹窗中的下拉层应设置 `:teleported="false"`,避免离开弹窗的焦点边界。Element Plus 组件、样式及 `@element-plus/icons-vue` 图标集由应用自行引入,不进入两个图标包的依赖。
31
+
32
+ 分组插槽外层不使用原生 `label` 包裹,避免内联选项层选择后再次激活控件;自定义分组控件应保留 `aria-label` 等可访问名称。
33
+
34
+ Admin 已接入 Element Plus 分组控件,并将官方图标集预生成为应用侧可信 SVG,按需注册到 `element-plus` 分组。所有图标仍通过 `LumalIcon` 渲染,完整 Vue 组件图标集不进入运行时。
35
+
36
+ Admin 的 Iconify 分组预置 16 个离线示例图标,包含 15 个 Lucide 常用图标及原有徽标,支持中文搜索;数据与许可留在应用侧,不引入整套图标集依赖或远程请求。
37
+
38
+ ## 状态形变
39
+
40
+ 当前源码在同一个 `LumalIcon` 中提供可选形变;已发布版本请以安装包的声明文件为准。
41
+
42
+ ```vue
43
+ <LumalIcon :name="iconName" morph morph-spring="smooth" :size="20" />
44
+ ```
45
+
46
+ - `morph?: boolean` 默认 `false`。
47
+ - `morphSpring?: LumalIconMorphSpring` 默认 `'smooth'`;从本包导出该类型,可选 `'smooth' | 'snappy' | 'bouncy'`。
48
+ - 首次直接显示,后续形状变化才播放。保留实例,不使用 `:key="iconName"`;连续切换从中间形状继续,改色或缩放不重播。
49
+ - 支持带有效 `viewBox` 的可信单色 SVG(注册名称、直接定义、SVG 字符串)。组件、Iconify、渐变及无法保真转换的 SVG 保持静态渲染。
50
+ - 复用 `@lumal/icons/morph` 的通用转换,再按需加载 `morphicons@2.0.0` 官方 Vue 绑定;填充归一化就绪前、SSR 和加载失败时均保留原始静态 SVG。静态消费者不加载引擎,ESM/CJS 均可消费。
51
+ - 遵守系统减少动画设置,关闭、卸载和失败时清理动画。保留尺寸、颜色继承和标题;图标按钮仍需提供 `aria-label`。
52
+
53
+ 形变不限定 Vue:非 Vue 项目可使用 `@lumal/icons/morph` 的 `createIconMorph` DOM 控制器或 `prepareIconMorph` 转换数据,并安装其可选 Morphicons peer。Vue 包已将 Morphicons 作为依赖,内核静态入口仍无强制运行时依赖。SVG/Data URI 输出和选择器不受影响。
54
+
55
+ Admin 图标示例新增懒加载的“形变动画”标签,并在主题、侧栏、内容最大化和表格全屏入口使用状态形变。完整边界见仓库 `docs/icons.md`。
56
+
18
57
  `LumalIcon` 接受注册名或直接 `IconDefinition`(component / iconify / local-svg)。SVG 使用 HTML 渲染,仅接受可信静态资源;注册和渲染不自动净化,单色格式校验不是完整 sanitizer。图标选择弹窗通过 Teleport 挂载到 body,约束 Tab、支持 Escape,并在关闭/卸载时恢复焦点。
@@ -1,2 +1,2 @@
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}}
1
+ .lumal-icon[data-v-42fa0af8]{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-42fa0af8],.lumal-icon__component[data-v-42fa0af8]{width:100%;height:100%}.lumal-icon__svg[data-v-42fa0af8] svg{width:100%;height:100%;display:block}.lumal-icon-picker[data-v-0b9c266c]{gap:12px;min-width:0;display:grid}.lumal-icon-picker__toolbar[data-v-0b9c266c]{grid-template-columns:minmax(0,1fr) minmax(140px,200px);align-items:start;gap:12px;display:grid}.lumal-icon-picker__field[data-v-0b9c266c]{gap:6px;min-width:0;display:grid}.lumal-icon-picker__field-label[data-v-0b9c266c],.lumal-icon-picker__summary[data-v-0b9c266c],.lumal-icon-picker__empty[data-v-0b9c266c]{color:var(--el-text-color-secondary,CanvasText);font-size:13px}.lumal-icon-picker__field input[data-v-0b9c266c],.lumal-icon-picker__field select[data-v-0b9c266c],.lumal-icon-picker__pagination button[data-v-0b9c266c]{box-sizing:border-box;height:var(--el-component-size,32px);min-height:var(--el-component-size,32px);border:1px solid var(--el-border-color,currentColor);border-radius:var(--lumal-radius-base,8px);color:var(--el-text-color-primary,CanvasText);background:var(--el-bg-color,Canvas);font:inherit;font-size:var(--lumal-font-size-base,14px);padding:0 12px}.lumal-icon-picker__field input[data-v-0b9c266c],.lumal-icon-picker__field select[data-v-0b9c266c]{width:100%;min-width:0}.lumal-icon-picker__summary[data-v-0b9c266c],.lumal-icon-picker__empty[data-v-0b9c266c]{margin:0}.lumal-icon-picker__grid[data-v-0b9c266c]{grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:8px;display:grid}.lumal-icon-picker--show-labels .lumal-icon-picker__grid[data-v-0b9c266c]{grid-template-columns:repeat(auto-fill,minmax(min(96px,100%),1fr));grid-auto-rows:minmax(84px,auto)}.lumal-icon-picker__item[data-v-0b9c266c]{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-0b9c266c]:hover,.lumal-icon-picker__item.is-selected[data-v-0b9c266c]{border-color:var(--el-color-primary,Highlight);background:var(--el-color-primary-light-9,Canvas)}.lumal-icon-picker__item[data-v-0b9c266c]:focus-visible,.lumal-icon-picker__field input[data-v-0b9c266c]:focus-visible,.lumal-icon-picker__field select[data-v-0b9c266c]:focus-visible,.lumal-icon-picker__pagination button[data-v-0b9c266c]:focus-visible{outline:2px solid var(--el-color-primary,Highlight);outline-offset:2px}.lumal-icon-picker__item-label[data-v-0b9c266c]{width:100%;max-width:100%;font-size:calc(var(--lumal-font-size-base,14px) - 2px);text-align:center;white-space:normal;overflow-wrap:anywhere;line-height:1.4}.lumal-icon-picker__pagination[data-v-0b9c266c]{justify-content:center;align-items:center;gap:12px;display:flex}.lumal-icon-picker__pagination button[data-v-0b9c266c]:disabled{cursor:not-allowed;opacity:.5}@media (width<=640px){.lumal-icon-picker__toolbar[data-v-0b9c266c]{grid-template-columns:minmax(0,1fr)}}@media (prefers-reduced-motion:reduce){.lumal-icon-picker__item[data-v-0b9c266c]{transition:none}}.lumal-icon-picker-dialog[data-v-ee548916]{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-ee548916]{border-radius:var(--lumal-radius-large,12px);width:min(680px,100%);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));grid-template-rows:auto minmax(0,1fr) auto;display:grid;overflow:hidden}.lumal-icon-picker-dialog__header[data-v-ee548916],.lumal-icon-picker-dialog__footer[data-v-ee548916]{justify-content:space-between;align-items:center;gap:12px;min-height:56px;padding:12px 20px;display:flex}.lumal-icon-picker-dialog__header[data-v-ee548916]{border-bottom:1px solid var(--el-border-color-lighter,currentColor)}.lumal-icon-picker-dialog__header h3[data-v-ee548916]{margin:0;font-size:17px}.lumal-icon-picker-dialog__content[data-v-ee548916]{scrollbar-gutter:stable;min-height:0;padding:20px;overflow:auto}.lumal-icon-picker-dialog__content[data-v-ee548916] .lumal-icon-picker__grid{grid-template-columns:repeat(8,minmax(0,1fr))}.lumal-icon-picker-dialog__footer[data-v-ee548916]{border-top:1px solid var(--el-border-color-lighter,currentColor);justify-content:flex-end}.lumal-icon-picker-dialog button[data-v-ee548916]{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-ee548916]{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-ee548916]:disabled{cursor:not-allowed;opacity:.5}@media (width<=640px){.lumal-icon-picker-dialog[data-v-ee548916]{align-items:flex-end;padding:0}.lumal-icon-picker-dialog__body[data-v-ee548916]{border-radius:var(--lumal-radius-large,12px) var(--lumal-radius-large,12px) 0 0;height:min(680px,92dvh)}}@media (width<=480px){.lumal-icon-picker-dialog__content[data-v-ee548916] .lumal-icon-picker__grid{grid-template-columns:repeat(6,minmax(0,1fr))}}@media (width<=360px){.lumal-icon-picker-dialog__content[data-v-ee548916] .lumal-icon-picker__grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
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)(()=>{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;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("vue"),t=require("@iconify/vue"),n=require("@lumal/icons"),r=require("@lumal/icons/morph");var i;function a(){return i??=import(`morphicons/vue`).then(e=>({MorphIcon:e.MorphIcon})).catch(e=>{throw i=void 0,e}),i}function o(t,n){let i=(0,e.shallowRef)(!1),o=(0,e.shallowRef)(!1),s=(0,e.shallowRef)(),c;return(0,e.onMounted)(()=>{i.value=!0}),(0,e.watch)([i,()=>(0,e.toValue)(n)],([e,t],n,r)=>{if(o.value=!1,!e||!t)return;let i=typeof window.matchMedia==`function`?window.matchMedia(`(prefers-reduced-motion: reduce)`):void 0,a=()=>{o.value=i?.matches??!1};a(),typeof i?.addEventListener==`function`?i.addEventListener(`change`,a):i?.addListener?.(a),r(()=>{typeof i?.removeEventListener==`function`?i.removeEventListener(`change`,a):i?.removeListener?.(a)})},{flush:`sync`}),(0,e.watch)([i,o,()=>(0,e.toValue)(t),()=>(0,e.toValue)(n)],async([e,t,n,i],o,l)=>{let u=!1;if(l(()=>{u=!0}),!e||t||!i||!n){s.value=void 0;return}try{let e=await(0,r.prepareIconMorph)(n);if(u)return;if(!e){s.value=void 0;return}if(c??=await a(),u)return;s.value={...e,icon:s.value?.shape===e.shape?s.value.icon:e.icon,component:c.MorphIcon}}catch{u||(s.value=void 0)}},{immediate:!0}),{state:s,reset:()=>{s.value=void 0}}}function s(){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 c=[`title`],l=[`innerHTML`],u=(0,e.defineComponent)({__name:`LumalIcon`,props:{name:{},icon:{},size:{},color:{},gradient:{},title:{},morph:{type:Boolean},morphSpring:{}},setup(r){let i=r,a=`lumal-icon-gradient-${(0,e.useId)()}`,u=s(),d=(0,e.computed)(()=>{let e=i.name?u.resolve(i.name):void 0;if(e)return e;let t=i.icon;return t&&typeof t==`object`&&`source`in t&&`key`in t?t:void 0}),f=(0,e.computed)(()=>{let e=i.icon;return d.value?.svgText??(typeof e==`string`&&e.trim().startsWith(`<svg`)?e:``)}),p=(0,e.computed)(()=>{let e=f.value;return e?i.gradient?(0,n.applySvgGradient)(e,{...i.gradient,id:i.gradient.id??a}):(0,n.recolorSvgString)(e,i.color):``}),m=(0,e.computed)(()=>{if(d.value){let t=d.value.source===`component`?d.value.component:void 0;return typeof t==`function`||typeof t==`object`&&t?(0,e.toRaw)(t):void 0}return typeof i.icon==`function`||typeof i.icon==`object`?(0,e.toRaw)(i.icon):void 0}),h=(0,e.computed)(()=>{if(d.value?.source===`iconify`)return d.value.icon}),{state:g,reset:_}=o(f,()=>i.morph===!0&&!i.gradient&&!m.value&&!h.value);(0,e.onErrorCaptured)(()=>{if(g.value)return _(),!1});let v=(0,e.computed)(()=>({"--lumal-icon-size":typeof i.size==`number`?`${i.size}px`:i.size??`1em`,color:i.color})),y=(0,e.computed)(()=>!!(p.value||m.value||h.value)),b=(0,e.computed)(()=>i.title??d.value?.label);return(n,i)=>y.value?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,{key:0,class:`lumal-icon`,style:(0,e.normalizeStyle)(v.value),title:b.value,"aria-hidden":`true`},[m.value?((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)(m.value),{key:0,class:`lumal-icon__component`})):h.value?((0,e.openBlock)(),(0,e.createBlock)((0,e.unref)(t.Icon),{key:1,class:`lumal-icon__component`,icon:h.value},null,8,[`icon`])):(0,e.unref)(g)?((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)((0,e.unref)(g).component),{key:2,class:`lumal-icon__component`,icon:(0,e.unref)(g).icon,spring:r.morphSpring??`smooth`,color:(0,e.unref)(g).color,"stroke-width":(0,e.unref)(g).strokeWidth,"stroke-linecap":(0,e.unref)(g).linecap,"stroke-linejoin":(0,e.unref)(g).linejoin,"reduced-motion":`user`,size:`100%`},null,8,[`icon`,`spring`,`color`,`stroke-width`,`stroke-linecap`,`stroke-linejoin`])):((0,e.openBlock)(),(0,e.createElementBlock)(`span`,{key:3,class:`lumal-icon__svg`,innerHTML:p.value},null,8,l))],12,c)):(0,e.createCommentVNode)(``,!0)}}),d=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},f=d(u,[[`__scopeId`,`data-v-42fa0af8`]]),p={class:`lumal-icon-picker__toolbar`},m={key:0,class:`lumal-icon-picker__field`},h={key:1,class:`lumal-icon-picker__field`},g=[`value`],_={class:`lumal-icon-picker__summary`,role:`status`},v={key:0,class:`lumal-icon-picker__grid`,role:`listbox`,"aria-label":`图标列表`},y=[`aria-label`,`aria-selected`,`title`,`onClick`],b={key:0,class:`lumal-icon-picker__item-label`},x={key:1,class:`lumal-icon-picker__empty`},S={key:2,class:`lumal-icon-picker__pagination`},C=[`disabled`],w=[`disabled`],T=d((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 r=t,i=n,a=(0,e.useModel)(t,`modelValue`),o=(0,e.shallowRef)(``),c=(0,e.shallowRef)(r.group),l=(0,e.shallowRef)(1),u=(0,e.computed)(()=>Math.max(1,r.pageSize)),d=s(),T=d.icons,E=(0,e.computed)(()=>{let e=d.groups.value,t=new Set(e.map(e=>e.key)),n=T.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]}),D=(0,e.computed)(()=>{let e=o.value.trim().toLocaleLowerCase();return T.value.filter(t=>{let n=!c.value||t.group===c.value,r=!e||t.key.toLocaleLowerCase().includes(e)||t.label?.toLocaleLowerCase().includes(e);return n&&r})}),O=(0,e.computed)(()=>Math.max(1,Math.ceil(D.value.length/u.value))),k=(0,e.computed)(()=>{let e=(l.value-1)*u.value;return D.value.slice(e,e+u.value)});function A(e){c.value=e}(0,e.watch)([o,c,u],()=>{l.value=1}),(0,e.watch)(()=>r.group,e=>{c.value=e}),(0,e.watch)(O,e=>{l.value=Math.min(l.value,e)}),r.storageKey&&typeof localStorage<`u`&&!a.value&&(a.value=localStorage.getItem(r.storageKey)??void 0);function j(e){a.value=e.key,r.storageKey&&typeof localStorage<`u`&&localStorage.setItem(r.storageKey,e.key),i(`select`,e)}return(n,r)=>((0,e.openBlock)(),(0,e.createElementBlock)(`div`,{class:(0,e.normalizeClass)([`lumal-icon-picker`,{"lumal-icon-picker--show-labels":t.showLabels}])},[(0,e.createElementVNode)(`div`,p,[t.searchable?((0,e.openBlock)(),(0,e.createElementBlock)(`label`,m,[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=>o.value=e,type:`search`,"aria-label":`搜索图标`,placeholder:`输入名称或 key`},null,512),[[e.vModelText,o.value]])])):(0,e.createCommentVNode)(``,!0),E.value.length?((0,e.openBlock)(),(0,e.createElementBlock)(`div`,h,[r[6]||=(0,e.createElementVNode)(`span`,{class:`lumal-icon-picker__field-label`},`图标分组`,-1),(0,e.renderSlot)(n.$slots,`group-select`,{modelValue:c.value,groups:E.value,setGroup:A},()=>[(0,e.withDirectives)((0,e.createElementVNode)(`select`,{"onUpdate:modelValue":r[1]||=e=>c.value=e,"aria-label":`图标分组`},[r[5]||=(0,e.createElementVNode)(`option`,{value:``},` 全部分组 `,-1),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(E.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)(`option`,{key:t.key,value:t.key},(0,e.toDisplayString)(t.label),9,g))),128))],512),[[e.vModelSelect,c.value]])],!0)])):(0,e.createCommentVNode)(``,!0)]),(0,e.createElementVNode)(`p`,_,` 共 `+(0,e.toDisplayString)(D.value.length)+` 个图标 `,1),k.value.length?((0,e.openBlock)(),(0,e.createElementBlock)(`div`,v,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(k.value,n=>((0,e.openBlock)(),(0,e.createElementBlock)(`button`,{key:n.key,class:(0,e.normalizeClass)([`lumal-icon-picker__item`,{"is-selected":a.value===n.key}]),type:`button`,role:`option`,"aria-label":n.label||n.key,"aria-selected":a.value===n.key,title:n.label||n.key,onClick:e=>j(n)},[(0,e.createVNode)(f,{name:n.key,size:28},null,8,[`name`]),t.showLabels?((0,e.openBlock)(),(0,e.createElementBlock)(`span`,b,(0,e.toDisplayString)(n.label||n.key),1)):(0,e.createCommentVNode)(``,!0)],10,y))),128))])):((0,e.openBlock)(),(0,e.createElementBlock)(`p`,x,` 未找到匹配图标 `)),O.value>1?((0,e.openBlock)(),(0,e.createElementBlock)(`footer`,S,[(0,e.createElementVNode)(`button`,{type:`button`,disabled:l.value<=1,onClick:r[2]||=e=>--l.value},` 上一页 `,8,C),(0,e.createElementVNode)(`span`,null,`第 `+(0,e.toDisplayString)(l.value)+` / `+(0,e.toDisplayString)(O.value)+` 页`,1),(0,e.createElementVNode)(`button`,{type:`button`,disabled:l.value>=O.value,onClick:r[3]||=e=>l.value+=1},` 下一页 `,8,w)])):(0,e.createCommentVNode)(``,!0)],2))}}),[[`__scopeId`,`data-v-0b9c266c`]]),E=[`aria-label`],D={class:`lumal-icon-picker-dialog__header`},O={class:`lumal-icon-picker-dialog__content`},k={class:`lumal-icon-picker-dialog__footer`},A=[`disabled`],j=d((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 p(){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`,D,[(0,e.createElementVNode)(`h3`,null,(0,e.toDisplayString)(t.title),1),(0,e.createElementVNode)(`button`,{type:`button`,"aria-label":`关闭图标选择器`,title:`关闭图标选择器`,onClick:d},[(0,e.createVNode)(f,{name:`lumal:close`,size:18})])]),(0,e.createElementVNode)(`div`,O,[(0,e.createVNode)(T,{modelValue:o.value,"onUpdate:modelValue":r[0]||=e=>o.value=e},(0,e.createSlots)({_:2},[n.$slots[`group-select`]?{name:`group-select`,fn:(0,e.withCtx)(t=>[(0,e.renderSlot)(n.$slots,`group-select`,(0,e.normalizeProps)((0,e.guardReactiveProps)(t)),void 0,!0)]),key:`0`}:void 0]),1032,[`modelValue`])]),(0,e.createElementVNode)(`footer`,k,[(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:p},(0,e.toDisplayString)(t.confirmText),9,A)])],40,E)],32)):(0,e.createCommentVNode)(``,!0)]))}}),[[`__scopeId`,`data-v-ee548916`]]);exports.LumalIcon=f,exports.LumalIconPicker=T,exports.LumalIconPickerDialog=j,exports.useIconRegistry=s;
package/dist/index.js CHANGED
@@ -1,15 +1,74 @@
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";
1
+ import { Fragment as e, Teleport as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createSlots as s, createVNode as c, defineComponent as l, guardReactiveProps as u, mergeModels as d, nextTick as f, normalizeClass as p, normalizeProps as m, normalizeStyle as h, onBeforeUnmount as g, onErrorCaptured as _, onMounted as v, onScopeDispose as y, openBlock as b, renderList as x, renderSlot as S, resolveDynamicComponent as C, shallowRef as w, toDisplayString as T, toRaw as E, toValue as D, unref as O, useId as k, useModel as A, useTemplateRef as ee, vModelSelect as j, vModelText as M, watch as N, withCtx as te, withDirectives as P, withModifiers as ne } from "vue";
2
+ import { Icon as F } from "@iconify/vue";
3
+ import { applySvgGradient as I, getRegisteredIconDefinitions as L, getRegisteredIconGroups as R, recolorSvgString as z, resolveIconDefinition as B, subscribeIconRegistry as V } from "@lumal/icons";
4
+ import { prepareIconMorph as H } from "@lumal/icons/morph";
5
+ //#region src/runtime/morph.ts
6
+ var U;
7
+ function W() {
8
+ return U ??= import("morphicons/vue").then((e) => ({ MorphIcon: e.MorphIcon })).catch((e) => {
9
+ throw U = void 0, e;
10
+ }), U;
11
+ }
12
+ //#endregion
13
+ //#region src/composables/useIconMorph.ts
14
+ function G(e, t) {
15
+ let n = w(!1), r = w(!1), i = w(), a;
16
+ return v(() => {
17
+ n.value = !0;
18
+ }), N([n, () => D(t)], ([e, t], n, i) => {
19
+ if (r.value = !1, !e || !t) return;
20
+ let a = typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : void 0, o = () => {
21
+ r.value = a?.matches ?? !1;
22
+ };
23
+ o(), typeof a?.addEventListener == "function" ? a.addEventListener("change", o) : a?.addListener?.(o), i(() => {
24
+ typeof a?.removeEventListener == "function" ? a.removeEventListener("change", o) : a?.removeListener?.(o);
25
+ });
26
+ }, { flush: "sync" }), N([
27
+ n,
28
+ r,
29
+ () => D(e),
30
+ () => D(t)
31
+ ], async ([e, t, n, r], o, s) => {
32
+ let c = !1;
33
+ if (s(() => {
34
+ c = !0;
35
+ }), !e || t || !r || !n) {
36
+ i.value = void 0;
37
+ return;
38
+ }
39
+ try {
40
+ let e = await H(n);
41
+ if (c) return;
42
+ if (!e) {
43
+ i.value = void 0;
44
+ return;
45
+ }
46
+ if (a ??= await W(), c) return;
47
+ i.value = {
48
+ ...e,
49
+ icon: i.value?.shape === e.shape ? i.value.icon : e.icon,
50
+ component: a.MorphIcon
51
+ };
52
+ } catch {
53
+ c || (i.value = void 0);
54
+ }
55
+ }, { immediate: !0 }), {
56
+ state: i,
57
+ reset: () => {
58
+ i.value = void 0;
59
+ }
60
+ };
61
+ }
62
+ //#endregion
4
63
  //#region src/composables/useIconRegistry.ts
5
- function I() {
6
- let e = y(0);
7
- m(F(() => {
64
+ function K() {
65
+ let e = w(0);
66
+ y(V(() => {
8
67
  e.value += 1;
9
68
  }));
10
- let t = n(() => (e.value, ee())), r = n(() => (e.value, te()));
69
+ let t = n(() => (e.value, L())), r = n(() => (e.value, R()));
11
70
  function i(t) {
12
- return e.value, P(t);
71
+ return e.value, B(t);
13
72
  }
14
73
  return {
15
74
  groups: r,
@@ -19,7 +78,7 @@ function I() {
19
78
  }
20
79
  //#endregion
21
80
  //#region src/components/LumalIcon.vue?vue&type=script&setup=true&lang.ts
22
- var L = ["title"], R = ["innerHTML"], z = /*@__PURE__*/ c({
81
+ var q = ["title"], J = ["innerHTML"], Y = /*@__PURE__*/ l({
23
82
  __name: "LumalIcon",
24
83
  props: {
25
84
  name: {},
@@ -27,83 +86,113 @@ var L = ["title"], R = ["innerHTML"], z = /*@__PURE__*/ c({
27
86
  size: {},
28
87
  color: {},
29
88
  gradient: {},
30
- title: {}
89
+ title: {},
90
+ morph: { type: Boolean },
91
+ morphSpring: {}
31
92
  },
32
93
  setup(e) {
33
- let t = e, o = `lumal-icon-gradient-${C()}`, s = I(), c = n(() => {
94
+ let t = e, o = `lumal-icon-gradient-${k()}`, s = K(), c = n(() => {
34
95
  let e = t.name ? s.resolve(t.name) : void 0;
35
96
  if (e) return e;
36
97
  let n = t.icon;
37
98
  return n && typeof n == "object" && "source" in n && "key" in n ? n : void 0;
38
99
  }), 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, {
100
+ let e = t.icon;
101
+ return c.value?.svgText ?? (typeof e == "string" && e.trim().startsWith("<svg") ? e : "");
102
+ }), u = n(() => {
103
+ let e = l.value;
104
+ return e ? t.gradient ? I(e, {
41
105
  ...t.gradient,
42
106
  id: t.gradient.id ?? o
43
- }) : N(n, t.color) : "";
44
- }), u = n(() => {
107
+ }) : z(e, t.color) : "";
108
+ }), d = n(() => {
45
109
  if (c.value) {
46
110
  let e = c.value.source === "component" ? c.value.component : void 0;
47
- return typeof e == "function" || typeof e == "object" && e ? x(e) : void 0;
111
+ return typeof e == "function" || typeof e == "object" && e ? E(e) : void 0;
48
112
  }
49
- return typeof t.icon == "function" || typeof t.icon == "object" ? x(t.icon) : void 0;
50
- }), d = n(() => {
113
+ return typeof t.icon == "function" || typeof t.icon == "object" ? E(t.icon) : void 0;
114
+ }), f = n(() => {
51
115
  if (c.value?.source === "iconify") return c.value.icon;
52
- }), p = n(() => ({
116
+ }), { state: p, reset: m } = G(l, () => t.morph === !0 && !t.gradient && !d.value && !f.value);
117
+ _(() => {
118
+ if (p.value) return m(), !1;
119
+ });
120
+ let g = n(() => ({
53
121
  "--lumal-icon-size": typeof t.size == "number" ? `${t.size}px` : t.size ?? "1em",
54
122
  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", {
123
+ })), v = n(() => !!(u.value || d.value || f.value)), y = n(() => t.title ?? c.value?.label);
124
+ return (t, n) => v.value ? (b(), a("span", {
57
125
  key: 0,
58
126
  class: "lumal-icon",
59
- style: f(p.value),
60
- title: g.value,
127
+ style: h(g.value),
128
+ title: y.value,
61
129
  "aria-hidden": "true"
62
- }, [u.value ? (h(), r(v(u.value), {
130
+ }, [d.value ? (b(), r(C(d.value), {
63
131
  key: 0,
64
132
  class: "lumal-icon__component"
65
- })) : d.value ? (h(), r(S(j), {
133
+ })) : f.value ? (b(), r(O(F), {
66
134
  key: 1,
67
135
  class: "lumal-icon__component",
68
- icon: d.value
69
- }, null, 8, ["icon"])) : (h(), a("span", {
136
+ icon: f.value
137
+ }, null, 8, ["icon"])) : O(p) ? (b(), r(C(O(p).component), {
70
138
  key: 2,
139
+ class: "lumal-icon__component",
140
+ icon: O(p).icon,
141
+ spring: e.morphSpring ?? "smooth",
142
+ color: O(p).color,
143
+ "stroke-width": O(p).strokeWidth,
144
+ "stroke-linecap": O(p).linecap,
145
+ "stroke-linejoin": O(p).linejoin,
146
+ "reduced-motion": "user",
147
+ size: "100%"
148
+ }, null, 8, [
149
+ "icon",
150
+ "spring",
151
+ "color",
152
+ "stroke-width",
153
+ "stroke-linecap",
154
+ "stroke-linejoin"
155
+ ])) : (b(), a("span", {
156
+ key: 3,
71
157
  class: "lumal-icon__svg",
72
- innerHTML: l.value
73
- }, null, 8, R))], 12, L)) : i("", !0);
158
+ innerHTML: u.value
159
+ }, null, 8, J))], 12, q)) : i("", !0);
74
160
  }
75
- }), B = (e, t) => {
161
+ }), X = (e, t) => {
76
162
  let n = e.__vccOpts || e;
77
163
  for (let [e, r] of t) n[e] = r;
78
164
  return n;
79
- }, V = /*#__PURE__*/ B(z, [["__scopeId", "data-v-f5cc1719"]]), H = { class: "lumal-icon-picker" }, U = { class: "lumal-icon-picker__toolbar" }, W = {
165
+ }, Z = /*#__PURE__*/ X(Y, [["__scopeId", "data-v-42fa0af8"]]), re = { class: "lumal-icon-picker__toolbar" }, ie = {
80
166
  key: 0,
81
167
  class: "lumal-icon-picker__field"
82
- }, G = {
168
+ }, ae = {
83
169
  key: 1,
84
170
  class: "lumal-icon-picker__field"
85
- }, K = ["value"], q = {
171
+ }, oe = ["value"], se = {
86
172
  class: "lumal-icon-picker__summary",
87
173
  role: "status"
88
- }, J = {
174
+ }, ce = {
89
175
  key: 0,
90
176
  class: "lumal-icon-picker__grid",
91
177
  role: "listbox",
92
178
  "aria-label": "图标列表"
93
- }, Y = [
179
+ }, le = [
94
180
  "aria-label",
95
181
  "aria-selected",
96
182
  "title",
97
183
  "onClick"
98
- ], X = { key: 0 }, Z = {
184
+ ], ue = {
185
+ key: 0,
186
+ class: "lumal-icon-picker__item-label"
187
+ }, de = {
99
188
  key: 1,
100
189
  class: "lumal-icon-picker__empty"
101
- }, ne = {
190
+ }, fe = {
102
191
  key: 2,
103
192
  class: "lumal-icon-picker__pagination"
104
- }, re = ["disabled"], ie = ["disabled"], Q = /*#__PURE__*/ B(/* @__PURE__ */ c({
193
+ }, pe = ["disabled"], me = ["disabled"], Q = /*#__PURE__*/ X(/* @__PURE__ */ l({
105
194
  __name: "LumalIconPicker",
106
- props: /*@__PURE__*/ l({
195
+ props: /*@__PURE__*/ d({
107
196
  group: { default: "" },
108
197
  pageSize: { default: 48 },
109
198
  searchable: {
@@ -119,76 +208,90 @@ var L = ["title"], R = ["innerHTML"], z = /*@__PURE__*/ c({
119
208
  modelValue: {},
120
209
  modelModifiers: {}
121
210
  }),
122
- emits: /*@__PURE__*/ l(["select"], ["update:modelValue"]),
211
+ emits: /*@__PURE__*/ d(["select"], ["update:modelValue"]),
123
212
  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) => ({
213
+ let s = t, l = r, u = A(t, "modelValue"), d = w(""), f = w(s.group), m = w(1), h = n(() => Math.max(1, s.pageSize)), g = K(), _ = g.icons, v = n(() => {
214
+ let e = g.groups.value, t = new Set(e.map((e) => e.key)), n = _.value.map((e) => e.group).filter((e) => typeof e == "string" && !t.has(e)).filter((e, t, n) => n.indexOf(e) === t).map((e) => ({
126
215
  key: e,
127
216
  label: e
128
217
  }));
129
218
  return [...e, ...n];
130
- }), C = n(() => {
131
- let e = f.value.trim().toLocaleLowerCase();
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);
219
+ }), y = n(() => {
220
+ let e = d.value.trim().toLocaleLowerCase();
221
+ return _.value.filter((t) => {
222
+ let n = !f.value || t.group === f.value, r = !e || t.key.toLocaleLowerCase().includes(e) || t.label?.toLocaleLowerCase().includes(e);
134
223
  return n && r;
135
224
  });
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);
225
+ }), C = n(() => Math.max(1, Math.ceil(y.value.length / h.value))), E = n(() => {
226
+ let e = (m.value - 1) * h.value;
227
+ return y.value.slice(e, e + h.value);
139
228
  });
140
- O([
229
+ function D(e) {
230
+ f.value = e;
231
+ }
232
+ N([
233
+ d,
141
234
  f,
142
- p,
143
- v
235
+ h
144
236
  ], () => {
145
237
  m.value = 1;
146
- }), O(() => c.group, (e) => {
147
- p.value = e;
148
- }), O(T, (e) => {
238
+ }), N(() => s.group, (e) => {
239
+ f.value = e;
240
+ }), N(C, (e) => {
149
241
  m.value = Math.min(m.value, e);
150
- }), c.storageKey && typeof localStorage < "u" && !u.value && (u.value = localStorage.getItem(c.storageKey) ?? void 0);
151
- function j(e) {
152
- u.value = e.key, c.storageKey && typeof localStorage < "u" && localStorage.setItem(c.storageKey, e.key), l("select", e);
242
+ }), s.storageKey && typeof localStorage < "u" && !u.value && (u.value = localStorage.getItem(s.storageKey) ?? void 0);
243
+ function O(e) {
244
+ u.value = e.key, s.storageKey && typeof localStorage < "u" && localStorage.setItem(s.storageKey, e.key), l("select", e);
153
245
  }
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,
246
+ return (n, r) => (b(), a("div", { class: p(["lumal-icon-picker", { "lumal-icon-picker--show-labels": t.showLabels }]) }, [
247
+ o("div", re, [t.searchable ? (b(), a("label", ie, [r[4] ||= o("span", { class: "lumal-icon-picker__field-label" }, "搜索图标", -1), P(o("input", {
248
+ "onUpdate:modelValue": r[0] ||= (e) => d.value = e,
157
249
  type: "search",
250
+ "aria-label": "搜索图标",
158
251
  placeholder: "输入名称或 key"
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", {
252
+ }, null, 512), [[M, d.value]])])) : i("", !0), v.value.length ? (b(), a("div", ae, [r[6] ||= o("span", { class: "lumal-icon-picker__field-label" }, "图标分组", -1), S(n.$slots, "group-select", {
253
+ modelValue: f.value,
254
+ groups: v.value,
255
+ setGroup: D
256
+ }, () => [P(o("select", {
257
+ "onUpdate:modelValue": r[1] ||= (e) => f.value = e,
258
+ "aria-label": "图标分组"
259
+ }, [r[5] ||= o("option", { value: "" }, " 全部分组 ", -1), (b(!0), a(e, null, x(v.value, (e) => (b(), a("option", {
160
260
  key: e.key,
161
261
  value: e.key
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", {
262
+ }, T(e.label), 9, oe))), 128))], 512), [[j, f.value]])], !0)])) : i("", !0)]),
263
+ o("p", se, " 共 " + T(y.value.length) + " 个图标 ", 1),
264
+ E.value.length ? (b(), a("div", ce, [(b(!0), a(e, null, x(E.value, (e) => (b(), a("button", {
165
265
  key: e.key,
166
- class: d(["lumal-icon-picker__item", { "is-selected": u.value === e.key }]),
266
+ class: p(["lumal-icon-picker__item", { "is-selected": u.value === e.key }]),
167
267
  type: "button",
168
268
  role: "option",
169
269
  "aria-label": e.label || e.key,
170
270
  "aria-selected": u.value === e.key,
171
271
  title: e.label || e.key,
172
- onClick: (t) => j(e)
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, [
272
+ onClick: (t) => O(e)
273
+ }, [c(Z, {
274
+ name: e.key,
275
+ size: 28
276
+ }, null, 8, ["name"]), t.showLabels ? (b(), a("span", ue, T(e.label || e.key), 1)) : i("", !0)], 10, le))), 128))])) : (b(), a("p", de, " 未找到匹配图标 ")),
277
+ C.value > 1 ? (b(), a("footer", fe, [
175
278
  o("button", {
176
279
  type: "button",
177
280
  disabled: m.value <= 1,
178
281
  onClick: r[2] ||= (e) => --m.value
179
- }, " 上一页 ", 8, re),
180
- o("span", null, "第 " + b(m.value) + " / " + b(T.value) + " 页", 1),
282
+ }, " 上一页 ", 8, pe),
283
+ o("span", null, "第 " + T(m.value) + " / " + T(C.value) + " 页", 1),
181
284
  o("button", {
182
285
  type: "button",
183
- disabled: m.value >= T.value,
286
+ disabled: m.value >= C.value,
184
287
  onClick: r[3] ||= (e) => m.value += 1
185
- }, " 下一页 ", 8, ie)
288
+ }, " 下一页 ", 8, me)
186
289
  ])) : i("", !0)
187
- ]));
290
+ ], 2));
188
291
  }
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({
292
+ }), [["__scopeId", "data-v-0b9c266c"]]), he = ["aria-label"], ge = { class: "lumal-icon-picker-dialog__header" }, $ = { class: "lumal-icon-picker-dialog__content" }, _e = { class: "lumal-icon-picker-dialog__footer" }, ve = ["disabled"], ye = /*#__PURE__*/ X(/* @__PURE__ */ l({
190
293
  __name: "LumalIconPickerDialog",
191
- props: /*@__PURE__*/ l({
294
+ props: /*@__PURE__*/ d({
192
295
  cancelText: { default: "取消" },
193
296
  confirmText: { default: "确认选择" },
194
297
  title: { default: "选择图标" }
@@ -201,71 +304,79 @@ var L = ["title"], R = ["innerHTML"], z = /*@__PURE__*/ c({
201
304
  modelValue: {},
202
305
  modelModifiers: {}
203
306
  }),
204
- emits: /*@__PURE__*/ l(["cancel", "confirm"], ["update:visible", "update:modelValue"]),
307
+ emits: /*@__PURE__*/ d(["cancel", "confirm"], ["update:visible", "update:modelValue"]),
205
308
  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();
309
+ let l = n, d = A(e, "visible"), p = A(e, "modelValue"), h = w(""), _ = ee("dialogRef"), v;
310
+ function y(e) {
311
+ d.value && _.value && !_.value.contains(e.target) && _.value.focus();
209
312
  }
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());
313
+ function x(e) {
314
+ if (e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), C()), e.key !== "Tab") return;
315
+ let t = [..._.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);
316
+ (!n || (e.shiftKey ? document.activeElement === n || document.activeElement === _.value : document.activeElement === r || document.activeElement === _.value)) && (e.preventDefault(), (e.shiftKey ? r : n)?.focus());
214
317
  }
215
- O(l, async (e) => {
318
+ N(d, async (e) => {
216
319
  if (!(typeof document > "u")) {
217
320
  if (!e) {
218
- document.removeEventListener("focusin", _);
219
- let e = g;
220
- await u(), !l.value && e?.isConnected && e.focus();
321
+ document.removeEventListener("focusin", y);
322
+ let e = v;
323
+ await f(), !d.value && e?.isConnected && e.focus();
221
324
  return;
222
325
  }
223
- g = document.activeElement instanceof HTMLElement ? document.activeElement : void 0, f.value = d.value ?? "", await u(), l.value && (m.value?.focus(), document.addEventListener("focusin", _));
326
+ v = document.activeElement instanceof HTMLElement ? document.activeElement : void 0, h.value = p.value ?? "", await f(), d.value && (_.value?.focus(), document.addEventListener("focusin", y));
224
327
  }
225
- }, { immediate: !0 }), p(() => {
226
- document.removeEventListener("focusin", _), g?.isConnected && g.focus();
328
+ }, { immediate: !0 }), g(() => {
329
+ document.removeEventListener("focusin", y), v?.isConnected && v.focus();
227
330
  });
228
- function x() {
229
- l.value = !1, c("cancel");
331
+ function C() {
332
+ d.value = !1, l("cancel");
230
333
  }
231
- function S() {
232
- f.value && (d.value = f.value, l.value = !1, c("confirm", f.value));
334
+ function E() {
335
+ h.value && (p.value = h.value, d.value = !1, l("confirm", h.value));
233
336
  }
234
- return (n, c) => (h(), r(t, { to: "body" }, [l.value ? (h(), a("div", {
337
+ return (n, l) => (b(), r(t, { to: "body" }, [d.value ? (b(), a("div", {
235
338
  key: 0,
236
339
  class: "lumal-icon-picker-dialog",
237
340
  role: "presentation",
238
- onMousedown: A(x, ["self"])
341
+ onMousedown: ne(C, ["self"])
239
342
  }, [o("section", {
240
343
  ref_key: "dialogRef",
241
- ref: m,
344
+ ref: _,
242
345
  class: "lumal-icon-picker-dialog__body",
243
346
  role: "dialog",
244
347
  "aria-modal": "true",
245
348
  "aria-label": e.title,
246
349
  tabindex: "-1",
247
- onKeydown: v
350
+ onKeydown: x
248
351
  }, [
249
- o("header", oe, [o("h3", null, b(e.title), 1), o("button", {
352
+ o("header", ge, [o("h3", null, T(e.title), 1), o("button", {
250
353
  type: "button",
251
354
  "aria-label": "关闭图标选择器",
252
- onClick: x
253
- }, " × ")]),
254
- o("div", $, [s(Q, {
255
- modelValue: f.value,
256
- "onUpdate:modelValue": c[0] ||= (e) => f.value = e
257
- }, null, 8, ["modelValue"])]),
258
- o("footer", se, [o("button", {
355
+ title: "关闭图标选择器",
356
+ onClick: C
357
+ }, [c(Z, {
358
+ name: "lumal:close",
359
+ size: 18
360
+ })])]),
361
+ o("div", $, [c(Q, {
362
+ modelValue: h.value,
363
+ "onUpdate:modelValue": l[0] ||= (e) => h.value = e
364
+ }, s({ _: 2 }, [n.$slots["group-select"] ? {
365
+ name: "group-select",
366
+ fn: te((e) => [S(n.$slots, "group-select", m(u(e)), void 0, !0)]),
367
+ key: "0"
368
+ } : void 0]), 1032, ["modelValue"])]),
369
+ o("footer", _e, [o("button", {
259
370
  type: "button",
260
- onClick: x
261
- }, b(e.cancelText), 1), o("button", {
371
+ onClick: C
372
+ }, T(e.cancelText), 1), o("button", {
262
373
  type: "button",
263
374
  class: "is-primary",
264
- disabled: !f.value,
265
- onClick: S
266
- }, b(e.confirmText), 9, ce)])
267
- ], 40, ae)], 32)) : i("", !0)]));
375
+ disabled: !h.value,
376
+ onClick: E
377
+ }, T(e.confirmText), 9, ve)])
378
+ ], 40, he)], 32)) : i("", !0)]));
268
379
  }
269
- }), [["__scopeId", "data-v-a6a04d17"]]);
380
+ }), [["__scopeId", "data-v-ee548916"]]);
270
381
  //#endregion
271
- export { V as LumalIcon, Q as LumalIconPicker, le as LumalIconPickerDialog, I as useIconRegistry };
382
+ export { Z as LumalIcon, Q as LumalIconPicker, ye as LumalIconPickerDialog, K as useIconRegistry };
@@ -1,5 +1,6 @@
1
1
  import type { IconDefinition, IconGradientOptions } from '@lumal/icons';
2
2
  import type { Component } from 'vue';
3
+ import type { LumalIconMorphSpring } from '../types';
3
4
  /***********************属性定义*********************/
4
5
  type __VLS_Props = {
5
6
  name?: string;
@@ -8,6 +9,8 @@ type __VLS_Props = {
8
9
  color?: string;
9
10
  gradient?: IconGradientOptions;
10
11
  title?: string;
12
+ morph?: boolean;
13
+ morphSpring?: LumalIconMorphSpring;
11
14
  };
12
15
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
16
  declare const _default: typeof __VLS_export;
@@ -1 +1 @@
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
+ {"version":3,"file":"LumalIcon.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIcon.vue"],"names":[],"mappings":"AAgKA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AACpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAOpD,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;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,oBAAoB,CAAA;CACnC,CAAC;AA6LF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1,4 +1,6 @@
1
1
  import type { IconDefinition } from '@lumal/icons';
2
+ import type { LumalIconPickerGroupSelectSlotProps } from '../types';
3
+ /***********************属性与事件*********************/
2
4
  type __VLS_Props = {
3
5
  group?: string;
4
6
  pageSize?: number;
@@ -6,11 +8,15 @@ type __VLS_Props = {
6
8
  showLabels?: boolean;
7
9
  storageKey?: string;
8
10
  };
11
+ type __VLS_Slots = {
12
+ 'group-select'?: (props: LumalIconPickerGroupSelectSlotProps) => unknown;
13
+ };
9
14
  type __VLS_ModelProps = {
15
+ /***********************筛选与分页*********************/
10
16
  modelValue?: string;
11
17
  };
12
18
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
13
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
14
20
  select: (icon: IconDefinition<unknown>) => any;
15
21
  "update:modelValue": (value: string | undefined) => any;
16
22
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
@@ -23,6 +29,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
23
29
  showLabels: boolean;
24
30
  storageKey: string;
25
31
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
26
33
  declare const _default: typeof __VLS_export;
27
34
  export default _default;
35
+ type __VLS_WithSlots<T, S> = T & {
36
+ new (): {
37
+ $slots: S;
38
+ };
39
+ };
28
40
  //# sourceMappingURL=LumalIconPicker.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LumalIconPicker.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIconPicker.vue"],"names":[],"mappings":"AA4PA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAKlD,KAAK,WAAW,GAAG;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAC;AA2EF,KAAK,gBAAgB,GAAG;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAYF,KAAK,iBAAiB,GAAG,WAAW,GAAG,gBAAgB,CAAC;AA6LxD,QAAA,MAAM,YAAY;;;;;;;WA3RR,MAAM;cACH,MAAM;gBACJ,OAAO;gBACP,OAAO;gBACP,MAAM;6EA2RnB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"LumalIconPicker.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIconPicker.vue"],"names":[],"mappings":"AAmSA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,UAAU,CAAA;AAKnE,mDAAmD;AACnD,KAAK,WAAW,GAAG;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAC;AAcF,KAAK,WAAW,GAAG;IACjB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,mCAAmC,KAAK,OAAO,CAAA;CACzE,CAAC;AAsEF,KAAK,gBAAgB,GAAG;IACxB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAYF,KAAK,iBAAiB,GAAG,WAAW,GAAG,gBAAgB,CAAC;AA+MxD,QAAA,MAAM,UAAU;;;;;;;WAzTN,MAAM;cACH,MAAM;gBACJ,OAAO;gBACP,OAAO;gBACP,MAAM;6EAyTnB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1,15 +1,19 @@
1
+ import type { LumalIconPickerGroupSelectSlotProps } from '../types';
1
2
  /***********************属性与事件*********************/
2
3
  type __VLS_Props = {
3
4
  cancelText?: string;
4
5
  confirmText?: string;
5
6
  title?: string;
6
7
  };
8
+ type __VLS_Slots = {
9
+ 'group-select'?: (props: LumalIconPickerGroupSelectSlotProps) => unknown;
10
+ };
7
11
  type __VLS_ModelProps = {
8
12
  'visible'?: boolean;
9
13
  modelValue?: string;
10
14
  };
11
15
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
12
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
16
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
17
  "update:modelValue": (value: string | undefined) => any;
14
18
  cancel: () => any;
15
19
  confirm: (icon: string) => any;
@@ -24,6 +28,12 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
24
28
  cancelText: string;
25
29
  confirmText: string;
26
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
27
32
  declare const _default: typeof __VLS_export;
28
33
  export default _default;
34
+ type __VLS_WithSlots<T, S> = T & {
35
+ new (): {
36
+ $slots: S;
37
+ };
38
+ };
29
39
  //# sourceMappingURL=LumalIconPickerDialog.vue.d.ts.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"LumalIconPickerDialog.vue.d.ts","sourceRoot":"","sources":["../../../src/components/LumalIconPickerDialog.vue"],"names":[],"mappings":"AAyPA,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,UAAU,CAAA;AAKnE,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;AAaF,KAAK,WAAW,GAAG;IACjB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,mCAAmC,KAAK,OAAO,CAAA;CACzE,CAAC;AAgFF,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;AAoJxD,QAAA,MAAM,UAAU;;;;;;;;;;;WAlQN,MAAM;gBAFD,MAAM;iBACL,MAAM;6EAuQpB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { PreparedIconMorph } from '@lumal/icons/morph';
2
+ import type { MaybeRefOrGetter } from 'vue';
3
+ import type { MorphRuntime } from '../runtime/morph';
4
+ export declare function useIconMorph(svgText: MaybeRefOrGetter<string>, enabled: MaybeRefOrGetter<boolean>): {
5
+ state: import("vue").ShallowRef<(PreparedIconMorph & {
6
+ component: MorphRuntime["MorphIcon"];
7
+ }) | undefined, (PreparedIconMorph & {
8
+ component: MorphRuntime["MorphIcon"];
9
+ }) | undefined>;
10
+ reset: () => void;
11
+ };
12
+ //# sourceMappingURL=useIconMorph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIconMorph.d.ts","sourceRoot":"","sources":["../../../src/composables/useIconMorph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAKpD,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC;;mBAIrC,YAAY,CAAC,WAAW,CAAC;;mBAAzB,YAAY,CAAC,WAAW,CAAC;;;EA6ErF"}
@@ -4,4 +4,5 @@ import LumalIconPickerDialog from './components/LumalIconPickerDialog.vue';
4
4
  export { LumalIcon, LumalIconPicker, LumalIconPickerDialog, };
5
5
  export { useIconRegistry } from './composables/useIconRegistry';
6
6
  export type { UseIconRegistryReturn } from './composables/useIconRegistry';
7
+ export type { LumalIconMorphSpring, LumalIconPickerGroupSelectSlotProps } from './types';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,4BAA4B,CAAA;AAClD,OAAO,eAAe,MAAM,kCAAkC,CAAA;AAC9D,OAAO,qBAAqB,MAAM,wCAAwC,CAAA;AAE1E,OAAO,EACL,SAAS,EACT,eAAe,EACf,qBAAqB,GACtB,CAAA;AACD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,4BAA4B,CAAA;AAClD,OAAO,eAAe,MAAM,kCAAkC,CAAA;AAC9D,OAAO,qBAAqB,MAAM,wCAAwC,CAAA;AAE1E,OAAO,EACL,SAAS,EACT,eAAe,EACf,qBAAqB,GACtB,CAAA;AACD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAC1E,YAAY,EAAE,oBAAoB,EAAE,mCAAmC,EAAE,MAAM,SAAS,CAAA"}
@@ -0,0 +1,6 @@
1
+ export interface MorphRuntime {
2
+ MorphIcon: typeof import('morphicons/vue')['MorphIcon'];
3
+ }
4
+ /** 通用转换由 @lumal/icons/morph 负责,此处只按需加载官方 Vue 绑定。 */
5
+ export declare function loadMorphRuntime(): Promise<MorphRuntime>;
6
+ //# sourceMappingURL=morph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"morph.d.ts","sourceRoot":"","sources":["../../../src/runtime/morph.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,cAAc,gBAAgB,CAAC,CAAC,WAAW,CAAC,CAAA;CACxD;AAID,oDAAoD;AACpD,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC,CAMxD"}
@@ -0,0 +1,9 @@
1
+ import type { IconGroupDefinition } from '@lumal/icons';
2
+ export type { LumalIconMorphSpring } from '@lumal/icons/morph';
3
+ /***********************选择器插槽类型*********************/
4
+ export interface LumalIconPickerGroupSelectSlotProps {
5
+ modelValue: string;
6
+ groups: IconGroupDefinition[];
7
+ setGroup: (group: string) => void;
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAEvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAE9D,qDAAqD;AACrD,MAAM,WAAW,mCAAmC;IAClD,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,mBAAmB,EAAE,CAAA;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lumal/icons-vue",
3
3
  "type": "module",
4
- "version": "0.0.3-beta",
4
+ "version": "0.0.5-beta",
5
5
  "description": "Vue components and reactive adapters for @lumal/icons.",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -38,7 +38,8 @@
38
38
  "vue": "^3.5.0"
39
39
  },
40
40
  "dependencies": {
41
- "@lumal/icons": "0.0.3-beta"
41
+ "@lumal/icons": "0.0.5-beta",
42
+ "morphicons": "2.0.0"
42
43
  },
43
44
  "scripts": {
44
45
  "build": "vite build --config vite.config.ts && vue-tsc -p tsconfig.json --emitDeclarationOnly --outDir dist && node ../../scripts/clean-package-dist.mjs dist",