@greypan/web-ui 8.0.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/README.CN.md +277 -146
  2. package/README.md +323 -191
  3. package/dist/assets/glass.js +1 -1
  4. package/dist/assets/glass.js.map +1 -1
  5. package/dist/assets/menu-portal.js +1 -1
  6. package/dist/assets/menu-portal.js.map +1 -1
  7. package/dist/assets/selection-control.js +1 -1
  8. package/dist/assets/selection-control.js.map +1 -1
  9. package/dist/assets/toast-containers.js +1 -1
  10. package/dist/assets/toast-containers.js.map +1 -1
  11. package/dist/components/autocomplete/index.d.ts +3 -2
  12. package/dist/components/autocomplete/index.js +46 -50
  13. package/dist/components/autocomplete/index.js.map +1 -1
  14. package/dist/components/autocomplete/style.js +1 -1
  15. package/dist/components/autocomplete/style.js.map +1 -1
  16. package/dist/components/avatar/index.js.map +1 -1
  17. package/dist/components/avatar/style.js +1 -1
  18. package/dist/components/avatar/style.js.map +1 -1
  19. package/dist/components/back-top/style.js +1 -1
  20. package/dist/components/back-top/style.js.map +1 -1
  21. package/dist/components/badge/style.js +1 -1
  22. package/dist/components/badge/style.js.map +1 -1
  23. package/dist/components/button/index.d.ts +368 -1
  24. package/dist/components/button/index.js +56 -36
  25. package/dist/components/button/index.js.map +1 -1
  26. package/dist/components/button/style.js +1 -1
  27. package/dist/components/button/style.js.map +1 -1
  28. package/dist/components/button-group/index.js +0 -1
  29. package/dist/components/button-group/index.js.map +1 -1
  30. package/dist/components/button-group/style.js +1 -1
  31. package/dist/components/button-group/style.js.map +1 -1
  32. package/dist/components/checkbox/index.d.ts +3 -0
  33. package/dist/components/checkbox/index.js +35 -37
  34. package/dist/components/checkbox/index.js.map +1 -1
  35. package/dist/components/checkbox/style.js +1 -1
  36. package/dist/components/checkbox/style.js.map +1 -1
  37. package/dist/components/checkbox-group/index.js +8 -8
  38. package/dist/components/checkbox-group/style.js +1 -1
  39. package/dist/components/checkbox-group/style.js.map +1 -1
  40. package/dist/components/context-menu/index.d.ts +167 -3
  41. package/dist/components/context-menu/index.js +162 -91
  42. package/dist/components/context-menu/index.js.map +1 -1
  43. package/dist/components/context-menu/scrim.js +6 -0
  44. package/dist/components/context-menu/scrim.js.map +1 -0
  45. package/dist/components/context-menu/style.js +1 -1
  46. package/dist/components/context-menu/style.js.map +1 -1
  47. package/dist/components/dialog/index.d.ts +9 -0
  48. package/dist/components/dialog/index.js +61 -46
  49. package/dist/components/dialog/index.js.map +1 -1
  50. package/dist/components/dialog/style.js +1 -1
  51. package/dist/components/dialog/style.js.map +1 -1
  52. package/dist/components/drawer/index.d.ts +45 -0
  53. package/dist/components/drawer/index.js +116 -52
  54. package/dist/components/drawer/index.js.map +1 -1
  55. package/dist/components/drawer/style.js +1 -1
  56. package/dist/components/drawer/style.js.map +1 -1
  57. package/dist/components/dropdown/index.d.ts +12 -0
  58. package/dist/components/dropdown/index.js +13 -10
  59. package/dist/components/dropdown/index.js.map +1 -1
  60. package/dist/components/dropdown-divider/style.js +1 -1
  61. package/dist/components/dropdown-divider/style.js.map +1 -1
  62. package/dist/components/dropdown-header/style.js +1 -1
  63. package/dist/components/dropdown-header/style.js.map +1 -1
  64. package/dist/components/dropdown-item/style.js +1 -1
  65. package/dist/components/dropdown-item/style.js.map +1 -1
  66. package/dist/components/editable-text/index.d.ts +41 -0
  67. package/dist/components/editable-text/index.js +55 -31
  68. package/dist/components/editable-text/index.js.map +1 -1
  69. package/dist/components/empty/index.d.ts +21 -4
  70. package/dist/components/empty/index.js +37 -32
  71. package/dist/components/empty/index.js.map +1 -1
  72. package/dist/components/empty/style.js +1 -1
  73. package/dist/components/empty/style.js.map +1 -1
  74. package/dist/components/icon/index.js +7 -7
  75. package/dist/components/icon/index.js.map +1 -1
  76. package/dist/components/image-preview/index.js +9 -2
  77. package/dist/components/image-preview/index.js.map +1 -1
  78. package/dist/components/image-preview/style.js +1 -1
  79. package/dist/components/image-preview/style.js.map +1 -1
  80. package/dist/components/index.js +23 -23
  81. package/dist/components/input/index.d.ts +7 -0
  82. package/dist/components/input/index.js +34 -29
  83. package/dist/components/input/index.js.map +1 -1
  84. package/dist/components/input/style.js +1 -1
  85. package/dist/components/input/style.js.map +1 -1
  86. package/dist/components/input-number/index.d.ts +1 -0
  87. package/dist/components/input-number/index.js +28 -26
  88. package/dist/components/input-number/index.js.map +1 -1
  89. package/dist/components/input-number/style.js +1 -1
  90. package/dist/components/input-number/style.js.map +1 -1
  91. package/dist/components/layout/index.d.ts +0 -3
  92. package/dist/components/layout/index.js +1 -1
  93. package/dist/components/layout/index.js.map +1 -1
  94. package/dist/components/layout/style.js +1 -1
  95. package/dist/components/layout/style.js.map +1 -1
  96. package/dist/components/option/style.js +1 -1
  97. package/dist/components/option/style.js.map +1 -1
  98. package/dist/components/popover/index.js.map +1 -1
  99. package/dist/components/popover/style.js +1 -1
  100. package/dist/components/popover/style.js.map +1 -1
  101. package/dist/components/radio/index.d.ts +3 -0
  102. package/dist/components/radio/index.js +23 -19
  103. package/dist/components/radio/index.js.map +1 -1
  104. package/dist/components/radio/style.js +1 -1
  105. package/dist/components/radio/style.js.map +1 -1
  106. package/dist/components/radio-group/index.js +8 -8
  107. package/dist/components/radio-group/style.js +1 -1
  108. package/dist/components/radio-group/style.js.map +1 -1
  109. package/dist/components/segmented/index.d.ts +5 -0
  110. package/dist/components/segmented/index.js +49 -32
  111. package/dist/components/segmented/index.js.map +1 -1
  112. package/dist/components/segmented/style.js +1 -1
  113. package/dist/components/segmented/style.js.map +1 -1
  114. package/dist/components/segmented-trigger/style.js +1 -1
  115. package/dist/components/segmented-trigger/style.js.map +1 -1
  116. package/dist/components/select/index.js +0 -1
  117. package/dist/components/select/index.js.map +1 -1
  118. package/dist/components/select/style.js +1 -1
  119. package/dist/components/select/style.js.map +1 -1
  120. package/dist/components/slider/index.js +9 -9
  121. package/dist/components/slider/style.js +1 -1
  122. package/dist/components/slider/style.js.map +1 -1
  123. package/dist/components/spinner/style.js +1 -1
  124. package/dist/components/spinner/style.js.map +1 -1
  125. package/dist/components/svg-draw-lines/index.js.map +1 -1
  126. package/dist/components/switch/index.d.ts +1 -0
  127. package/dist/components/switch/index.js +26 -24
  128. package/dist/components/switch/index.js.map +1 -1
  129. package/dist/components/switch/style.js +1 -1
  130. package/dist/components/switch/style.js.map +1 -1
  131. package/dist/components/textarea/index.d.ts +7 -1
  132. package/dist/components/textarea/index.js +45 -43
  133. package/dist/components/textarea/index.js.map +1 -1
  134. package/dist/components/textarea/style.js +1 -1
  135. package/dist/components/textarea/style.js.map +1 -1
  136. package/dist/components/theme/index.d.ts +9 -0
  137. package/dist/components/theme/index.js +128 -85
  138. package/dist/components/theme/index.js.map +1 -1
  139. package/dist/components/theme/style.js +1 -1
  140. package/dist/components/theme/style.js.map +1 -1
  141. package/dist/components/toast/style.js +1 -1
  142. package/dist/components/toast/style.js.map +1 -1
  143. package/dist/components/toast/toast.js +8 -8
  144. package/dist/components/toast/toast.js.map +1 -1
  145. package/dist/components/tooltip/index.js.map +1 -1
  146. package/dist/components/tooltip/style.js +1 -1
  147. package/dist/components/tooltip/style.js.map +1 -1
  148. package/dist/icons/generated/akar-icons-check.d.ts +6 -0
  149. package/dist/icons/generated/akar-icons-check.js +10 -0
  150. package/dist/icons/generated/akar-icons-check.js.map +1 -0
  151. package/dist/icons/generated/akar-icons-circle-check.d.ts +6 -0
  152. package/dist/icons/generated/akar-icons-circle-check.js +10 -0
  153. package/dist/icons/generated/akar-icons-circle-check.js.map +1 -0
  154. package/dist/icons/generated/bi-check-lg.d.ts +6 -0
  155. package/dist/icons/generated/bi-check-lg.js +10 -0
  156. package/dist/icons/generated/bi-check-lg.js.map +1 -0
  157. package/dist/icons/generated/bi-check.d.ts +6 -0
  158. package/dist/icons/generated/bi-check.js +10 -0
  159. package/dist/icons/generated/bi-check.js.map +1 -0
  160. package/dist/icons/generated/fluent-tag-search-24-regular.d.ts +6 -0
  161. package/dist/icons/generated/fluent-tag-search-24-regular.js +10 -0
  162. package/dist/icons/generated/fluent-tag-search-24-regular.js.map +1 -0
  163. package/dist/icons/generated/mdi-tag-search-outline.d.ts +6 -0
  164. package/dist/icons/generated/mdi-tag-search-outline.js +10 -0
  165. package/dist/icons/generated/mdi-tag-search-outline.js.map +1 -0
  166. package/dist/icons/index.d.ts +6 -0
  167. package/dist/icons/index.js +7 -1
  168. package/dist/shared/element-height/index.js +47 -0
  169. package/dist/shared/element-height/index.js.map +1 -0
  170. package/dist/shared/form-association/field-id.js +9 -0
  171. package/dist/shared/form-association/field-id.js.map +1 -0
  172. package/dist/shared/form-association/index.js +9 -1
  173. package/dist/shared/form-association/index.js.map +1 -1
  174. package/dist/shared/label-emptiness/index.js +45 -0
  175. package/dist/shared/label-emptiness/index.js.map +1 -0
  176. package/dist/shared/menu-portal/menu-portal.js +11 -11
  177. package/dist/shared/menu-portal/menu-portal.js.map +1 -1
  178. package/dist/shared/menu-portal/menu-tree.js +2 -2
  179. package/dist/shared/menu-portal/menu-tree.js.map +1 -1
  180. package/dist/shared/overlay/anchored-panel.js.map +1 -1
  181. package/dist/shared/overlay/native-dialog-presence.js +23 -11
  182. package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
  183. package/dist/shared/overlay/nested-drawer-layers.js +30 -23
  184. package/dist/shared/overlay/nested-drawer-layers.js.map +1 -1
  185. package/dist/shared/scroll-lock/scroll-lock.js +3 -3
  186. package/dist/shared/scroll-lock/scroll-lock.js.map +1 -1
  187. package/dist/shared/theme/root-sync.js +24 -18
  188. package/dist/shared/theme/root-sync.js.map +1 -1
  189. package/package.json +8 -4
