@greypan/web-ui 7.0.0 → 8.1.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 (120) hide show
  1. package/README.CN.md +109 -24
  2. package/README.md +149 -63
  3. package/dist/assets/menu-portal.js +1 -1
  4. package/dist/assets/menu-portal.js.map +1 -1
  5. package/dist/assets/selection-control.js +1 -1
  6. package/dist/assets/selection-control.js.map +1 -1
  7. package/dist/components/autocomplete/index.d.ts +17 -5
  8. package/dist/components/autocomplete/index.js +138 -103
  9. package/dist/components/autocomplete/index.js.map +1 -1
  10. package/dist/components/autocomplete/style.js +1 -1
  11. package/dist/components/autocomplete/style.js.map +1 -1
  12. package/dist/components/avatar/index.js +4 -4
  13. package/dist/components/badge/style.js.map +1 -1
  14. package/dist/components/button/index.d.ts +368 -1
  15. package/dist/components/button/index.js +61 -41
  16. package/dist/components/button/index.js.map +1 -1
  17. package/dist/components/button/style.js +1 -1
  18. package/dist/components/button/style.js.map +1 -1
  19. package/dist/components/button-group/index.js +5 -5
  20. package/dist/components/checkbox/index.d.ts +3 -0
  21. package/dist/components/checkbox/index.js +30 -32
  22. package/dist/components/checkbox/index.js.map +1 -1
  23. package/dist/components/checkbox/style.js +1 -1
  24. package/dist/components/checkbox/style.js.map +1 -1
  25. package/dist/components/checkbox-group/index.js +4 -4
  26. package/dist/components/context-menu/index.js +4 -1
  27. package/dist/components/context-menu/index.js.map +1 -1
  28. package/dist/components/dialog/index.js +11 -8
  29. package/dist/components/dialog/index.js.map +1 -1
  30. package/dist/components/drawer/index.js +11 -8
  31. package/dist/components/drawer/index.js.map +1 -1
  32. package/dist/components/dropdown/index.js +4 -1
  33. package/dist/components/dropdown/index.js.map +1 -1
  34. package/dist/components/dropdown-item/style.js +1 -1
  35. package/dist/components/dropdown-item/style.js.map +1 -1
  36. package/dist/components/editable-text/index.d.ts +473 -0
  37. package/dist/components/editable-text/index.js +226 -0
  38. package/dist/components/editable-text/index.js.map +1 -0
  39. package/dist/components/editable-text/style.js +6 -0
  40. package/dist/components/editable-text/style.js.map +1 -0
  41. package/dist/components/icon/index.js +7 -7
  42. package/dist/components/icon/index.js.map +1 -1
  43. package/dist/components/image-preview/index.js +21 -18
  44. package/dist/components/image-preview/index.js.map +1 -1
  45. package/dist/components/index.d.ts +1 -0
  46. package/dist/components/index.js +39 -38
  47. package/dist/components/input/index.d.ts +9 -0
  48. package/dist/components/input/index.js +41 -30
  49. package/dist/components/input/index.js.map +1 -1
  50. package/dist/components/input-number/index.d.ts +1 -0
  51. package/dist/components/input-number/index.js +26 -24
  52. package/dist/components/input-number/index.js.map +1 -1
  53. package/dist/components/layout/index.js +8 -8
  54. package/dist/components/layout/index.js.map +1 -1
  55. package/dist/components/layout/style.js +1 -1
  56. package/dist/components/layout/style.js.map +1 -1
  57. package/dist/components/option/style.js +1 -1
  58. package/dist/components/option/style.js.map +1 -1
  59. package/dist/components/popover/index.js +13 -10
  60. package/dist/components/popover/index.js.map +1 -1
  61. package/dist/components/popover/style.js +1 -1
  62. package/dist/components/popover/style.js.map +1 -1
  63. package/dist/components/radio/index.d.ts +3 -0
  64. package/dist/components/radio/index.js +22 -18
  65. package/dist/components/radio/index.js.map +1 -1
  66. package/dist/components/radio-group/index.js +4 -4
  67. package/dist/components/segmented/index.d.ts +4 -1
  68. package/dist/components/segmented/index.js +42 -29
  69. package/dist/components/segmented/index.js.map +1 -1
  70. package/dist/components/segmented/style.js +1 -1
  71. package/dist/components/segmented/style.js.map +1 -1
  72. package/dist/components/segmented-trigger/style.js +1 -1
  73. package/dist/components/segmented-trigger/style.js.map +1 -1
  74. package/dist/components/select/index.js +35 -32
  75. package/dist/components/select/index.js.map +1 -1
  76. package/dist/components/select/style.js +1 -1
  77. package/dist/components/select/style.js.map +1 -1
  78. package/dist/components/slider/index.js +11 -11
  79. package/dist/components/switch/index.d.ts +1 -0
  80. package/dist/components/switch/index.js +34 -32
  81. package/dist/components/switch/index.js.map +1 -1
  82. package/dist/components/textarea/index.d.ts +7 -1
  83. package/dist/components/textarea/index.js +46 -44
  84. package/dist/components/textarea/index.js.map +1 -1
  85. package/dist/components/textarea/style.js.map +1 -1
  86. package/dist/components/theme/index.d.ts +10 -3
  87. package/dist/components/theme/index.js +133 -93
  88. package/dist/components/theme/index.js.map +1 -1
  89. package/dist/components/theme/style.js +1 -1
  90. package/dist/components/theme/style.js.map +1 -1
  91. package/dist/components/toast/toast.js +7 -7
  92. package/dist/components/toast/toast.js.map +1 -1
  93. package/dist/components/tooltip/index.js +12 -9
  94. package/dist/components/tooltip/index.js.map +1 -1
  95. package/dist/components/tooltip/style.js +1 -1
  96. package/dist/components/tooltip/style.js.map +1 -1
  97. package/dist/icons/generated/akar-icons-check.d.ts +6 -0
  98. package/dist/icons/generated/akar-icons-check.js +10 -0
  99. package/dist/icons/generated/akar-icons-check.js.map +1 -0
  100. package/dist/icons/generated/bi-check.d.ts +6 -0
  101. package/dist/icons/generated/bi-check.js +10 -0
  102. package/dist/icons/generated/bi-check.js.map +1 -0
  103. package/dist/icons/index.d.ts +2 -0
  104. package/dist/icons/index.js +3 -1
  105. package/dist/shared/form-association/field-id.js +9 -0
  106. package/dist/shared/form-association/field-id.js.map +1 -0
  107. package/dist/shared/form-association/index.js +9 -1
  108. package/dist/shared/form-association/index.js.map +1 -1
  109. package/dist/shared/label-emptiness/index.js +45 -0
  110. package/dist/shared/label-emptiness/index.js.map +1 -0
  111. package/dist/shared/option-portal/combobox-shell.js +47 -5
  112. package/dist/shared/option-portal/combobox-shell.js.map +1 -1
  113. package/dist/shared/option-portal/index.js +9 -9
  114. package/dist/shared/overlay/anchored-panel.js +2 -2
  115. package/dist/shared/overlay/anchored-panel.js.map +1 -1
  116. package/dist/shared/overlay/open-overlay.js +38 -22
  117. package/dist/shared/overlay/open-overlay.js.map +1 -1
  118. package/dist/shared/theme/root-sync.js +48 -0
  119. package/dist/shared/theme/root-sync.js.map +1 -0
  120. package/package.json +3 -1