@@ -1,5 +1,5 @@
1
1
  //#region src/assets/glass.css?inline
2
- var e = ".wui-glass{--wui-internal-glass-shadow:var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004);background-color:var(--wui-color-surface-glass,#fafafa57);-webkit-backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06));box-shadow:inset 0 0 0 .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 38%, transparent), inset 0 1px .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 52%, transparent), inset 0 -.5px 1px #00000008, var(--wui-internal-glass-shadow,var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004));background-clip:padding-box;border:none;position:relative}.wui-glass:before{pointer-events:none;content:\"\";border-radius:inherit;background-color:var(--wui-color-glass-border,transparent);background-image:radial-gradient(var(--wui-glass-corner-radius,32px) at 100% 0, var(--wui-color-glass-shade,#00000008), transparent), radial-gradient(var(--wui-glass-corner-radius,32px) at 0 100%, var(--wui-color-glass-shade,#00000008), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 0 0, var(--wui-color-glass-corner,#ffffff80), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 100% 100%, var(--wui-color-glass-corner,#ffffff80), transparent);-webkit-mask-composite:xor;-webkit-mask-source-type:auto,auto;padding:1px;position:absolute;inset:0;-webkit-mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;-webkit-mask-size:auto,auto;mask-size:auto,auto;-webkit-mask-repeat:repeat,repeat;mask-repeat:repeat,repeat;-webkit-mask-clip:content-box,border-box;mask-clip:content-box,border-box;-webkit-mask-origin:content-box,border-box;mask-origin:content-box,border-box;-webkit-mask-composite:xor;mask-composite:exclude;-webkit-mask-source-type:auto,auto;mask-mode:match-source,match-source}";
2
+ var e = ".wui-glass{--wui-internal-glass-shadow:var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004);background-color:var(--wui-color-surface-glass,#fafafa57);-webkit-backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06));box-shadow:inset 0 0 0 .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 38%, transparent), inset 0 1px .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 52%, transparent), inset 0 -.5px 1px #00000008, var(--wui-internal-glass-shadow,var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004));background-clip:padding-box;border:none;position:relative}.wui-glass:before{pointer-events:none;content:\"\";border-radius:inherit;background-color:var(--wui-color-glass-ring,#0000000d);background-image:radial-gradient(var(--wui-glass-corner-radius,32px) at 100% 0, var(--wui-color-glass-ring-shade,#00000008), transparent), radial-gradient(var(--wui-glass-corner-radius,32px) at 0 100%, var(--wui-color-glass-ring-shade,#00000008), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 0 0, var(--wui-color-glass-ring-sheen,#ffffff80), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 100% 100%, var(--wui-color-glass-ring-sheen,#ffffff80), transparent);-webkit-mask-composite:xor;-webkit-mask-source-type:auto,auto;padding:1px;position:absolute;inset:0;-webkit-mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;-webkit-mask-size:auto,auto;mask-size:auto,auto;-webkit-mask-repeat:repeat,repeat;mask-repeat:repeat,repeat;-webkit-mask-clip:content-box,border-box;mask-clip:content-box,border-box;-webkit-mask-origin:content-box,border-box;mask-origin:content-box,border-box;-webkit-mask-composite:xor;mask-composite:exclude;-webkit-mask-source-type:auto,auto;mask-mode:match-source,match-source}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"glass.js","names":[],"sources":["../../src/assets/glass.css?inline"],"sourcesContent":[".wui-glass {\n /*\n * 内部阴影变量在 glass 元素上自声明默认值,切断从祖先 glass 容器(drawer/dialog\n * body 等声明了 overlay 阴影的元素)沿 flattened tree 继承进 slotted 内容的\n * 通道;各组件在自身元素上的同变量配置(特异性/源顺序恒胜出)不受影响。\n */\n --wui-internal-glass-shadow: var(\n --wui-shadow-glass,\n 0 0 1px rgb(0 0 0 / 0.02),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n );\n\n position: relative;\n\n border: none;\n\n background-color: var(--wui-color-surface-glass, rgb(250 250 250 / 0.34));\n background-clip: padding-box;\n\n /* Safari 16.4 只支持带 -webkit- 前缀的 backdrop-filter(无前缀 18 才支持);\n 前缀由 lightningcss 按 ?inline 管线默认 targets(含 ios16.4)自动生成,无需手写。 */\n backdrop-filter: blur(4px) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n box-shadow:\n inset 0 0 0 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 38%, transparent),\n inset 0 1px 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 52%, transparent),\n inset 0 -0.5px 1px rgb(0 0 0 / 0.03),\n var(\n --wui-internal-glass-shadow,\n var(\n --wui-shadow-glass,\n 0 0 1px rgb(0 0 0 / 0.02),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n )\n );\n}\n\n/*\n * 玻璃描边:底环 + 对角受光/背光。background-color 用 border 色铺满整圈(含圆角\n * 弧段,修复胶囊弧段无着色发暗的问题);叠两枚 corner→transparent radial 作左上/\n * 右下受光光泽,再叠两枚 shade→transparent radial(置于最上层)压暗右上/左下背光\n * 角,形成对角光影的玻璃立体感。四枚渐变均为锚定角点、半径 --wui-glass-corner-radius\n * 的固定物理尺寸正圆——视觉覆盖范围不随元素宽高缩放(百分比方案在大面板上暗边\n * 过长、小控件上过弱),各组件用与自身 border-radius 同源的值覆盖该变量即可联动。\n * 颜色由 theme 按明暗主题提供 --wui-color-glass-corner / --wui-color-glass-shade /\n * --wui-color-glass-border;-webkit-mask-* 旧语法(含 mask-composite:xor)由\n * lightningcss 按 targets 自动生成,无前缀 mask-composite 留给 Chrome 120+。\n */\n.wui-glass::before {\n pointer-events: none;\n content: '';\n\n position: absolute;\n inset: 0;\n\n padding: 1px;\n border-radius: inherit;\n\n background-color: var(--wui-color-glass-border, transparent);\n background-image:\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 100% 0,\n var(--wui-color-glass-shade, rgb(0 0 0 / 0.03)),\n transparent\n ),\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 0 100%,\n var(--wui-color-glass-shade, rgb(0 0 0 / 0.03)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 0 0,\n var(--wui-color-glass-corner, rgb(255 255 255 / 0.5)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 100% 100%,\n var(--wui-color-glass-corner, rgb(255 255 255 / 0.5)),\n transparent\n );\n\n mask:\n linear-gradient(#000 0 0) content-box,\n linear-gradient(#000 0 0);\n mask-composite: exclude;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"glass.js","names":[],"sources":["../../src/assets/glass.css?inline"],"sourcesContent":[".wui-glass {\n /*\n * 内部阴影变量在 glass 元素上自声明默认值,切断从祖先 glass 容器(drawer/dialog\n * body 等声明了 overlay 阴影的元素)沿 flattened tree 继承进 slotted 内容的\n * 通道;各组件在自身元素上的同变量配置(特异性/源顺序恒胜出)不受影响。\n */\n --wui-internal-glass-shadow: var(\n --wui-shadow-glass,\n 0 0 1px rgb(0 0 0 / 0.02),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n );\n\n position: relative;\n\n border: none;\n\n background-color: var(--wui-color-surface-glass, rgb(250 250 250 / 0.34));\n background-clip: padding-box;\n\n /* Safari 16.4 只支持带 -webkit- 前缀的 backdrop-filter(无前缀 18 才支持);\n 前缀由 lightningcss 按 ?inline 管线默认 targets(含 ios16.4)自动生成,无需手写。 */\n backdrop-filter: blur(4px) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n box-shadow:\n inset 0 0 0 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 38%, transparent),\n inset 0 1px 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 52%, transparent),\n inset 0 -0.5px 1px rgb(0 0 0 / 0.03),\n var(\n --wui-internal-glass-shadow,\n var(\n --wui-shadow-glass,\n 0 0 1px rgb(0 0 0 / 0.02),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n )\n );\n}\n\n/*\n * 玻璃描边环:底色铺满整圈,其上叠两枚 sheen→transparent radial 作左上/右下受光\n * 光泽,再叠两枚 shade→transparent radial(置于最上层)压暗右上/左下背光角,形成\n * 对角光影的玻璃立体感。\n *\n * 底色(--wui-color-glass-ring)不是可选项:四枚 radial 全部锚定角点、半径固定\n * (R = --wui-glass-corner-radius,sheen 用 2R、shade 用 R),一条边只有长过约 3R\n * 才有一段落在所有 radial 之外。底色是唯一覆盖那一段的一层,也是圆角弧段(如 pill\n * 的半圆端)不发暗的原因。三枚 token 同属 ring 前缀,因为它们共同描述这一枚环,\n * 而非三个独立效果。\n *\n * 底色字面量取明色值 rgb(0 0 0 / 0.05) 而非 transparent:本文件其余玻璃 token 的\n * fallback 一律等于明色真值(surface-glass / brightness / highlight / sheen / shade),\n * token 缺省时(未挂 <web-ui-theme>,或 theme 未设 appearance —— 颜色 token 只定义在\n * [appearance] 三个选择器下)整套玻璃面就是明色观感,这一层没有理由例外。\n *\n * 渐变半径为 --wui-glass-corner-radius 的固定物理尺寸正圆——视觉覆盖范围不随元素\n * 宽高缩放(百分比方案在大面板上暗边过长、小控件上过弱),各组件用与自身\n * border-radius 同源的值覆盖该变量即可联动。\n *\n * 同源的 --wui-color-glass-highlight 不在此层:它是元素自身 box-shadow 的 inset\n * 高光,与本环无关。-webkit-mask-* 旧语法(含 mask-composite:xor)由 lightningcss\n * 按 targets 自动生成,无前缀 mask-composite 留给 Chrome 120+。\n */\n.wui-glass::before {\n pointer-events: none;\n content: '';\n\n position: absolute;\n inset: 0;\n\n padding: 1px;\n border-radius: inherit;\n\n background-color: var(--wui-color-glass-ring, rgb(0 0 0 / 0.05));\n background-image:\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 100% 0,\n var(--wui-color-glass-ring-shade, rgb(0 0 0 / 0.03)),\n transparent\n ),\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 0 100%,\n var(--wui-color-glass-ring-shade, rgb(0 0 0 / 0.03)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 0 0,\n var(--wui-color-glass-ring-sheen, rgb(255 255 255 / 0.5)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 100% 100%,\n var(--wui-color-glass-ring-sheen, rgb(255 255 255 / 0.5)),\n transparent\n );\n\n mask:\n linear-gradient(#000 0 0) content-box,\n linear-gradient(#000 0 0);\n mask-composite: exclude;\n}\n"],"mappings":""}
@@ -1,5 +1,5 @@
1
1
  //#region src/assets/menu-portal.css?inline
2
- var e = ".wui-menu-portal-overlay.wui-floating-panel{--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-internal-duration-float-enter:var(--wui-duration-float-enter,.24s);--wui-internal-duration-float-exit:var(--wui-duration-float-exit,.16s);--wui-glass-corner-radius:var(--wui-radius-menu,18px);-webkit-user-select:none;user-select:none;z-index:var(--wui-layer-menu,100);box-sizing:border-box;min-width:var(--wui-overlay-min-width,200px);border-radius:var(--wui-radius-menu,18px);max-width:90vw;max-height:80vh;color:var(--wui-color-text,#1b1b1b);background-color:var(--wui-color-surface-menu,#f6f6f6d1);position:fixed;overflow:hidden}.wui-menu-portal-overlay.wui-floating-panel .wui-menu-scroll{max-height:80vh;overflow-y:auto}.wui-menu-portal-overlay.wui-floating-panel .wui-menu-content{padding:4px}.wui-menu-portal-overlay.wui-floating-panel.dropdown-overlay .wui-menu-scroll{max-height:320px}.wui-menu-portal-overlay.wui-floating-panel.dropdown-overlay[data-level]:not([data-level=\"0\"]),.wui-menu-portal-overlay.wui-floating-panel.context-submenu{z-index:var(--wui-layer-menu-nested,110)}";
2
+ var e = ".wui-menu-portal-overlay.wui-floating-panel{--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-internal-duration-float-enter:var(--wui-duration-float-enter,.24s);--wui-internal-duration-float-exit:var(--wui-duration-float-exit,.16s);--wui-glass-corner-radius:var(--wui-radius-menu,18px);--wui-color-glass-ring:transparent;-webkit-user-select:none;user-select:none;z-index:var(--wui-layer-menu,100);box-sizing:border-box;min-width:var(--wui-overlay-min-width,200px);border-radius:var(--wui-radius-menu,18px);max-width:90vw;max-height:80vh;color:var(--wui-color-text,#1b1b1b);background-color:var(--wui-color-surface-menu,#fafafac2);position:fixed;overflow:hidden}.wui-menu-portal-overlay.wui-floating-panel .wui-menu-scroll{max-height:80vh;overflow-y:auto}.wui-menu-portal-overlay.wui-floating-panel .wui-menu-content{padding:var(--wui-space-1,4px)}.wui-menu-portal-overlay.wui-floating-panel.dropdown-overlay .wui-menu-scroll{max-height:320px}.wui-menu-portal-overlay.wui-floating-panel.dropdown-overlay[data-level]:not([data-level=\"0\"]),.wui-menu-portal-overlay.wui-floating-panel.context-submenu{z-index:var(--wui-layer-menu-nested,110)}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"menu-portal.js","names":[],"sources":["../../src/assets/menu-portal.css?inline"],"sourcesContent":["/* 菜单面板:wui-glass 玻璃(背景/描边/阴影)由面板自身承担,随面板 opacity 与\n backdrop-filter 插值一起过渡(单层玻璃,见 overlay-motion.css)。\n 选择器用 .wui-menu-portal-overlay.wui-floating-panel(0,2,0)压制 .wui-glass\n (0,1,0):面板无自有 shadow root,直接挂在宿主 shadow(overlay root 的 \\3c style>\n 或 dialog 的 adopted stylesheets)里,若只用单类选择器,dialog 场景下宿主 adopted\n stylesheets 的 .wui-glass 会在层叠中晚于面板内联 \\3c style> 而胜出(position:relative\n 顶掉 fixed、背景/阴影变量回弱默认)。 */\n.wui-menu-portal-overlay.wui-floating-panel {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-internal-duration-float-enter: var(--wui-duration-float-enter, 240ms);\n --wui-internal-duration-float-exit: var(--wui-duration-float-exit, 160ms);\n --wui-glass-corner-radius: var(--wui-radius-menu, 18px);\n user-select: none;\n\n position: fixed;\n z-index: var(--wui-layer-menu, 100);\n\n overflow: hidden;\n\n box-sizing: border-box;\n min-width: var(--wui-overlay-min-width, 200px);\n max-width: 90vw;\n max-height: 80vh;\n border-radius: var(--wui-radius-menu, 18px);\n\n color: var(--wui-color-text, #1b1b1b);\n\n /* 玻璃背景:面板自身 overflow:hidden 不裁自身的 box-shadow(box-shadow 不受\n 元素自身 overflow 影响)。 */\n background-color: var(--wui-color-surface-menu, rgb(246 246 246 / 0.82));\n\n & .wui-menu-scroll {\n overflow-y: auto;\n max-height: 80vh;\n }\n\n & .wui-menu-content {\n padding: 4px;\n }\n\n &.dropdown-overlay {\n & .wui-menu-scroll {\n max-height: 320px;\n }\n\n &[data-level]:not([data-level='0']) {\n z-index: var(--wui-layer-menu-nested, 110);\n }\n }\n\n &.context-submenu {\n z-index: var(--wui-layer-menu-nested, 110);\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"menu-portal.js","names":[],"sources":["../../src/assets/menu-portal.css?inline"],"sourcesContent":["/* 菜单面板:wui-glass 玻璃(背景/描边/阴影)由面板自身承担,随面板 opacity 与\n backdrop-filter 插值一起过渡(单层玻璃,见 overlay-motion.css)。\n 选择器用 .wui-menu-portal-overlay.wui-floating-panel(0,2,0)压制 .wui-glass\n (0,1,0):面板无自有 shadow root,直接挂在宿主 shadow(overlay root 的 \\3c style>\n 或 dialog 的 adopted stylesheets)里,若只用单类选择器,dialog 场景下宿主 adopted\n stylesheets 的 .wui-glass 会在层叠中晚于面板内联 \\3c style> 而胜出(position:relative\n 顶掉 fixed、背景/阴影变量回弱默认)。 */\n.wui-menu-portal-overlay.wui-floating-panel {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-internal-duration-float-enter: var(--wui-duration-float-enter, 240ms);\n --wui-internal-duration-float-exit: var(--wui-duration-float-exit, 160ms);\n --wui-glass-corner-radius: var(--wui-radius-menu, 18px);\n\n /* 菜单族面板把环底色转 transparent。底色是环里唯一覆盖长边中段的一层(见 glass.css\n 的说明),而菜单面板宽远大于角半径 18px——按几何它只负责很短的一段,读出来却像\n 一条比四角更重的直边描边,边界感比四角强。转 transparent 后环只剩四段角弧,\n 斜向受光/背光光影(sheen + shade 的两枚对角 radial)完整保留,边界改由这两层\n 承担。handle 类玻璃面(switch/slider/segmented thumb)只在按压/拖拽态做同样处理:\n 它们的短边半径就是 thumb 尺寸的一半,长边长不过 3R,底色几乎不覆盖任何中段,\n 去掉它只去掉一层均匀灰 tint,不改变环的可见形状。 */\n --wui-color-glass-ring: transparent;\n user-select: none;\n\n position: fixed;\n z-index: var(--wui-layer-menu, 100);\n\n overflow: hidden;\n\n box-sizing: border-box;\n min-width: var(--wui-overlay-min-width, 200px);\n max-width: 90vw;\n max-height: 80vh;\n border-radius: var(--wui-radius-menu, 18px);\n\n color: var(--wui-color-text, #1b1b1b);\n\n /* 玻璃背景:面板自身 overflow:hidden 不裁自身的 box-shadow(box-shadow 不受\n 元素自身 overflow 影响)。 */\n background-color: var(--wui-color-surface-menu, rgb(250 250 250 / 0.76));\n\n & .wui-menu-scroll {\n overflow-y: auto;\n max-height: 80vh;\n }\n\n & .wui-menu-content {\n padding: var(--wui-space-1, 4px);\n }\n\n &.dropdown-overlay {\n & .wui-menu-scroll {\n max-height: 320px;\n }\n\n &[data-level]:not([data-level='0']) {\n z-index: var(--wui-layer-menu-nested, 110);\n }\n }\n\n &.context-submenu {\n z-index: var(--wui-layer-menu-nested, 110);\n }\n}\n"],"mappings":""}
@@ -1,5 +1,5 @@
1
1
  //#region src/assets/selection-control.css?inline
2
- var e = "*,:before,:after{box-sizing:border-box}:host{cursor:default;vertical-align:middle;align-items:center;display:inline-flex}:host([disabled]){cursor:not-allowed}:where(.wui-radio,.wui-checkbox){cursor:inherit;-webkit-user-select:none;user-select:none;font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);align-items:center;gap:10px;line-height:1;display:inline-flex}:where(.wui-radio,.wui-checkbox):focus-visible{border-radius:var(--wui-radius-control,calc(infinity * 1px));outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,#08f6);outline-offset:2px}:host([data-wui-pointer-focus]) :where(.wui-radio,.wui-checkbox):focus-visible{outline-color:#0000}:where(.wui-radio.is-disabled,.wui-checkbox.is-disabled){cursor:not-allowed;color:var(--wui-color-text-secondary,#6a6a6a);opacity:.4}:where(.wui-radio-circle,.wui-checkbox-box){isolation:isolate;width:var(--wui-selection-control-size,18px);height:var(--wui-selection-control-size,18px);background-color:var(--wui-color-surface-control,#dfdfdf);transition:background-color var(--wui-duration-trigger,.16s) ease;flex-shrink:0;justify-content:center;align-items:center;display:flex;position:relative}:where(.wui-radio-circle,.wui-checkbox-box):before{content:\"\";z-index:-1;border-radius:inherit;position:absolute;inset:0}:where(.wui-radio-label,.wui-checkbox-label){pointer-events:none}@media (hover:hover) and (pointer:fine){:where(.wui-radio,.wui-checkbox):hover:not(.is-disabled,.is-checked) :where(.wui-radio-circle,.wui-checkbox-box):before{background-color:color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent)}}";
2
+ var e = "*,:before,:after{box-sizing:border-box}:host{cursor:default;vertical-align:middle;align-items:center;display:inline-flex}:host([disabled]){cursor:not-allowed}:where(.wui-radio,.wui-checkbox){cursor:inherit;-webkit-user-select:none;user-select:none;font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);align-items:center;gap:10px;line-height:1;display:inline-flex}:where(.wui-radio,.wui-checkbox):focus-visible{border-radius:var(--wui-radius-control,calc(infinity * 1px));outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#08f) 40%, transparent));outline-offset:2px}:where(.wui-radio.is-label-empty,.wui-checkbox.is-label-empty){gap:0}:host([data-wui-pointer-focus]) :where(.wui-radio,.wui-checkbox):focus-visible{outline-color:#0000}:where(.wui-radio.is-disabled,.wui-checkbox.is-disabled){cursor:not-allowed;color:var(--wui-color-text-secondary,#6a6a6a);opacity:.4}:where(.wui-radio-circle,.wui-checkbox-box){isolation:isolate;width:var(--wui-selection-control-size,18px);height:var(--wui-selection-control-size,18px);background-color:var(--wui-color-surface-control,#dfdfdf);transition:background-color var(--wui-duration-trigger,.16s) ease;flex-shrink:0;justify-content:center;align-items:center;display:flex;position:relative}:where(.wui-radio-circle,.wui-checkbox-box):before{content:\"\";z-index:-1;border-radius:inherit;position:absolute;inset:0}:where(.wui-radio-label,.wui-checkbox-label){pointer-events:none}@media (hover:hover) and (pointer:fine){:where(.wui-radio,.wui-checkbox):hover:not(.is-disabled,.is-checked) :where(.wui-radio-circle,.wui-checkbox-box):before{background-color:color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent)}}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"selection-control.js","names":[],"sources":["../../src/assets/selection-control.css?inline"],"sourcesContent":["/*\n * radio / checkbox 共享外壳。\n *\n * 指示器只有 18px。宿主一旦走 inline-block,页面行高会在宿主内生成匿名行盒,把盒子撑到\n * 行高(Tailwind preflight 下是 24px),且多出的空隙落在哪一侧取决于内部基线落点,radio 与\n * checkbox 因此一个贴顶一个贴底。改成 inline-flex 后宿主高度由内容决定,行高不再参与,\n * 与相邻文字的对齐交给 vertical-align 显式声明。\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: default;\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n/* :where() 保持零特异性,组件级配置(圆角、选中色、内部图形)始终覆盖共享层。 */\n:where(.wui-radio, .wui-checkbox) {\n cursor: inherit;\n user-select: none;\n\n display: inline-flex;\n gap: 10px;\n align-items: center;\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text, #1b1b1b);\n\n &:focus-visible {\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n outline: var(--wui-focus-ring-width, 3px) solid var(--wui-color-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n}\n\n:host([data-wui-pointer-focus]) :where(.wui-radio, .wui-checkbox):focus-visible {\n outline-color: transparent;\n}\n\n:where(.wui-radio.is-disabled, .wui-checkbox.is-disabled) {\n cursor: not-allowed;\n color: var(--wui-color-text-secondary, #6a6a6a);\n opacity: 0.4;\n}\n\n/*\n * 指示器底色取控件档。surface-raised 在深色下(#2c2c2e)离页面底色(#242628)只有 8 个\n * 亮度点,未选中时几乎看不出有一个圆/方框;surface-control 才是主题里「控件自己的底」\n * 那一档(中性按钮同档),深色比页面高 22 个亮度点,浅色下也从近白的 #f2f2f7 变成可读的 #dfdfdf。\n */\n:where(.wui-radio-circle, .wui-checkbox-box) {\n isolation: isolate;\n position: relative;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: var(--wui-selection-control-size, 18px);\n height: var(--wui-selection-control-size, 18px);\n\n background-color: var(--wui-color-surface-control, #dfdfdf);\n\n transition: background-color var(--wui-duration-trigger, 160ms) ease;\n}\n\n/*\n * 状态层走覆盖层,不占用指示器自己的 background-color:同一个属性没法一半过渡一半即时,\n * 而这里要的是 hover 当帧切换、选中态的 accent 按 --wui-duration-trigger 淡入淡出。\n * z-index: -1 配父级 isolation 把覆盖层夹在控件底与圆点/勾之间,半径跟着指示器走。\n */\n:where(.wui-radio-circle, .wui-checkbox-box)::before {\n content: '';\n\n position: absolute;\n z-index: -1;\n inset: 0;\n\n border-radius: inherit;\n}\n\n:where(.wui-radio-label, .wui-checkbox-label) {\n pointer-events: none;\n}\n\n/*\n * 未激活态的 hover 状态层。用半透明色而不是混进控件底:覆盖层本就压在不透明的控件底上,\n * 合成结果与 color-mix(text 6%, surface-control) 一致,深色档同样成立。\n * 标签文字带 pointer-events: none,命中落回 label 自身,所以整条触发区(含右侧文字)\n * 的 hover 都会作用到指示器。hover 只在真正的指针设备上生效,避免触屏留态。\n */\n@media (hover: hover) and (pointer: fine) {\n :where(.wui-radio, .wui-checkbox):hover:not(.is-disabled, .is-checked)\n :where(.wui-radio-circle, .wui-checkbox-box)::before {\n background-color: color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent);\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"selection-control.js","names":[],"sources":["../../src/assets/selection-control.css?inline"],"sourcesContent":["/*\n * radio / checkbox 共享外壳。\n *\n * 指示器只有 18px。宿主一旦走 inline-block,页面行高会在宿主内生成匿名行盒,把盒子撑到\n * 行高(Tailwind preflight 下是 24px),且多出的空隙落在哪一侧取决于内部基线落点,radio 与\n * checkbox 因此一个贴顶一个贴底。改成 inline-flex 后宿主高度由内容决定,行高不再参与,\n * 与相邻文字的对齐交给 vertical-align 显式声明。\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: default;\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n/* :where() 保持零特异性,组件级配置(圆角、选中色、内部图形)始终覆盖共享层。 */\n:where(.wui-radio, .wui-checkbox) {\n cursor: inherit;\n user-select: none;\n\n display: inline-flex;\n gap: 10px;\n align-items: center;\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text, #1b1b1b);\n\n &:focus-visible {\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #08f) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n/*\n * 标签没有可渲染内容时把间距一并收掉。gap 只认「这里有个 flex item」,不认它有没有宽度,所以空槽位\n * 或只挂了一个视觉隐藏的无障碍名时,指示器右边照样多出这一段;判据见 LabelEmptinessController。\n */\n:where(.wui-radio.is-label-empty, .wui-checkbox.is-label-empty) {\n gap: 0;\n}\n\n:host([data-wui-pointer-focus]) :where(.wui-radio, .wui-checkbox):focus-visible {\n outline-color: transparent;\n}\n\n:where(.wui-radio.is-disabled, .wui-checkbox.is-disabled) {\n cursor: not-allowed;\n color: var(--wui-color-text-secondary, #6a6a6a);\n opacity: 0.4;\n}\n\n/*\n * 指示器底色取控件档。surface-raised 在深色下(#2c2c2e)离页面底色(#242628)只有 8 个\n * 亮度点,未选中时几乎看不出有一个圆/方框;surface-control 才是主题里「控件自己的底」\n * 那一档(中性按钮同档),深色比页面高 22 个亮度点,浅色下也从近白的 #f2f2f7 变成可读的 #dfdfdf。\n */\n:where(.wui-radio-circle, .wui-checkbox-box) {\n isolation: isolate;\n position: relative;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: var(--wui-selection-control-size, 18px);\n height: var(--wui-selection-control-size, 18px);\n\n background-color: var(--wui-color-surface-control, #dfdfdf);\n\n transition: background-color var(--wui-duration-trigger, 160ms) ease;\n}\n\n/*\n * 状态层走覆盖层,不占用指示器自己的 background-color:同一个属性没法一半过渡一半即时,\n * 而这里要的是 hover 当帧切换、选中态的 accent 按 --wui-duration-trigger 淡入淡出。\n * z-index: -1 配父级 isolation 把覆盖层夹在控件底与圆点/勾之间,半径跟着指示器走。\n */\n:where(.wui-radio-circle, .wui-checkbox-box)::before {\n content: '';\n\n position: absolute;\n z-index: -1;\n inset: 0;\n\n border-radius: inherit;\n}\n\n:where(.wui-radio-label, .wui-checkbox-label) {\n pointer-events: none;\n}\n\n/*\n * 未激活态的 hover 状态层。用半透明色而不是混进控件底:覆盖层本就压在不透明的控件底上,\n * 合成结果与 color-mix(text 6%, surface-control) 一致,深色档同样成立。\n * 标签文字带 pointer-events: none,命中落回 label 自身,所以整条触发区(含右侧文字)\n * 的 hover 都会作用到指示器。hover 只在真正的指针设备上生效,避免触屏留态。\n */\n@media (hover: hover) and (pointer: fine) {\n :where(.wui-radio, .wui-checkbox):hover:not(.is-disabled, .is-checked)\n :where(.wui-radio-circle, .wui-checkbox-box)::before {\n background-color: color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent);\n }\n}\n"],"mappings":""}
@@ -1,5 +1,5 @@
1
1
  //#region src/assets/toast-containers.css?inline
2
- var e = ".wui-toast-container{--wui-toast-viewport-gap:16px;--wui-toast-container-padding:40px;pointer-events:none;z-index:var(--wui-layer-toast,200);overscroll-behavior:contain;max-height:calc(100vh + 2 * (var(--wui-toast-container-padding) - var(--wui-toast-viewport-gap)));padding:var(--wui-toast-container-padding);flex-direction:column;gap:8px;display:flex;position:fixed;overflow-y:auto}.wui-toast-container>*{pointer-events:auto}.wui-toast-top-left{top:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));left:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));align-items:flex-start}.wui-toast-top-center{top:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));align-items:center;left:50%;transform:translate(-50%)}.wui-toast-top-right{top:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));right:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));align-items:flex-end}.wui-toast-bottom-left{bottom:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));left:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));flex-direction:column-reverse;align-items:flex-start}.wui-toast-bottom-center{bottom:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));flex-direction:column-reverse;align-items:center;left:50%;transform:translate(-50%)}.wui-toast-bottom-right{right:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));bottom:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));flex-direction:column-reverse;align-items:flex-end}";
2
+ var e = ".wui-toast-container{--wui-toast-viewport-gap:16px;--wui-toast-container-padding:40px;pointer-events:none;z-index:var(--wui-layer-toast,200);overscroll-behavior:contain;gap:var(--wui-space-2,8px);max-height:calc(100vh + 2 * (var(--wui-toast-container-padding) - var(--wui-toast-viewport-gap)));padding:var(--wui-toast-container-padding);flex-direction:column;display:flex;position:fixed;overflow-y:auto}.wui-toast-container>*{pointer-events:auto}.wui-toast-top-left{top:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));left:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));align-items:flex-start}.wui-toast-top-center{top:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));align-items:center;left:50%;transform:translate(-50%)}.wui-toast-top-right{top:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));right:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));align-items:flex-end}.wui-toast-bottom-left{bottom:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));left:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));flex-direction:column-reverse;align-items:flex-start}.wui-toast-bottom-center{bottom:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));flex-direction:column-reverse;align-items:center;left:50%;transform:translate(-50%)}.wui-toast-bottom-right{right:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));bottom:calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));flex-direction:column-reverse;align-items:flex-end}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"toast-containers.js","names":[],"sources":["../../src/assets/toast-containers.css?inline"],"sourcesContent":["/* Toast 容器定位 — 由 toast 命令式 API 动态注入到 body */\n\n.wui-toast-container {\n --wui-toast-viewport-gap: 16px;\n --wui-toast-container-padding: 40px;\n pointer-events: none;\n\n position: fixed;\n z-index: var(--wui-layer-toast, 200);\n\n overflow-y: auto;\n overscroll-behavior: contain;\n display: flex;\n flex-direction: column;\n gap: 8px;\n\n /* 负向定位只露出可见 gap;剩余 padding 继续作为阴影裁剪缓冲区 */\n max-height: calc(100vh + 2 * (var(--wui-toast-container-padding) - var(--wui-toast-viewport-gap)));\n\n /* padding 需要 >= 阴影偏移 + 模糊半径,否则 overflow 会裁剪子元素 box-shadow */\n padding: var(--wui-toast-container-padding);\n}\n\n.wui-toast-container > * {\n pointer-events: auto;\n}\n\n.wui-toast-top-left {\n top: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n align-items: flex-start;\n}\n\n.wui-toast-top-center {\n top: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n}\n\n.wui-toast-top-right {\n top: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n right: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n align-items: flex-end;\n}\n\n.wui-toast-bottom-left {\n bottom: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n flex-direction: column-reverse;\n align-items: flex-start;\n}\n\n.wui-toast-bottom-center {\n bottom: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: 50%;\n transform: translateX(-50%);\n\n flex-direction: column-reverse;\n align-items: center;\n}\n\n.wui-toast-bottom-right {\n right: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n bottom: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n flex-direction: column-reverse;\n align-items: flex-end;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"toast-containers.js","names":[],"sources":["../../src/assets/toast-containers.css?inline"],"sourcesContent":["/* Toast 容器定位 — 由 toast 命令式 API 动态注入到 body */\n\n.wui-toast-container {\n --wui-toast-viewport-gap: 16px;\n --wui-toast-container-padding: 40px;\n pointer-events: none;\n\n position: fixed;\n z-index: var(--wui-layer-toast, 200);\n\n overflow-y: auto;\n overscroll-behavior: contain;\n display: flex;\n flex-direction: column;\n gap: var(--wui-space-2, 8px);\n\n /* 负向定位只露出可见 gap;剩余 padding 继续作为阴影裁剪缓冲区 */\n max-height: calc(100vh + 2 * (var(--wui-toast-container-padding) - var(--wui-toast-viewport-gap)));\n\n /* padding 需要 >= 阴影偏移 + 模糊半径,否则 overflow 会裁剪子元素 box-shadow */\n padding: var(--wui-toast-container-padding);\n}\n\n.wui-toast-container > * {\n pointer-events: auto;\n}\n\n.wui-toast-top-left {\n top: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n align-items: flex-start;\n}\n\n.wui-toast-top-center {\n top: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n}\n\n.wui-toast-top-right {\n top: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n right: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n align-items: flex-end;\n}\n\n.wui-toast-bottom-left {\n bottom: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n flex-direction: column-reverse;\n align-items: flex-start;\n}\n\n.wui-toast-bottom-center {\n bottom: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n left: 50%;\n transform: translateX(-50%);\n\n flex-direction: column-reverse;\n align-items: center;\n}\n\n.wui-toast-bottom-right {\n right: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n bottom: calc(var(--wui-toast-viewport-gap) - var(--wui-toast-container-padding));\n flex-direction: column-reverse;\n align-items: flex-end;\n}\n"],"mappings":""}
@@ -445,7 +445,8 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
445
445
  private _syncOptionA11y;
446
446
  private _getA11yOptionId;
447
447
  private _applyFilter;
448
- private _syncEmptyState;
448
+ private _hasMatchingOptions;
449
+ private _syncOpenWithMatches;
449
450
  private readonly _optionListeners;
450
451
  private _bindOption;
451
452
  private _unbindOption;
@@ -462,6 +463,7 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
462
463
  private _selectOption;
463
464
  private _findExactOption;
464
465
  private _hasExactOption;
466
+ private _canSubmitCustomValue;
465
467
  private _selectCustomValue;
466
468
  private _onTriggerInput;
467
469
  private _onTriggerClick;
@@ -478,7 +480,6 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
478
480
  private _syncScrollLock;
479
481
  private _createPortal;
480
482
  private _getLabelledbyText;
481
- private _getEmptySlotText;
482
483
  render(): import('lit').TemplateResult<1>;
483
484
  readonly $events: {
484
485
  input: Event;
@@ -1,9 +1,8 @@
1
1
  import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
2
2
  import t from "../../assets/glass.js";
3
- import { normalizeLiteral as n } from "../../shared/normalize/index.js";
4
- import { FormAssociated as r, FormAssociationController as i, defineFormAssociation as a } from "../../shared/form-association/index.js";
3
+ import { FormAssociated as n, FormAssociationController as r, defineFormAssociation as i } from "../../shared/form-association/index.js";
4
+ import { normalizeLiteral as a } from "../../shared/normalize/index.js";
5
5
  import "../input/index.js";
6
- import "../option/index.js";
7
6
  import o from "../../assets/overlay-motion.js";
8
7
  import { dispatchOpenChangeEvent as s } from "../../shared/open-state/index.js";
9
8
  import { createComboboxOpenController as c, createOptionListenerBinding as l, defineComboboxTrigger as u, handleComboboxFocusOut as d, nextWrappingIndex as f } from "../../shared/option-portal/combobox-shell.js";
@@ -23,17 +22,17 @@ var O, k = [
23
22
  "contains"
24
23
  ];
25
24
  function A(e) {
26
- return e instanceof Element && e.getAttribute("slot") === "empty";
25
+ return e instanceof Element && e.slot === "trigger";
27
26
  }
28
27
  function j(e) {
29
- return e instanceof Element && e.slot === "trigger";
28
+ return e instanceof Element && e.slot === "empty";
30
29
  }
31
- var M = class extends r(b) {
30
+ var M = class extends n(b) {
32
31
  static {
33
32
  O = this;
34
33
  }
35
34
  constructor(...e) {
36
- super(...e), this.placeholder = "", this.borderless = !1, this.disabled = !1, this.readonly = !1, this.required = !1, this.portal = !1, this.noScrollLock = !1, this.allowCustomValue = !1, this.name = "", this.ariaLabel = null, this._filter = "contains", this._value = "", this._selectedValue = "", this._formAssociation = a({
35
+ super(...e), this.placeholder = "", this.borderless = !1, this.disabled = !1, this.readonly = !1, this.required = !1, this.portal = !1, this.noScrollLock = !1, this.allowCustomValue = !1, this.name = "", this.ariaLabel = null, this._filter = "contains", this._value = "", this._selectedValue = "", this._formAssociation = i({
37
36
  host: this,
38
37
  initialize: () => {
39
38
  let e = this.getAttribute("value");
@@ -49,7 +48,7 @@ var M = class extends r(b) {
49
48
  typeof e == "string" && (this.value = e);
50
49
  },
51
50
  syncValidity: () => this._syncValidity()
52
- }).make(), this._formAssociationController = new i(this, this._formAssociation), this._isOpen = !1, this._activeIndex = -1, this._focused = !1, this._hasTriggerSlot = !1, this._idPrefix = `web-ui-autocomplete-${++O._nextInstanceId}`, this._a11yOptionIds = /* @__PURE__ */ new WeakMap(), this._nextA11yOptionId = 0, this._options = [], this._scrollLock = v().make(), this._optionPortal = p().make({
51
+ }).make(), this._formAssociationController = new r(this, this._formAssociation), this._isOpen = !1, this._activeIndex = -1, this._focused = !1, this._hasTriggerSlot = !1, this._idPrefix = `web-ui-autocomplete-${++O._nextInstanceId}`, this._a11yOptionIds = /* @__PURE__ */ new WeakMap(), this._nextA11yOptionId = 0, this._options = [], this._scrollLock = v().make(), this._optionPortal = p().make({
53
52
  element: this,
54
53
  idPrefix: `${this._idPrefix}-option`,
55
54
  getPortal: () => this._portal,
@@ -112,31 +111,36 @@ var M = class extends r(b) {
112
111
  }, this._onSlotChange = () => {
113
112
  this._optionPortal.scheduleRefresh();
114
113
  }, this._onKeydown = (e) => {
115
- if (!(this._isDisabled || this.readonly)) switch (e.key) {
114
+ if (!(this._isDisabled || this.readonly)) switch (this._applyFilter(), this._syncOpenWithMatches(), e.key) {
116
115
  case "ArrowDown":
117
116
  case "ArrowUp":
118
117
  if (this._isOpen && this._trigger.isMultilineEdit(e)) break;
119
118
  e.preventDefault(), this._isOpen ? this._navigateActive(e.key === "ArrowDown" ? 1 : -1) : this._open(!0);
120
119
  break;
121
- case "Enter": if (this._isOpen && !this._trigger.isMultilineEdit(e)) {
122
- e.preventDefault();
123
- let t = this._options[this._activeIndex];
124
- if (t && !t.disabled && !t.hasAttribute("data-filtered")) {
125
- this._selectOption(t);
126
- return;
120
+ case "Enter": {
121
+ let t = this._canSubmitCustomValue();
122
+ if (!this._trigger.isMultilineEdit(e) && (this._isOpen || !this._hasMatchingOptions() && t)) {
123
+ if (e.preventDefault(), this._isOpen) {
124
+ let e = this._options[this._activeIndex];
125
+ if (e && !e.disabled && !e.hasAttribute("data-filtered")) {
126
+ this._selectOption(e);
127
+ return;
128
+ }
129
+ let t = this._findExactOption(this._value);
130
+ if (t) {
131
+ this._selectOption(t);
132
+ return;
133
+ }
134
+ }
135
+ t && this._selectCustomValue();
127
136
  }
128
- let n = this._findExactOption(this._value);
129
- if (n) {
130
- this._selectOption(n);
131
- return;
132
- }
133
- this.allowCustomValue && this._value && !this._hasExactOption(this._value) && this._selectCustomValue();
137
+ break;
134
138
  }
135
139
  }
136
140
  }, this._onTriggerInput = (e) => {
137
- this._isDisabled || this.readonly || e !== this._value && (this.value = e, this._activeIndex = -1, this._syncActiveOption(), this._isOpen || this._open());
141
+ this._isDisabled || this.readonly || e !== this._value && (this.value = e, this._activeIndex = -1, this._syncActiveOption(), this._open());
138
142
  }, this._onTriggerClick = () => {
139
- this._isDisabled || this.readonly || this._options.length > 0 && this._open();
143
+ this._isDisabled || this.readonly || this._open();
140
144
  }, this._onTriggerFocusIn = (e) => {
141
145
  this._isDisabled || (this._focused = !0, this._isSlottedFocus(e) && this.dispatchEvent(new FocusEvent("focus", {
142
146
  composed: !0,
@@ -181,7 +185,7 @@ var M = class extends r(b) {
181
185
  }
182
186
  set filter(e) {
183
187
  let t = this._filter;
184
- this._filter = n(e, k, "contains"), this.requestUpdate("filter", t);
188
+ this._filter = a(e, k, "contains"), this.requestUpdate("filter", t);
185
189
  }
186
190
  get value() {
187
191
  return this._value;
@@ -219,7 +223,7 @@ var M = class extends r(b) {
219
223
  super.connectedCallback(), this._optionPortal.bindHost(), this._trigger.bind(), this.addEventListener("keydown", this._onKeydown), this.addEventListener("focusout", this._onFocusOut), document.addEventListener("click", this._onClickOutside);
220
224
  }
221
225
  _syncTriggerSlot() {
222
- let e = Array.from(this.children).some(j);
226
+ let e = Array.from(this.children).some(A);
223
227
  this._hasTriggerSlot !== e && (this._hasTriggerSlot = e, this.hasUpdated && this._reconfigureOverlay());
224
228
  }
225
229
  attributeChangedCallback(e, t, n) {
@@ -239,7 +243,7 @@ var M = class extends r(b) {
239
243
  this._syncTriggerSlot(), this._refreshOptions(), this._optionPortal.ensureOptionIds(this._options), this._syncSelectedValue(), this._applyFilter(), this._syncOptionA11y(), this._syncActiveOption();
240
244
  }
241
245
  updated(e) {
242
- this._trigger.setValue(this._value), (e.has("portal") || e.has("overlayContainer")) && requestAnimationFrame(() => this._reconfigureOverlay()), e.has("noScrollLock") && this._syncScrollLock(), this.toggleAttribute("focused", this._focused), this._syncOpenAttribute(), this._syncOverlayInert(), this._syncValidity(), this._syncEmptyState();
246
+ this._trigger.setValue(this._value), (e.has("portal") || e.has("overlayContainer")) && requestAnimationFrame(() => this._reconfigureOverlay()), e.has("noScrollLock") && this._syncScrollLock(), this.toggleAttribute("focused", this._focused), this._syncOpenAttribute(), this._syncOverlayInert(), this._syncValidity(), this._syncOpenWithMatches();
243
247
  }
244
248
  formDisabledCallback(e) {
245
249
  this._formAssociation.setDisabled(e), e && this._isOpen && this._close();
@@ -276,11 +280,11 @@ var M = class extends r(b) {
276
280
  let n = this._options[this._activeIndex];
277
281
  this._activeIndex >= 0 && (!n || n.hasAttribute("data-filtered") || n.disabled) && (this._activeIndex = -1, this._syncActiveOption());
278
282
  }
279
- _syncEmptyState() {
280
- let e = this._panel.getPanel()?.querySelector(".autocomplete-empty"), t = this._options.filter((e) => !e.hasAttribute("data-filtered")), n = this._isOpen && this._options.length > 0 && t.length === 0;
281
- e && (e.hidden = !n);
282
- let r = (this.shadowRoot?.querySelector("slot[name=\"empty\"]"))?.assignedElements().map((e) => e.textContent?.trim()).filter(Boolean).join(" ").trim() || e?.dataset.wuiA11yEmpty || "无匹配选项", i = this.shadowRoot?.querySelector(".autocomplete-empty-a11y");
283
- i && (i.textContent = r, i.hidden = !n);
283
+ _hasMatchingOptions() {
284
+ return this._options.some((e) => !e.hasAttribute("data-filtered"));
285
+ }
286
+ _syncOpenWithMatches() {
287
+ this._isOpen && !this._hasMatchingOptions() && this._close();
284
288
  }
285
289
  _refreshOptions() {
286
290
  let e = this._options[this._activeIndex], t = this._optionPortal.refresh(this._options, e);
@@ -316,6 +320,9 @@ var M = class extends r(b) {
316
320
  let t = e.trim().toLowerCase();
317
321
  return this._options.some((e) => e.label.trim().toLowerCase() === t);
318
322
  }
323
+ _canSubmitCustomValue() {
324
+ return this.allowCustomValue && !!this._value && !this._hasExactOption(this._value);
325
+ }
319
326
  _selectCustomValue() {
320
327
  this._close(), this.dispatchEvent(new Event("input", {
321
328
  bubbles: !0,
@@ -330,6 +337,10 @@ var M = class extends r(b) {
330
337
  return t instanceof Node && !!this.shadowRoot && !this.shadowRoot.contains(t);
331
338
  }
332
339
  _open(e = !1) {
340
+ if (this._applyFilter(), !this._hasMatchingOptions()) {
341
+ this._isOpen && this._close();
342
+ return;
343
+ }
333
344
  this._openController.open(e);
334
345
  }
335
346
  _close() {
@@ -339,7 +350,7 @@ var M = class extends r(b) {
339
350
  s(this, this._isOpen);
340
351
  }
341
352
  _openOverlay(e = !1) {
342
- this._panel.open(e), this._syncOverlayInert(), this._syncEmptyState();
353
+ this._panel.open(e), this._syncOverlayInert();
343
354
  }
344
355
  async _closeOverlay() {
345
356
  await this._panel.close(() => this._isOpen) && (this._portal = void 0, this._portalContent = void 0);
@@ -356,14 +367,8 @@ var M = class extends r(b) {
356
367
  target: this,
357
368
  style: `${t}\n${o}\n${y}`,
358
369
  className: "wui-glass autocomplete-overlay portal wui-floating-panel",
359
- onContentChange: (e) => {
370
+ onContentChange: () => {
360
371
  this._optionPortal.scheduleRefresh();
361
- let t = e.flatMap((e) => [...e.removedNodes]).filter(A);
362
- if (t.length) {
363
- this._portal?.removeContent(t);
364
- let e = this._portal?.panel.querySelector(".autocomplete-empty");
365
- e && (e.textContent = "无匹配选项", e.dataset.wuiA11yEmpty = "无匹配选项"), this._syncEmptyState();
366
- }
367
372
  }
368
373
  });
369
374
  this._portal = e, g(e.panel, this, [
@@ -374,10 +379,8 @@ var M = class extends r(b) {
374
379
  let n = document.createElement("div");
375
380
  n.className = "autocomplete-scroll";
376
381
  let r = document.createElement("div");
377
- r.className = "autocomplete-content", this._portalContent = r;
378
- let i = document.createElement("div");
379
- i.className = "autocomplete-empty", i.hidden = !0, i.dataset.wuiA11yEmpty = this._getEmptySlotText(), n.append(r), r.append(i), e.panel.append(n);
380
- for (let t of Array.from(this.childNodes)) t instanceof Comment || j(t) || (A(t) ? e.appendContent([t], i) : e.appendContent([t], r));
382
+ r.className = "autocomplete-content", this._portalContent = r, n.append(r), e.panel.append(n);
383
+ for (let t of Array.from(this.childNodes)) t instanceof Comment || A(t) || j(t) || e.appendContent([t], r);
381
384
  return e;
382
385
  }
383
386
  _getLabelledbyText() {
@@ -388,9 +391,6 @@ var M = class extends r(b) {
388
391
  return e.querySelector(`#${n}`)?.textContent?.trim() ?? "";
389
392
  }).filter(Boolean).join(" ") : "";
390
393
  }
391
- _getEmptySlotText() {
392
- return (this.shadowRoot?.querySelector("slot[name=\"empty\"]"))?.assignedElements().map((e) => e.textContent?.trim()).filter(Boolean).join(" ").trim() || "无匹配选项";
393
- }
394
394
  render() {
395
395
  let e = `${this._idPrefix}-listbox`, t = `${this._idPrefix}-label`, n = this._getLabelledbyText(), r = this._options.filter((e) => !e.hasAttribute("data-filtered")), i = this._isOpen && this._activeIndex >= 0 ? this._options[this._activeIndex] : void 0, a = i ? this._getA11yOptionId(i) : S;
396
396
  return x`
@@ -441,7 +441,6 @@ var M = class extends r(b) {
441
441
  ${e.label}
442
442
  </div>`)}
443
443
  </div>
444
- <div class="autocomplete-a11y-only autocomplete-empty-a11y" role="status" hidden></div>
445
444
  <div
446
445
  class="autocomplete-overlay wui-floating-panel wui-glass"
447
446
  hidden
@@ -451,9 +450,6 @@ var M = class extends r(b) {
451
450
  <div class="autocomplete-scroll">
452
451
  <div class="autocomplete-content">
453
452
  <slot @slotchange=${this._onSlotChange}></slot>
454
- <div class="autocomplete-empty" hidden>
455
- <slot name="empty">无匹配选项</slot>
456
- </div>
457
453
  </div>
458
454
  </div>
459
455
  </div>