@@ -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);-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,#fefefec2);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)}";
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 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(254 254 254 / 0.76));\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,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,#08f6);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 var(--wui-color-focus-ring, rgb(0 136 255 / 0.4));\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":""}
@@ -373,6 +373,12 @@ declare const WebUiAutocomplete_base: {
373
373
  * 可编辑输入框:`value` 即当前输入文本(表单值),键入时按 `filter` 模式过滤候选,
374
374
  * 选择 option 时文本回填为该项 label,`selected-value` 暴露该项的 value。
375
375
  * `allow-custom-value` 开启后,Enter 可把不匹配候选的原文作为 custom value 显式提交。
376
+ *
377
+ * 触发器跟随 select 的 wrapper div 模式:`slot[name="trigger"]` 可替换默认触发器
378
+ * (shadow 内的 `web-ui-input`);多行触发器(如 `web-ui-textarea`)保留 Enter 换行语义,
379
+ * 关闭面板用 Escape 或 blur。
380
+ * tab 位只属于触发器自身:默认触发器是 shadow 内 input,自定义触发器由消费者提供
381
+ * 可聚焦元素(README 契约);包装 div 恒为 tabindex="-1",不占顺序焦点,避免双 tab 位。
376
382
  */
377
383
  export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
378
384
  static styles: import('lit').CSSResult[];
@@ -403,6 +409,7 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
403
409
  private _isOpen;
404
410
  private _activeIndex;
405
411
  private _focused;
412
+ private _hasTriggerSlot;
406
413
  private static _nextInstanceId;
407
414
  private readonly _idPrefix;
408
415
  private readonly _a11yOptionIds;
@@ -412,14 +419,19 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
412
419
  private _portalContent?;
413
420
  private readonly _scrollLock;
414
421
  private readonly _optionPortal;
422
+ private readonly _trigger;
415
423
  private readonly _overlay;
416
424
  private readonly _panel;
417
425
  get isOpen(): boolean;
418
426
  get open(): boolean;
427
+ focus(options?: FocusOptions): void;
428
+ blur(): void;
419
429
  private _onClickOutside;
420
430
  private _onFocusOut;
421
431
  private _handlePanelPointerDown;
422
432
  connectedCallback(): void;
433
+ private _onTriggerSlotChange;
434
+ private _syncTriggerSlot;
423
435
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
424
436
  disconnectedCallback(): void;
425
437
  firstUpdated(): void;
@@ -451,11 +463,11 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
451
463
  private _findExactOption;
452
464
  private _hasExactOption;
453
465
  private _selectCustomValue;
454
- private _onInput;
455
- private _onInnerChange;
456
- private _onFocus;
457
- private _onInputClick;
458
- private _onBlur;
466
+ private _onTriggerInput;
467
+ private _onTriggerClick;
468
+ private _onTriggerFocusIn;
469
+ private _onTriggerFocusOut;
470
+ private _isSlottedFocus;
459
471
  private readonly _openController;
460
472
  private _open;
461
473
  private _close;
@@ -1,35 +1,39 @@
1
1
  import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
2
- import "../option/index.js";
3
2
  import t from "../../assets/glass.js";
4
- import n from "../../assets/overlay-motion.js";
5
- import { FormAssociated as r, FormAssociationController as i, defineFormAssociation as a } from "../../shared/form-association/index.js";
6
- import { normalizeLiteral as o } from "../../shared/normalize/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
+ import "../input/index.js";
6
+ import "../option/index.js";
7
+ import o from "../../assets/overlay-motion.js";
7
8
  import { dispatchOpenChangeEvent as s } from "../../shared/open-state/index.js";
8
- import { createComboboxOpenController as c, createOptionListenerBinding as l, handleComboboxFocusOut as u, nextWrappingIndex as d } from "../../shared/option-portal/combobox-shell.js";
9
- import { defineOptionPortal as f } from "../../shared/option-portal/index.js";
10
- import { defineAnchoredPanel as p } from "../../shared/overlay/anchored-panel.js";
11
- import { defineOpenOverlay as m } from "../../shared/overlay/open-overlay.js";
12
- import { applyOverlayVariables as h, defineOverlayPortal as g } from "../../shared/overlay/portal.js";
13
- import { defineScrollLockLease as _ } from "../../shared/scroll-lock/scroll-lock.js";
14
- import v from "./style.js";
15
- import { LitElement as y, html as b, nothing as x, unsafeCSS as S } from "lit";
16
- import { customElement as C, property as w, state as T } from "lit/decorators.js";
17
- import { ifDefined as E } from "lit/directives/if-defined.js";
9
+ import { createComboboxOpenController as c, createOptionListenerBinding as l, defineComboboxTrigger as u, handleComboboxFocusOut as d, nextWrappingIndex as f } from "../../shared/option-portal/combobox-shell.js";
10
+ import { defineOptionPortal as p } from "../../shared/option-portal/index.js";
11
+ import { defineAnchoredPanel as m } from "../../shared/overlay/anchored-panel.js";
12
+ import { defineOpenOverlay as h } from "../../shared/overlay/open-overlay.js";
13
+ import { applyOverlayVariables as g, defineOverlayPortal as _ } from "../../shared/overlay/portal.js";
14
+ import { defineScrollLockLease as v } from "../../shared/scroll-lock/scroll-lock.js";
15
+ import y from "./style.js";
16
+ import { LitElement as b, html as x, nothing as S, unsafeCSS as C } from "lit";
17
+ import { customElement as w, property as T, state as E } from "lit/decorators.js";
18
+ import { ifDefined as D } from "lit/directives/if-defined.js";
18
19
  //#region src/components/autocomplete/index.ts
19
- var D, O = [
20
+ var O, k = [
20
21
  "none",
21
22
  "prefix",
22
23
  "contains"
23
24
  ];
24
- function k(e) {
25
+ function A(e) {
25
26
  return e instanceof Element && e.getAttribute("slot") === "empty";
26
27
  }
27
- var A = class extends r(y) {
28
+ function j(e) {
29
+ return e instanceof Element && e.slot === "trigger";
30
+ }
31
+ var M = class extends n(b) {
28
32
  static {
29
- D = this;
33
+ O = this;
30
34
  }
31
35
  constructor(...e) {
32
- 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({
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 = i({
33
37
  host: this,
34
38
  initialize: () => {
35
39
  let e = this.getAttribute("value");
@@ -45,19 +49,33 @@ var A = class extends r(y) {
45
49
  typeof e == "string" && (this.value = e);
46
50
  },
47
51
  syncValidity: () => this._syncValidity()
48
- }).make(), this._formAssociationController = new i(this, this._formAssociation), this._isOpen = !1, this._activeIndex = -1, this._focused = !1, this._idPrefix = `web-ui-autocomplete-${++D._nextInstanceId}`, this._a11yOptionIds = /* @__PURE__ */ new WeakMap(), this._nextA11yOptionId = 0, this._options = [], this._scrollLock = _().make(), this._optionPortal = f().make({
52
+ }).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({
49
53
  element: this,
50
54
  idPrefix: `${this._idPrefix}-option`,
51
55
  getPortal: () => this._portal,
52
56
  getPortalContent: () => this._portalContent,
53
57
  isOpen: () => this.portal && this._isOpen,
54
- getMigratableNodes: () => Array.from(this.childNodes).filter((e) => !k(e)),
58
+ getMigratableNodes: () => Array.from(this.childNodes).filter((e) => !A(e) && !j(e)),
55
59
  hasUpdated: () => this.hasUpdated,
56
60
  requestUpdate: () => this.requestUpdate(),
57
61
  bindOption: (e) => this._bindOption(e),
58
62
  unbindOption: (e) => this._unbindOption(e)
59
- }), this._overlay = m().make({ requestClose: () => this._close() }), this._panel = p().make({
60
- getAnchor: () => this.shadowRoot?.querySelector(".input-wrapper") ?? null,
63
+ }), this._trigger = u().make({
64
+ getWrapper: () => this.shadowRoot?.querySelector(".autocomplete-trigger") ?? null,
65
+ getCustomTrigger: () => {
66
+ let e = this.shadowRoot?.querySelector("slot[name=\"trigger\"]")?.assignedElements()[0];
67
+ return e instanceof HTMLElement ? e : null;
68
+ },
69
+ getFallbackTrigger: () => this.shadowRoot?.querySelector(".autocomplete-input") ?? null,
70
+ onInput: (e) => this._onTriggerInput(e),
71
+ onClick: () => this._onTriggerClick(),
72
+ onFocusIn: (e) => this._onTriggerFocusIn(e),
73
+ onFocusOut: (e) => this._onTriggerFocusOut(e)
74
+ }), this._overlay = h().make({
75
+ requestClose: () => this._close(),
76
+ isConnected: () => this.isConnected
77
+ }), this._panel = m().make({
78
+ getAnchor: () => this._trigger.getTrigger() ?? this.shadowRoot?.querySelector(".autocomplete-trigger") ?? null,
61
79
  getLocalPanel: () => this.shadowRoot?.querySelector(".autocomplete-overlay") ?? null,
62
80
  getPositioning: () => ({
63
81
  placement: "bottom-start",
@@ -71,9 +89,11 @@ var A = class extends r(y) {
71
89
  }), this._onClickOutside = (e) => {
72
90
  this._isOpen && (e.composedPath().includes(this) || this._panel.getHandle()?.containsEvent(e) || this._close());
73
91
  }, this._onFocusOut = () => {
74
- u(this, () => this._panel.getHandle(), () => this._isOpen, () => this._close());
92
+ d(this, () => this._panel.getHandle(), () => this._isOpen, () => this._close());
75
93
  }, this._handlePanelPointerDown = (e) => {
76
94
  e.preventDefault();
95
+ }, this._onTriggerSlotChange = () => {
96
+ this._syncTriggerSlot();
77
97
  }, this._optionListeners = l({
78
98
  onClick: (e) => this._handleOptionClick(e),
79
99
  onPointerOver: (e) => this._handleOptionPointerOver(e),
@@ -94,12 +114,11 @@ var A = class extends r(y) {
94
114
  }, this._onKeydown = (e) => {
95
115
  if (!(this._isDisabled || this.readonly)) switch (e.key) {
96
116
  case "ArrowDown":
97
- e.preventDefault(), this._isOpen ? this._navigateActive(1) : this._open(!0);
98
- break;
99
117
  case "ArrowUp":
100
- e.preventDefault(), this._isOpen ? this._navigateActive(-1) : this._open(!0);
118
+ if (this._isOpen && this._trigger.isMultilineEdit(e)) break;
119
+ e.preventDefault(), this._isOpen ? this._navigateActive(e.key === "ArrowDown" ? 1 : -1) : this._open(!0);
101
120
  break;
102
- case "Enter": if (this._isOpen) {
121
+ case "Enter": if (this._isOpen && !this._trigger.isMultilineEdit(e)) {
103
122
  e.preventDefault();
104
123
  let t = this._options[this._activeIndex];
105
124
  if (t && !t.disabled && !t.hasAttribute("data-filtered")) {
@@ -114,18 +133,20 @@ var A = class extends r(y) {
114
133
  this.allowCustomValue && this._value && !this._hasExactOption(this._value) && this._selectCustomValue();
115
134
  }
116
135
  }
117
- }, this._onInput = (e) => {
118
- if (this._isDisabled || this.readonly) return;
119
- let t = e.target;
120
- t.value !== this._value && (this.value = t.value, this._activeIndex = -1, this._syncActiveOption(), this._isOpen || this._open());
121
- }, this._onInnerChange = (e) => {
122
- e.stopPropagation();
123
- }, this._onFocus = () => {
124
- this._isDisabled || (this._focused = !0);
125
- }, this._onInputClick = () => {
136
+ }, this._onTriggerInput = (e) => {
137
+ this._isDisabled || this.readonly || e !== this._value && (this.value = e, this._activeIndex = -1, this._syncActiveOption(), this._isOpen || this._open());
138
+ }, this._onTriggerClick = () => {
126
139
  this._isDisabled || this.readonly || this._options.length > 0 && this._open();
127
- }, this._onBlur = () => {
128
- this._focused = !1;
140
+ }, this._onTriggerFocusIn = (e) => {
141
+ this._isDisabled || (this._focused = !0, this._isSlottedFocus(e) && this.dispatchEvent(new FocusEvent("focus", {
142
+ composed: !0,
143
+ relatedTarget: e.relatedTarget
144
+ })));
145
+ }, this._onTriggerFocusOut = (e) => {
146
+ this._focused = !1, this._isSlottedFocus(e) && this.dispatchEvent(new FocusEvent("blur", {
147
+ composed: !0,
148
+ relatedTarget: e.relatedTarget
149
+ }));
129
150
  }, this._openController = c({
130
151
  canOpen: () => !this._isDisabled && !this.readonly,
131
152
  getIsOpen: () => this._isOpen,
@@ -150,9 +171,9 @@ var A = class extends r(y) {
150
171
  }
151
172
  static {
152
173
  this.styles = [
153
- S(t),
154
- S(n),
155
- S(v)
174
+ C(t),
175
+ C(o),
176
+ C(y)
156
177
  ];
157
178
  }
158
179
  get filter() {
@@ -160,7 +181,7 @@ var A = class extends r(y) {
160
181
  }
161
182
  set filter(e) {
162
183
  let t = this._filter;
163
- this._filter = o(e, O, "contains"), this.requestUpdate("filter", t);
184
+ this._filter = a(e, k, "contains"), this.requestUpdate("filter", t);
164
185
  }
165
186
  get value() {
166
187
  return this._value;
@@ -188,8 +209,18 @@ var A = class extends r(y) {
188
209
  get open() {
189
210
  return this._isOpen;
190
211
  }
212
+ focus(e) {
213
+ this._trigger.focusTrigger(e);
214
+ }
215
+ blur() {
216
+ this._trigger.blurTrigger();
217
+ }
191
218
  connectedCallback() {
192
- super.connectedCallback(), this._optionPortal.bindHost(), this.addEventListener("keydown", this._onKeydown), this.addEventListener("focusout", this._onFocusOut), document.addEventListener("click", this._onClickOutside);
219
+ super.connectedCallback(), this._optionPortal.bindHost(), this._trigger.bind(), this.addEventListener("keydown", this._onKeydown), this.addEventListener("focusout", this._onFocusOut), document.addEventListener("click", this._onClickOutside);
220
+ }
221
+ _syncTriggerSlot() {
222
+ let e = Array.from(this.children).some(j);
223
+ this._hasTriggerSlot !== e && (this._hasTriggerSlot = e, this.hasUpdated && this._reconfigureOverlay());
193
224
  }
194
225
  attributeChangedCallback(e, t, n) {
195
226
  super.attributeChangedCallback(e, t, n), e === "selected-value" && this.isConnected && n !== this._selectedValue && queueMicrotask(() => {
@@ -197,19 +228,18 @@ var A = class extends r(y) {
197
228
  });
198
229
  }
199
230
  disconnectedCallback() {
200
- super.disconnectedCallback(), this._optionPortal.dispose(), this.removeEventListener("keydown", this._onKeydown), this.removeEventListener("focusout", this._onFocusOut), document.removeEventListener("click", this._onClickOutside), this._options.forEach(this._unbindOption), this._close(), this._portal = void 0, this._portalContent = void 0, this._panel.dispose(), this._scrollLock.release();
231
+ super.disconnectedCallback(), this._optionPortal.dispose(), this._trigger.dispose(), this.removeEventListener("keydown", this._onKeydown), this.removeEventListener("focusout", this._onFocusOut), document.removeEventListener("click", this._onClickOutside), this._options.forEach(this._unbindOption), this._close(), this._portal = void 0, this._portalContent = void 0, this._panel.dispose(), this._scrollLock.release();
201
232
  }
202
233
  firstUpdated() {
203
- requestAnimationFrame(() => {
234
+ this._trigger.bind(), requestAnimationFrame(() => {
204
235
  this.isConnected && this._optionPortal.scheduleRefresh();
205
236
  });
206
237
  }
207
238
  willUpdate() {
208
- this._refreshOptions(), this._optionPortal.ensureOptionIds(this._options), this._syncSelectedValue(), this._applyFilter(), this._syncOptionA11y(), this._syncActiveOption();
239
+ this._syncTriggerSlot(), this._refreshOptions(), this._optionPortal.ensureOptionIds(this._options), this._syncSelectedValue(), this._applyFilter(), this._syncOptionA11y(), this._syncActiveOption();
209
240
  }
210
241
  updated(e) {
211
- let t = this.shadowRoot?.querySelector(".autocomplete-input");
212
- t && t.value !== this._value && (t.value = 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();
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();
213
243
  }
214
244
  formDisabledCallback(e) {
215
245
  this._formAssociation.setDisabled(e), e && this._isOpen && this._close();
@@ -260,7 +290,7 @@ var A = class extends r(y) {
260
290
  let t = this._options.filter((e) => !e.disabled && !e.hasAttribute("data-filtered"));
261
291
  if (!t.length) return;
262
292
  let n = this._activeIndex >= 0 ? t.indexOf(this._options[this._activeIndex]) : e > 0 ? -1 : 0;
263
- this._activeIndex = this._options.indexOf(t[d(t.length, n, e)]), this._syncActiveOption();
293
+ this._activeIndex = this._options.indexOf(t[f(t.length, n, e)]), this._syncActiveOption();
264
294
  }
265
295
  _setInitialActiveOption() {
266
296
  let e = this._options.findIndex((e) => !e.disabled && !e.hasAttribute("data-filtered"));
@@ -295,6 +325,10 @@ var A = class extends r(y) {
295
325
  composed: !0
296
326
  }));
297
327
  }
328
+ _isSlottedFocus(e) {
329
+ let t = e.target;
330
+ return t instanceof Node && !!this.shadowRoot && !this.shadowRoot.contains(t);
331
+ }
298
332
  _open(e = !1) {
299
333
  this._openController.open(e);
300
334
  }
@@ -317,14 +351,14 @@ var A = class extends r(y) {
317
351
  this._scrollLock.sync(e && !this.noScrollLock);
318
352
  }
319
353
  _createPortal() {
320
- let e = g().make({
354
+ let e = _().make({
321
355
  container: this.overlayContainer,
322
356
  target: this,
323
- style: `${t}\n${n}\n${v}`,
357
+ style: `${t}\n${o}\n${y}`,
324
358
  className: "wui-glass autocomplete-overlay portal wui-floating-panel",
325
359
  onContentChange: (e) => {
326
360
  this._optionPortal.scheduleRefresh();
327
- let t = e.flatMap((e) => [...e.removedNodes]).filter(k);
361
+ let t = e.flatMap((e) => [...e.removedNodes]).filter(A);
328
362
  if (t.length) {
329
363
  this._portal?.removeContent(t);
330
364
  let e = this._portal?.panel.querySelector(".autocomplete-empty");
@@ -332,18 +366,18 @@ var A = class extends r(y) {
332
366
  }
333
367
  }
334
368
  });
335
- this._portal = e, h(e.panel, this, [
369
+ this._portal = e, g(e.panel, this, [
336
370
  "--wui-overlay-min-width",
337
371
  "--wui-autocomplete-max-width",
338
372
  "--wui-autocomplete-max-height"
339
373
  ]), e.panel.setAttribute("aria-hidden", "true"), e.panel.addEventListener("pointerdown", this._handlePanelPointerDown);
374
+ let n = document.createElement("div");
375
+ n.className = "autocomplete-scroll";
340
376
  let r = document.createElement("div");
341
- r.className = "autocomplete-scroll";
377
+ r.className = "autocomplete-content", this._portalContent = r;
342
378
  let i = document.createElement("div");
343
- i.className = "autocomplete-content", this._portalContent = i;
344
- let a = document.createElement("div");
345
- a.className = "autocomplete-empty", a.hidden = !0, a.dataset.wuiA11yEmpty = this._getEmptySlotText(), r.append(i), i.append(a), e.panel.append(r);
346
- for (let t of Array.from(this.childNodes)) t instanceof Comment || (k(t) ? e.appendContent([t], a) : e.appendContent([t], i));
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));
347
381
  return e;
348
382
  }
349
383
  _getLabelledbyText() {
@@ -358,36 +392,37 @@ var A = class extends r(y) {
358
392
  return (this.shadowRoot?.querySelector("slot[name=\"empty\"]"))?.assignedElements().map((e) => e.textContent?.trim()).filter(Boolean).join(" ").trim() || "无匹配选项";
359
393
  }
360
394
  render() {
361
- 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) : x;
362
- return b`
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
+ return x`
363
397
  <div class="wui-autocomplete-inner">
364
- ${n ? b`<span class="autocomplete-a11y-only" id=${t}>${n}</span>` : x}
365
- <div class="wui-glass input-wrapper">
366
- <input
367
- class="autocomplete-input"
368
- type="text"
369
- placeholder=${this.placeholder}
370
- name=${this.name}
371
- .value=${this._value}
372
- aria-label=${E(this.ariaLabel)}
373
- aria-labelledby=${n ? t : x}
374
- ?disabled=${this._isDisabled}
375
- ?readonly=${this.readonly}
376
- ?required=${this.required}
377
- role="combobox"
378
- aria-expanded=${this._isOpen}
379
- aria-haspopup="listbox"
380
- aria-autocomplete="list"
381
- aria-controls=${e}
382
- aria-disabled=${String(this._isDisabled)}
383
- aria-readonly=${this.readonly ? "true" : x}
384
- aria-activedescendant=${a}
385
- @input=${this._onInput}
386
- @change=${this._onInnerChange}
387
- @click=${this._onInputClick}
388
- @focus=${this._onFocus}
389
- @blur=${this._onBlur}
390
- />
398
+ ${n ? x`<span class="autocomplete-a11y-only" id=${t}>${n}</span>` : S}
399
+ <div
400
+ class="autocomplete-trigger"
401
+ ?data-custom-trigger=${this._hasTriggerSlot}
402
+ role="combobox"
403
+ aria-expanded=${this._isOpen}
404
+ aria-haspopup="listbox"
405
+ aria-autocomplete="list"
406
+ aria-controls=${e}
407
+ aria-disabled=${String(this._isDisabled)}
408
+ aria-readonly=${this.readonly ? "true" : S}
409
+ aria-label=${D(this.ariaLabel)}
410
+ aria-labelledby=${n ? t : S}
411
+ aria-activedescendant=${a}
412
+ tabindex="-1"
413
+ >
414
+ <slot name="trigger" @slotchange=${this._onTriggerSlotChange}></slot>
415
+ ${this._hasTriggerSlot ? S : x`<web-ui-input
416
+ class="autocomplete-input"
417
+ .value=${this._value}
418
+ placeholder=${this.placeholder}
419
+ name=${this.name}
420
+ ?borderless=${this.borderless}
421
+ ?disabled=${this._isDisabled}
422
+ ?readonly=${this.readonly}
423
+ ?required=${this.required}
424
+ aria-label=${D(this.ariaLabel || n || void 0)}
425
+ ></web-ui-input>`}
391
426
  </div>
392
427
  <div
393
428
  class="autocomplete-a11y-listbox"
@@ -396,7 +431,7 @@ var A = class extends r(y) {
396
431
  ?hidden=${!this._isOpen}
397
432
  aria-hidden=${String(!this._isOpen)}
398
433
  >
399
- ${r.map((e) => b`<div
434
+ ${r.map((e) => x`<div
400
435
  id=${this._getA11yOptionId(e)}
401
436
  role="option"
402
437
  aria-selected=${e.value === this._selectedValue ? "true" : "false"}
@@ -426,46 +461,46 @@ var A = class extends r(y) {
426
461
  `;
427
462
  }
428
463
  };
429
- e([w({
464
+ e([T({
430
465
  type: String,
431
466
  reflect: !0
432
- })], A.prototype, "placeholder", void 0), e([w({
467
+ })], M.prototype, "placeholder", void 0), e([T({
433
468
  type: Boolean,
434
469
  reflect: !0
435
- })], A.prototype, "borderless", void 0), e([w({
470
+ })], M.prototype, "borderless", void 0), e([T({
436
471
  type: Boolean,
437
472
  reflect: !0
438
- })], A.prototype, "disabled", void 0), e([w({
473
+ })], M.prototype, "disabled", void 0), e([T({
439
474
  type: Boolean,
440
475
  reflect: !0
441
- })], A.prototype, "readonly", void 0), e([w({
476
+ })], M.prototype, "readonly", void 0), e([T({
442
477
  type: Boolean,
443
478
  reflect: !0
444
- })], A.prototype, "required", void 0), e([w({
479
+ })], M.prototype, "required", void 0), e([T({
445
480
  type: Boolean,
446
481
  reflect: !0
447
- })], A.prototype, "portal", void 0), e([w({
482
+ })], M.prototype, "portal", void 0), e([T({
448
483
  type: Boolean,
449
484
  reflect: !0,
450
485
  attribute: "no-scroll-lock"
451
- })], A.prototype, "noScrollLock", void 0), e([w({
486
+ })], M.prototype, "noScrollLock", void 0), e([T({
452
487
  type: Boolean,
453
488
  reflect: !0,
454
489
  attribute: "allow-custom-value"
455
- })], A.prototype, "allowCustomValue", void 0), e([w({ attribute: !1 })], A.prototype, "overlayContainer", void 0), e([w({
490
+ })], M.prototype, "allowCustomValue", void 0), e([T({ attribute: !1 })], M.prototype, "overlayContainer", void 0), e([T({
456
491
  type: String,
457
492
  reflect: !0
458
- })], A.prototype, "name", void 0), e([w({
493
+ })], M.prototype, "name", void 0), e([T({
459
494
  type: String,
460
495
  attribute: "aria-label"
461
- })], A.prototype, "ariaLabel", void 0), e([w({
496
+ })], M.prototype, "ariaLabel", void 0), e([T({
462
497
  type: String,
463
498
  attribute: "aria-labelledby"
464
- })], A.prototype, "ariaLabelledby", void 0), e([w({
499
+ })], M.prototype, "ariaLabelledby", void 0), e([T({
465
500
  type: String,
466
501
  reflect: !0
467
- })], A.prototype, "filter", null), e([T()], A.prototype, "_value", void 0), e([T()], A.prototype, "_selectedValue", void 0), e([T()], A.prototype, "_isOpen", void 0), e([T()], A.prototype, "_activeIndex", void 0), e([T()], A.prototype, "_focused", void 0), A = D = e([C("web-ui-autocomplete")], A);
502
+ })], M.prototype, "filter", null), e([E()], M.prototype, "_value", void 0), e([E()], M.prototype, "_selectedValue", void 0), e([E()], M.prototype, "_isOpen", void 0), e([E()], M.prototype, "_activeIndex", void 0), e([E()], M.prototype, "_focused", void 0), e([E()], M.prototype, "_hasTriggerSlot", void 0), M = O = e([w("web-ui-autocomplete")], M);
468
503
  //#endregion
469
- export { A as WebUiAutocomplete };
504
+ export { M as WebUiAutocomplete };
470
505
 
471
506
  //# sourceMappingURL=index.js.map