@greypan/web-ui 12.0.1 → 12.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 (129) hide show
  1. package/README.CN.md +2 -0
  2. package/README.md +2 -0
  3. package/dist/assets/menu-portal.js +1 -1
  4. package/dist/assets/menu-portal.js.map +1 -1
  5. package/dist/assets/toast-containers.js +1 -1
  6. package/dist/assets/toast-containers.js.map +1 -1
  7. package/dist/components/autocomplete/index.d.ts +5 -0
  8. package/dist/components/autocomplete/index.d.ts.map +1 -1
  9. package/dist/components/autocomplete/index.js +17 -1
  10. package/dist/components/autocomplete/index.js.map +1 -1
  11. package/dist/components/autocomplete/style.js +1 -1
  12. package/dist/components/autocomplete/style.js.map +1 -1
  13. package/dist/components/back-top/style.js +1 -1
  14. package/dist/components/back-top/style.js.map +1 -1
  15. package/dist/components/button-group/style.js +1 -1
  16. package/dist/components/button-group/style.js.map +1 -1
  17. package/dist/components/dialog/index.d.ts +5 -1
  18. package/dist/components/dialog/index.d.ts.map +1 -1
  19. package/dist/components/dialog/index.js +16 -4
  20. package/dist/components/dialog/index.js.map +1 -1
  21. package/dist/components/dialog/style.js +1 -1
  22. package/dist/components/dialog/style.js.map +1 -1
  23. package/dist/components/dropdown/index.js +1 -1
  24. package/dist/components/icon/index.d.ts +1 -1
  25. package/dist/components/icon/index.d.ts.map +1 -1
  26. package/dist/components/index.d.ts +3 -2
  27. package/dist/components/index.d.ts.map +1 -1
  28. package/dist/components/index.js +2 -1
  29. package/dist/components/layout/index.d.ts +8 -0
  30. package/dist/components/layout/index.d.ts.map +1 -1
  31. package/dist/components/layout/index.js +23 -13
  32. package/dist/components/layout/index.js.map +1 -1
  33. package/dist/components/layout/style.js +1 -1
  34. package/dist/components/layout/style.js.map +1 -1
  35. package/dist/components/popover/index.js +1 -1
  36. package/dist/components/popover/style.js +1 -1
  37. package/dist/components/popover/style.js.map +1 -1
  38. package/dist/components/progress/index.d.ts +30 -0
  39. package/dist/components/progress/index.d.ts.map +1 -0
  40. package/dist/components/progress/index.js +103 -0
  41. package/dist/components/progress/index.js.map +1 -0
  42. package/dist/components/progress/style.js +5 -0
  43. package/dist/components/progress/style.js.map +1 -0
  44. package/dist/components/segmented-trigger/index.d.ts +2 -0
  45. package/dist/components/segmented-trigger/index.d.ts.map +1 -1
  46. package/dist/components/segmented-trigger/index.js +7 -0
  47. package/dist/components/segmented-trigger/index.js.map +1 -1
  48. package/dist/components/select/index.d.ts +13 -0
  49. package/dist/components/select/index.d.ts.map +1 -1
  50. package/dist/components/select/index.js +41 -3
  51. package/dist/components/select/index.js.map +1 -1
  52. package/dist/components/select/style.js +1 -1
  53. package/dist/components/select/style.js.map +1 -1
  54. package/dist/components/spinner/index.d.ts +0 -3
  55. package/dist/components/spinner/index.d.ts.map +1 -1
  56. package/dist/components/spinner/index.js +5 -20
  57. package/dist/components/spinner/index.js.map +1 -1
  58. package/dist/components/spinner/style.js +1 -1
  59. package/dist/components/spinner/style.js.map +1 -1
  60. package/dist/components/theme/style.js +1 -1
  61. package/dist/components/theme/style.js.map +1 -1
  62. package/dist/components/tooltip/index.js +1 -1
  63. package/dist/components/tooltip/style.js +1 -1
  64. package/dist/components/tooltip/style.js.map +1 -1
  65. package/dist/icons/generated/ant-design-sync-outlined.d.ts +7 -0
  66. package/dist/icons/generated/ant-design-sync-outlined.d.ts.map +1 -0
  67. package/dist/icons/generated/ant-design-sync-outlined.js +9 -0
  68. package/dist/icons/generated/ant-design-sync-outlined.js.map +1 -0
  69. package/dist/icons/generated/ic-baseline-phonelink.d.ts +7 -0
  70. package/dist/icons/generated/ic-baseline-phonelink.d.ts.map +1 -0
  71. package/dist/icons/generated/ic-baseline-phonelink.js +9 -0
  72. package/dist/icons/generated/ic-baseline-phonelink.js.map +1 -0
  73. package/dist/icons/generated/ic-outline-motion-photos-off.d.ts +7 -0
  74. package/dist/icons/generated/ic-outline-motion-photos-off.d.ts.map +1 -0
  75. package/dist/icons/generated/ic-outline-motion-photos-off.js +9 -0
  76. package/dist/icons/generated/ic-outline-motion-photos-off.js.map +1 -0
  77. package/dist/icons/generated/ic-outline-motion-photos-on.d.ts +7 -0
  78. package/dist/icons/generated/ic-outline-motion-photos-on.d.ts.map +1 -0
  79. package/dist/icons/generated/ic-outline-motion-photos-on.js +9 -0
  80. package/dist/icons/generated/ic-outline-motion-photos-on.js.map +1 -0
  81. package/dist/icons/generated/ic-round-menu-open.d.ts +7 -0
  82. package/dist/icons/generated/ic-round-menu-open.d.ts.map +1 -0
  83. package/dist/icons/generated/ic-round-menu-open.js +9 -0
  84. package/dist/icons/generated/ic-round-menu-open.js.map +1 -0
  85. package/dist/icons/generated/lucide-accessibility.d.ts +7 -0
  86. package/dist/icons/generated/lucide-accessibility.d.ts.map +1 -0
  87. package/dist/icons/generated/lucide-accessibility.js +9 -0
  88. package/dist/icons/generated/lucide-accessibility.js.map +1 -0
  89. package/dist/icons/generated/lucide-boxes.d.ts +7 -0
  90. package/dist/icons/generated/lucide-boxes.d.ts.map +1 -0
  91. package/dist/icons/generated/lucide-boxes.js +9 -0
  92. package/dist/icons/generated/lucide-boxes.js.map +1 -0
  93. package/dist/icons/generated/lucide-contrast.d.ts +7 -0
  94. package/dist/icons/generated/lucide-contrast.d.ts.map +1 -0
  95. package/dist/icons/generated/lucide-contrast.js +9 -0
  96. package/dist/icons/generated/lucide-contrast.js.map +1 -0
  97. package/dist/icons/generated/lucide-keyboard.d.ts +7 -0
  98. package/dist/icons/generated/lucide-keyboard.d.ts.map +1 -0
  99. package/dist/icons/generated/lucide-keyboard.js +9 -0
  100. package/dist/icons/generated/lucide-keyboard.js.map +1 -0
  101. package/dist/icons/generated/lucide-languages.d.ts +7 -0
  102. package/dist/icons/generated/lucide-languages.d.ts.map +1 -0
  103. package/dist/icons/generated/lucide-languages.js +9 -0
  104. package/dist/icons/generated/lucide-languages.js.map +1 -0
  105. package/dist/icons/generated/lucide-list.d.ts +7 -0
  106. package/dist/icons/generated/lucide-list.d.ts.map +1 -0
  107. package/dist/icons/generated/lucide-list.js +9 -0
  108. package/dist/icons/generated/lucide-list.js.map +1 -0
  109. package/dist/icons/generated/lucide-moon.d.ts +7 -0
  110. package/dist/icons/generated/lucide-moon.d.ts.map +1 -0
  111. package/dist/icons/generated/lucide-moon.js +9 -0
  112. package/dist/icons/generated/lucide-moon.js.map +1 -0
  113. package/dist/icons/generated/lucide-sparkles.d.ts +7 -0
  114. package/dist/icons/generated/lucide-sparkles.d.ts.map +1 -0
  115. package/dist/icons/generated/lucide-sparkles.js +9 -0
  116. package/dist/icons/generated/lucide-sparkles.js.map +1 -0
  117. package/dist/icons/generated/lucide-sun.d.ts +7 -0
  118. package/dist/icons/generated/lucide-sun.d.ts.map +1 -0
  119. package/dist/icons/generated/lucide-sun.js +9 -0
  120. package/dist/icons/generated/lucide-sun.js.map +1 -0
  121. package/dist/icons/generated/tabler-brand-typescript.d.ts +7 -0
  122. package/dist/icons/generated/tabler-brand-typescript.d.ts.map +1 -0
  123. package/dist/icons/generated/tabler-brand-typescript.js +9 -0
  124. package/dist/icons/generated/tabler-brand-typescript.js.map +1 -0
  125. package/dist/icons/index.d.ts +87 -72
  126. package/dist/icons/index.js +16 -1
  127. package/dist/shared/locale/builtin-labels.js +2 -1
  128. package/dist/shared/locale/builtin-labels.js.map +1 -1
  129. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/layout/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n --wui-layout-visible-banner-height: 0px;\n\n display: block;\n}\n\n/* 页面级滚动容器。Banner 位于正文前,随页面一起滚动。 */\n.layout-page {\n display: flex;\n flex-direction: column;\n min-height: 100vh;\n min-height: 100dvh;\n}\n\n.layout-banner {\n position: relative;\n z-index: var(--wui-layer-banner, 30);\n}\n\n/* 参考 book-fe:正文区域负责撑高 sidebar 的 relative wrapper。 */\n.layout-body {\n display: flex;\n flex: 1;\n}\n\n.sidebar-wrapper {\n position: relative;\n align-self: stretch;\n}\n\n/* Layout 只提供可用高度;桌面端由 Consumer 决定 scrollport,移动端由 Drawer content 提供。 */\n.sidebar-viewport {\n flex: 1;\n min-height: 0;\n}\n\n/*\n * Banner 可见时,组件用它的当前可见高度缩短 aside;Banner 滚出后该值归零。\n * 因而圆角卡片始终完整可见,同时 sticky Sidebar 可在 Banner 消失后填满视口。\n */\naside {\n position: sticky;\n z-index: var(--wui-layer-sidebar, 50);\n top: 0;\n\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n max-width: 50vw;\n height: calc(100vh - var(--wui-layout-visible-banner-height));\n height: calc(100dvh - var(--wui-layout-visible-banner-height));\n max-height: calc(100vh - var(--wui-layout-visible-banner-height));\n max-height: calc(100dvh - var(--wui-layout-visible-banner-height));\n padding: var(--wui-space-2, 8px) 0 var(--wui-space-2, 8px) var(--wui-space-2, 8px);\n\n transition: width var(--wui-duration-layout, 200ms) var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1));\n\n .aside-panel {\n --wui-glass-corner-radius: var(--wui-layout-sidebar-radius, 24px);\n\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-height: 0;\n border-radius: var(--wui-layout-sidebar-radius, 24px);\n\n /* 深色下比 page 浅一档的专用表面 token。不直接复用 --wui-color-surface-overlay:\n 该 token 同时服务 dialog/drawer/toast,整体抬升会带偏不在本次范围内的表面。\n 浅色保持中性分层,无 theme 时回退到同一字面量。 */\n background-color: var(--wui-color-surface-sidebar, rgb(233 233 233 / 0.82));\n }\n\n .sidebar-toggle-area {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n }\n\n .sidebar-toggle {\n /*\n * 走可覆盖的 var:`.sidebar-toggle` 自身声明的 `--wui-button-width` 优先于从\n * 祖先继承的同名变量,app 侧无法直接改写它。要让 collapsed state 的 toggle 跟着 collapsed width\n * 一起变,只能由这里显式接一个出口。取值由 app 决定,本组件不假设 collapsed width。\n * 默认值 44px;app 侧不覆盖时就是这个宽度。\n */\n --wui-button-width: var(--wui-layout-sidebar-toggle-width, 44px);\n\n margin: var(--wui-space-2, 8px);\n }\n\n &.collapsed {\n .sidebar-viewport {\n overflow: hidden;\n }\n }\n}\n\n/*\n * 命中条贴 aside 右缘(约 12px 宽),hover 或拖拽中显示 3px accent 竖线。\n * aside 有 8px padding,handle 定位在 padding 区外缘,不遮挡 aside-panel 内容。\n */\n.sidebar-resize-handle {\n touch-action: none;\n cursor: col-resize;\n\n position: absolute;\n z-index: 1;\n top: 0;\n right: -6px;\n bottom: 0;\n\n width: 12px;\n}\n\n.sidebar-resize-handle::before {\n content: '';\n\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n translate: -50%;\n\n width: 3px;\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n opacity: 0;\n background: var(--wui-color-accent, #0071e3);\n\n transition: opacity var(--wui-duration-feedback, 100ms) ease;\n}\n\n.sidebar-resize-handle:hover::before,\n.sidebar-resize-handle:focus-visible::before,\naside.is-resizing .sidebar-resize-handle::before {\n opacity: 1;\n}\n\n/*\n * 键盘 focus 同时给出两样东西:竖条与 hover / 拖拽同形,ring 与其余组件同一套浅蓝\n * 样式。竖条说明「命中条在哪」,ring 说明「键盘落点在哪」——handle 宽 12px 且通高,\n * 命中区远大于 3px 竖条本身,只靠竖条不足以说明焦点位置。\n *\n * ring 沿用 --wui-focus-ring-width / --wui-color-focus-ring 两个 token。圆角取\n * control token 后 outline 呈细长胶囊,与 button 的胶囊 ring 同一形状语言;offset\n * 2px 让 ring 骑在 aside 右缘内外两侧,不被 aside 裁掉。\n */\n.sidebar-resize-handle: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, #0071e3) 40%, transparent));\n outline-offset: 2px;\n}\n\n/* 拖拽中禁用宽度过渡,保证实时跟手。 */\naside.is-resizing {\n transition: none;\n}\n\n.layout-content {\n /*\n * 内容列的横向溢出由本层裁掉,避免撑出页面横向 scrollbar;它有 min-width: 0,\n * 是容纳横向溢出的位置。glow 伪元素已收在 header 盒内(见 header 的注释),\n * 不再依赖这层裁剪。\n *\n * clip 不创建滚动容器,因此不影响 header / footer 自身的 sticky;也不用 hidden——\n * 那会把本层变成滚动容器,sticky 随即失效。\n */\n overflow-x: clip;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-width: 0;\n}\n\nheader {\n /*\n * isolation: isolate 把负层级的 .wui-glow 伪元素限定在本 Header 的局部 stacking\n * context,slot 内容自然位于其上。晕染本身来自共享样式(src/classes/glow.css),\n * header-glow 属性负责挂 class。\n *\n * 「纵向必须 visible 才留得住模糊尾巴与下拉 overlay 的溢出空间」仍然成立——\n * overflow-* 一旦生效就会裁剪该轴,visible 是这些内容的唯一溢出出口。\n */\n isolation: isolate;\n position: sticky;\n z-index: var(--wui-layer-header, 10);\n top: 0;\n\n display: flex;\n gap: var(--wui-space-2, 8px);\n align-items: center;\n}\n\n/* 移动端 Toggle 属于组件自身,不随 Consumer 的 header 内边距缩进;\n 默认 8px 使其脱离视口边缘,Consumer 可用同名变量对齐自身内容左缘。 */\n.mobile-toggle {\n margin-left: var(--wui-layout-mobile-toggle-inset, 8px);\n}\n\nmain {\n flex: 1;\n}\n\nfooter {\n position: sticky;\n z-index: var(--wui-layer-tabbar, 40);\n bottom: 0;\n}\n\n@media (width <= 640px) {\n aside,\n .sidebar-wrapper {\n display: none;\n }\n\n /* Slot 可能包含展开后的多行 header;Toggle 对齐首行,而不是被整段 header 高度居中。 */\n header {\n align-items: flex-start;\n }\n\n .mobile-toggle {\n align-self: flex-start;\n margin-top: var(--wui-space-2, 8px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n aside {\n transition: none;\n }\n\n .sidebar-resize-handle::before {\n transition: none;\n }\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
1
+ {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/layout/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n --wui-layout-visible-banner-height: 0px;\n --wui-internal-layout-viewport-height: var(--wui-layout-viewport-height, 100vh);\n\n display: block;\n}\n\n/* 页面级滚动容器。Banner 位于正文前,随页面一起滚动。 */\n.layout-page {\n display: flex;\n flex-direction: column;\n min-height: var(--wui-internal-layout-viewport-height);\n}\n\n.layout-banner {\n position: relative;\n z-index: var(--wui-layer-banner, 300);\n}\n\n/* 参考 book-fe:正文区域负责撑高 sidebar 的 relative wrapper。 */\n.layout-body {\n display: flex;\n flex: 1;\n}\n\n.sidebar-wrapper {\n position: relative;\n align-self: stretch;\n}\n\n/* Layout 只提供可用高度;桌面端由 Consumer 决定 scrollport,移动端由 Drawer content 提供。 */\n.sidebar-viewport {\n flex: 1;\n min-height: 0;\n}\n\n/*\n * Banner 可见时,组件用它的当前可见高度缩短 aside;Banner 滚出后该值归零。\n * 因而圆角卡片始终完整可见,同时 sticky Sidebar 可在 Banner 消失后填满视口。\n */\naside {\n position: sticky;\n z-index: var(--wui-layer-sidebar, 500);\n top: 0;\n\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n\n max-width: 50vw;\n height: calc(var(--wui-internal-layout-viewport-height) - var(--wui-layout-visible-banner-height));\n max-height: calc(var(--wui-internal-layout-viewport-height) - var(--wui-layout-visible-banner-height));\n padding: var(--wui-space-2, 8px) 0 var(--wui-space-2, 8px) var(--wui-space-2, 8px);\n\n transition: width var(--wui-duration-layout, 200ms) var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1));\n\n .aside-panel {\n --wui-glass-corner-radius: var(--wui-layout-sidebar-radius, 24px);\n\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-height: 0;\n border-radius: var(--wui-layout-sidebar-radius, 24px);\n\n /* 深色下比 page 浅一档的专用表面 token。不直接复用 --wui-color-surface-overlay:\n 该 token 同时服务 dialog/drawer/toast,整体抬升会带偏不在本次范围内的表面。\n 浅色保持中性分层,无 theme 时回退到同一字面量。 */\n background-color: var(--wui-color-surface-sidebar, rgb(233 233 233 / 0.82));\n }\n\n .sidebar-toggle-area {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n }\n\n .sidebar-toggle {\n /*\n * 走可覆盖的 var:`.sidebar-toggle` 自身声明的 `--wui-button-width` 优先于从\n * 祖先继承的同名变量,app 侧无法直接改写它。要让 collapsed state 的 toggle 跟着 collapsed width\n * 一起变,只能由这里显式接一个出口。取值由 app 决定,本组件不假设 collapsed width。\n * 默认值 36px;app 侧不覆盖时就是这个宽度。\n */\n --wui-button-width: var(--wui-layout-sidebar-toggle-width, 36px);\n\n margin: var(--wui-space-2, 8px);\n }\n\n &.collapsed {\n .sidebar-viewport {\n overflow: hidden;\n }\n }\n}\n\n@supports (height: 100dvh) {\n :host {\n --wui-internal-layout-viewport-height: var(--wui-layout-viewport-height, 100dvh);\n }\n}\n\n/*\n * 命中条贴 aside 右缘(约 12px 宽),hover 或拖拽中显示 3px accent 竖线。\n * aside 有 8px padding,handle 定位在 padding 区外缘,不遮挡 aside-panel 内容。\n */\n.sidebar-resize-handle {\n touch-action: none;\n cursor: col-resize;\n\n position: absolute;\n z-index: 1;\n top: 0;\n right: -6px;\n bottom: 0;\n\n width: 12px;\n}\n\n.sidebar-resize-handle::before {\n content: '';\n\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n translate: -50%;\n\n width: 3px;\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n opacity: 0;\n background: var(--wui-color-accent, #0071e3);\n\n transition: opacity var(--wui-duration-feedback, 100ms) ease;\n}\n\n.sidebar-resize-handle:hover::before,\n.sidebar-resize-handle:focus-visible::before,\naside.is-resizing .sidebar-resize-handle::before {\n opacity: 1;\n}\n\n/*\n * 键盘 focus 同时给出两样东西:竖条与 hover / 拖拽同形,ring 与其余组件同一套浅蓝\n * 样式。竖条说明「命中条在哪」,ring 说明「键盘落点在哪」——handle 宽 12px 且通高,\n * 命中区远大于 3px 竖条本身,只靠竖条不足以说明焦点位置。\n *\n * ring 沿用 --wui-focus-ring-width / --wui-color-focus-ring 两个 token。圆角取\n * control token 后 outline 呈细长胶囊,与 button 的胶囊 ring 同一形状语言;offset\n * 2px 让 ring 骑在 aside 右缘内外两侧,不被 aside 裁掉。\n */\n.sidebar-resize-handle: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, #0071e3) 40%, transparent));\n outline-offset: 2px;\n}\n\n/* 拖拽中禁用宽度过渡,保证实时跟手。 */\naside.is-resizing {\n transition: none;\n}\n\n.layout-content {\n /*\n * 内容列的横向溢出由本层裁掉,避免撑出页面横向 scrollbar;它有 min-width: 0,\n * 是容纳横向溢出的位置。glow 伪元素已收在 header 盒内(见 header 的注释),\n * 不再依赖这层裁剪。\n *\n * clip 不创建滚动容器,因此不影响 header / footer 自身的 sticky;也不用 hidden——\n * 那会把本层变成滚动容器,sticky 随即失效。\n */\n overflow-x: clip;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-width: 0;\n}\n\nheader {\n /*\n * isolation: isolate 把负层级的 .wui-glow 伪元素限定在本 Header 的局部 stacking\n * context,slot 内容自然位于其上。晕染本身来自共享样式(src/classes/glow.css),\n * header-glow 属性负责挂 class。\n *\n * 「纵向必须 visible 才留得住模糊尾巴与下拉 overlay 的溢出空间」仍然成立——\n * overflow-* 一旦生效就会裁剪该轴,visible 是这些内容的唯一溢出出口。\n */\n isolation: isolate;\n position: sticky;\n z-index: var(--wui-layer-header, 100);\n top: 0;\n\n display: flex;\n gap: var(--wui-space-2, 8px);\n align-items: center;\n}\n\n/* 移动端 Toggle 属于组件自身,不随 Consumer 的 header 内边距缩进;\n 默认 8px 使其脱离视口边缘,Consumer 可用同名变量对齐自身内容左缘。 */\n.mobile-toggle {\n margin-left: var(--wui-layout-mobile-toggle-inset, 8px);\n}\n\nmain {\n flex: 1;\n}\n\nfooter {\n position: sticky;\n z-index: var(--wui-layer-tabbar, 400);\n bottom: 0;\n}\n\n@media (width <= 640px) {\n aside,\n .sidebar-wrapper {\n display: none;\n }\n\n /* Slot 可能包含展开后的多行 header;Toggle 对齐首行,而不是被整段 header 高度居中。 */\n header {\n align-items: flex-start;\n }\n\n .mobile-toggle {\n align-self: flex-start;\n margin-top: var(--wui-space-2, 8px);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n aside {\n transition: none;\n }\n\n .sidebar-resize-handle::before {\n transition: none;\n }\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
@@ -5,9 +5,9 @@ import overlay_motion_default from "../../assets/overlay-motion.js";
5
5
  import { dispatchOpenChangeEvent } from "../../shared/open-state/index.js";
6
6
  import { defineAnchoredPanel } from "../../shared/overlay/anchored-panel.js";
7
7
  import { defineOpenOverlay } from "../../shared/overlay/open-overlay.js";
8
+ import { FLOATING_PLACEMENTS } from "../../shared/overlay/placement-props.js";
8
9
  import { defineOverlayPortal } from "../../shared/overlay/portal.js";
9
10
  import { UserChangeController } from "../../shared/events/user-change.js";
10
- import { FLOATING_PLACEMENTS } from "../../shared/overlay/placement-props.js";
11
11
  import style_default from "./style.js";
12
12
  import { LitElement, html, unsafeCSS } from "lit";
13
13
  import { customElement, property } from "lit/decorators.js";
@@ -1,5 +1,5 @@
1
1
  // src/components/popover/style.css?inline
2
- var style_default = "*,:before,:after{box-sizing:border-box}:host{display:inline-flex}:host([disabled]){cursor:not-allowed}.popover-trigger{display:inline-flex}.popover-anchor{display:inline-flex;position:relative}.popover-panel{--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-glass-corner-radius:var(--wui-radius-menu,18px);--wui-color-glass-ring:transparent;z-index:var(--wui-layer-inline-overlay,1);box-sizing:border-box;width:max-content;max-width:min(90vw,400px);padding:var(--wui-space-2,8px) var(--wui-space-3,12px);border-radius:var(--wui-radius-menu,18px);font-size:var(--wui-font-size,14px);line-height:var(--wui-line-height-normal,1.5);color:var(--wui-color-text,#1b1b1b);background-color:var(--wui-color-surface-menu,#fafafac2);position:absolute;top:-9999px;left:-9999px}.popover-panel:where([hidden]){display:none}.popover-panel:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#0071e3) 40%, transparent));outline-offset:2px}.popover-panel.portal{z-index:var(--wui-layer-menu,100);position:fixed}:host([portal]) .popover-panel{display:none}\n";
2
+ var style_default = "*,:before,:after{box-sizing:border-box}:host{display:inline-flex}:host([disabled]){cursor:not-allowed}.popover-trigger{display:inline-flex}.popover-anchor{display:inline-flex;position:relative}.popover-panel{--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-glass-corner-radius:var(--wui-radius-menu,18px);--wui-color-glass-ring:transparent;z-index:var(--wui-layer-inline-overlay,10);box-sizing:border-box;width:max-content;max-width:min(90vw,400px);padding:var(--wui-space-2,8px) var(--wui-space-3,12px);border-radius:var(--wui-radius-menu,18px);font-size:var(--wui-font-size,14px);line-height:var(--wui-line-height-normal,1.5);color:var(--wui-color-text,#1b1b1b);background-color:var(--wui-color-surface-menu,#fafafac2);position:absolute;top:-9999px;left:-9999px}.popover-panel:where([hidden]){display:none}.popover-panel:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#0071e3) 40%, transparent));outline-offset:2px}.popover-panel.portal{z-index:var(--wui-layer-menu,1000);position:fixed}:host([portal]) .popover-panel{display:none}\n";
3
3
  export { style_default as default };
4
4
 
5
5
  //# sourceMappingURL=style.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/popover/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-flex;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.popover-trigger {\n display: inline-flex;\n}\n\n.popover-anchor {\n position: relative;\n display: inline-flex;\n}\n\n.popover-panel {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-glass-corner-radius: var(--wui-radius-menu, 18px);\n\n /* panel 宽远大于角半径,环底色铺出的整圈铺底会在长边中段读成一条比四角更重的\n 直边描边;转 transparent 后只剩四段角弧,见 menu-portal.css 同处注释。 */\n --wui-color-glass-ring: transparent;\n position: absolute;\n z-index: var(--wui-layer-inline-overlay, 1);\n top: -9999px;\n left: -9999px;\n\n box-sizing: border-box;\n width: max-content;\n max-width: min(90vw, 400px);\n padding: var(--wui-space-2, 8px) var(--wui-space-3, 12px);\n border-radius: var(--wui-radius-menu, 18px);\n\n font-size: var(--wui-font-size, 14px);\n line-height: var(--wui-line-height-normal, 1.5);\n color: var(--wui-color-text, #1b1b1b);\n\n /* 玻璃背景:wui-glass 在 panel 自身,这里覆盖其默认玻璃底为 menu surface 色 */\n background-color: var(--wui-color-surface-menu, rgb(250 250 250 / 0.76));\n\n &:where([hidden]) {\n display: none;\n }\n\n &:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #0071e3) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n.popover-panel.portal {\n position: fixed;\n z-index: var(--wui-layer-menu, 100);\n}\n\n:host([portal]) .popover-panel {\n display: none;\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
1
+ {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/popover/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-flex;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.popover-trigger {\n display: inline-flex;\n}\n\n.popover-anchor {\n position: relative;\n display: inline-flex;\n}\n\n.popover-panel {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-glass-corner-radius: var(--wui-radius-menu, 18px);\n\n /* panel 宽远大于角半径,环底色铺出的整圈铺底会在长边中段读成一条比四角更重的\n 直边描边;转 transparent 后只剩四段角弧,见 menu-portal.css 同处注释。 */\n --wui-color-glass-ring: transparent;\n position: absolute;\n z-index: var(--wui-layer-inline-overlay, 10);\n top: -9999px;\n left: -9999px;\n\n box-sizing: border-box;\n width: max-content;\n max-width: min(90vw, 400px);\n padding: var(--wui-space-2, 8px) var(--wui-space-3, 12px);\n border-radius: var(--wui-radius-menu, 18px);\n\n font-size: var(--wui-font-size, 14px);\n line-height: var(--wui-line-height-normal, 1.5);\n color: var(--wui-color-text, #1b1b1b);\n\n /* 玻璃背景:wui-glass 在 panel 自身,这里覆盖其默认玻璃底为 menu surface 色 */\n background-color: var(--wui-color-surface-menu, rgb(250 250 250 / 0.76));\n\n &:where([hidden]) {\n display: none;\n }\n\n &:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #0071e3) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n.popover-panel.portal {\n position: fixed;\n z-index: var(--wui-layer-menu, 1000);\n}\n\n:host([portal]) .popover-panel {\n display: none;\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
@@ -0,0 +1,30 @@
1
+ import { LitElement } from "lit";
2
+ /**
3
+ * 线性进度指示。宿主本身承担 `progressbar` 语义,numeric props 写入后始终按 `0..max` 暴露。
4
+ *
5
+ * @csspart base - 轨道与可选数值组成的网格
6
+ * @csspart track - 进度槽
7
+ * @csspart indicator - 已完成部分
8
+ * @csspart value - `show-value` 时的可见百分比文本
9
+ */
10
+ export declare class WebUiProgress extends LitElement {
11
+ static styles: import("lit").CSSResult;
12
+ set value(value: number);
13
+ get value(): number;
14
+ private _value;
15
+ set max(value: number);
16
+ get max(): number;
17
+ private _max;
18
+ indeterminate: boolean;
19
+ showValue: boolean;
20
+ connectedCallback(): void;
21
+ protected updated(): void;
22
+ private _syncAria;
23
+ render(): import("lit").TemplateResult<1>;
24
+ }
25
+ declare global {
26
+ interface HTMLElementTagNameMap {
27
+ 'web-ui-progress': WebUiProgress;
28
+ }
29
+ }
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/progress/index.ts"],"mappings":";;;;;;;;;qBAoBa,sBAAsB;SACjB,sBAAM;MAGlB,MAAM;MAWN;UAII;MAGJ,IAAI;MAYJ;UAII;EAEoC;EACyB;EAE5D;YAKU;UAUX;EAgBC,wBAAM;;QAqBT;YACI;IACR,mBAAmB"}
@@ -0,0 +1,103 @@
1
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
2
+ import { normalizeNumber } from "../../shared/normalize/index.js";
3
+ import { resolveBuiltinLabel } from "../../shared/locale/builtin-labels.js";
4
+ import style_default from "./style.js";
5
+ import { LitElement, html, unsafeCSS } from "lit";
6
+ import { customElement, property } from "lit/decorators.js";
7
+ import { styleMap } from "lit/directives/style-map.js";
8
+ // src/components/progress/index.ts
9
+ const MAX_SAFE = Number.MAX_SAFE_INTEGER;
10
+ let WebUiProgress = class WebUiProgress extends LitElement {
11
+ constructor(..._args) {
12
+ super(..._args);
13
+ this._value = 0;
14
+ this._max = 100;
15
+ this.indeterminate = false;
16
+ this.showValue = false;
17
+ }
18
+ static {
19
+ this.styles = unsafeCSS(style_default);
20
+ }
21
+ set value(value) {
22
+ const normalized = normalizeNumber(value, 0, MAX_SAFE, 0);
23
+ if (this._value === normalized) return;
24
+ const old = this.value;
25
+ this._value = normalized;
26
+ this.requestUpdate("value", old);
27
+ if (this.getAttribute("value") !== String(normalized)) this.setAttribute("value", String(normalized));
28
+ }
29
+ get value() {
30
+ return Math.min(this._value, this._max);
31
+ }
32
+ set max(value) {
33
+ const normalized = typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.min(MAX_SAFE, value) : 100;
34
+ if (this._max === normalized) return;
35
+ const old = this._max;
36
+ this._max = normalized;
37
+ this.requestUpdate("max", old);
38
+ if (this.getAttribute("max") !== String(normalized)) this.setAttribute("max", String(normalized));
39
+ }
40
+ get max() {
41
+ return this._max;
42
+ }
43
+ connectedCallback() {
44
+ super.connectedCallback();
45
+ this._syncAria();
46
+ }
47
+ updated() {
48
+ if (this._value > this._max) {
49
+ const old = this._value;
50
+ this._value = this._max;
51
+ this.requestUpdate("value", old);
52
+ this.setAttribute("value", String(this._max));
53
+ }
54
+ this._syncAria();
55
+ }
56
+ _syncAria() {
57
+ this.setAttribute("role", "progressbar");
58
+ this.setAttribute("aria-valuemin", "0");
59
+ this.setAttribute("aria-valuemax", String(this.max));
60
+ if (this.indeterminate) this.removeAttribute("aria-valuenow");
61
+ else this.setAttribute("aria-valuenow", String(this.value));
62
+ if (!this.getAttribute("aria-label")?.trim() && !this.getAttribute("aria-labelledby")?.trim()) this.setAttribute("aria-label", resolveBuiltinLabel("progress"));
63
+ }
64
+ render() {
65
+ const percent = this.value / this.max * 100;
66
+ const valueText = this.indeterminate ? "…" : `${Math.round(percent)}%`;
67
+ return html`
68
+ <div class="wui-progress" part="base">
69
+ <div class="wui-progress-track" part="track">
70
+ <div
71
+ class="wui-progress-indicator"
72
+ part="indicator"
73
+ style=${styleMap({ "--wui-progress-percent": `${percent}%` })}
74
+ ></div>
75
+ </div>
76
+ <span class="wui-progress-value" part="value" aria-hidden="true" ?hidden=${!this.showValue}>
77
+ ${valueText}
78
+ </span>
79
+ </div>
80
+ `;
81
+ }
82
+ };
83
+ __decorate([property({
84
+ type: Number,
85
+ reflect: true
86
+ })], WebUiProgress.prototype, "value", null);
87
+ __decorate([property({
88
+ type: Number,
89
+ reflect: true
90
+ })], WebUiProgress.prototype, "max", null);
91
+ __decorate([property({
92
+ type: Boolean,
93
+ reflect: true
94
+ })], WebUiProgress.prototype, "indeterminate", void 0);
95
+ __decorate([property({
96
+ type: Boolean,
97
+ reflect: true,
98
+ attribute: "show-value"
99
+ })], WebUiProgress.prototype, "showValue", void 0);
100
+ WebUiProgress = __decorate([customElement("web-ui-progress")], WebUiProgress);
101
+ export { WebUiProgress };
102
+
103
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["style"],"sources":["../../../src/components/progress/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { styleMap } from 'lit/directives/style-map.js'\n\nimport { resolveBuiltinLabel } from '@/shared/locale/builtin-labels'\nimport { normalizeNumber } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\nconst MAX_SAFE = Number.MAX_SAFE_INTEGER\n\n/**\n * 线性进度指示。宿主本身承担 `progressbar` 语义,numeric props 写入后始终按 `0..max` 暴露。\n *\n * @csspart base - 轨道与可选数值组成的网格\n * @csspart track - 进度槽\n * @csspart indicator - 已完成部分\n * @csspart value - `show-value` 时的可见百分比文本\n */\n@customElement('web-ui-progress')\nexport class WebUiProgress extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: Number, reflect: true })\n set value(value: number) {\n const normalized = normalizeNumber(value, 0, MAX_SAFE, 0)\n if (this._value === normalized) return\n const old = this.value\n this._value = normalized\n this.requestUpdate('value', old)\n if (this.getAttribute('value') !== String(normalized)) {\n this.setAttribute('value', String(normalized))\n }\n }\n\n get value(): number {\n return Math.min(this._value, this._max)\n }\n\n private _value = 0\n\n @property({ type: Number, reflect: true })\n set max(value: number) {\n const normalized =\n typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.min(MAX_SAFE, value) : 100\n if (this._max === normalized) return\n const old = this._max\n this._max = normalized\n this.requestUpdate('max', old)\n if (this.getAttribute('max') !== String(normalized)) {\n this.setAttribute('max', String(normalized))\n }\n }\n\n get max(): number {\n return this._max\n }\n\n private _max = 100\n\n @property({ type: Boolean, reflect: true }) indeterminate = false\n @property({ type: Boolean, reflect: true, attribute: 'show-value' }) showValue = false\n\n override connectedCallback() {\n super.connectedCallback()\n this._syncAria()\n }\n\n protected override updated() {\n if (this._value > this._max) {\n const old = this._value\n this._value = this._max\n this.requestUpdate('value', old)\n this.setAttribute('value', String(this._max))\n }\n this._syncAria()\n }\n\n private _syncAria() {\n this.setAttribute('role', 'progressbar')\n this.setAttribute('aria-valuemin', '0')\n this.setAttribute('aria-valuemax', String(this.max))\n\n if (this.indeterminate) {\n this.removeAttribute('aria-valuenow')\n } else {\n this.setAttribute('aria-valuenow', String(this.value))\n }\n\n if (!this.getAttribute('aria-label')?.trim() && !this.getAttribute('aria-labelledby')?.trim()) {\n this.setAttribute('aria-label', resolveBuiltinLabel('progress'))\n }\n }\n\n override render() {\n const percent = (this.value / this.max) * 100\n const valueText = this.indeterminate ? '…' : `${Math.round(percent)}%`\n\n return html`\n <div class=\"wui-progress\" part=\"base\">\n <div class=\"wui-progress-track\" part=\"track\">\n <div\n class=\"wui-progress-indicator\"\n part=\"indicator\"\n style=${styleMap({ '--wui-progress-percent': `${percent}%` })}\n ></div>\n </div>\n <span class=\"wui-progress-value\" part=\"value\" aria-hidden=\"true\" ?hidden=${!this.showValue}>\n ${valueText}\n </span>\n </div>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-progress': WebUiProgress\n }\n}\n"],"mappings":";;;;;;;;AASA,MAAM,WAAW,OAAO;AAWjB,IAAM,gBAAN,MAAM,sBAAsB,WAAW;;;EAmB3B,KAAA,SAAA;EAmBF,KAAA,OAAA;EAE6C,KAAA,gBAAA;EACqB,KAAA,YAAA;;;EAxCxD,KAAA,SAAA,UAAUA,aAAK;;CAExC,IACI,MAAM,OAAe;EACvB,MAAM,aAAa,gBAAgB,OAAO,GAAG,UAAU,CAAC;EACxD,IAAI,KAAK,WAAW,YAAY;EAChC,MAAM,MAAM,KAAK;EACjB,KAAK,SAAS;EACd,KAAK,cAAc,SAAS,GAAG;EAC/B,IAAI,KAAK,aAAa,OAAO,MAAM,OAAO,UAAU,GAClD,KAAK,aAAa,SAAS,OAAO,UAAU,CAAC;CAEjD;CAEA,IAAI,QAAgB;EAClB,OAAO,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI;CACxC;CAIA,IACI,IAAI,OAAe;EACrB,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,UAAU,KAAK,IAAI;EACjG,IAAI,KAAK,SAAS,YAAY;EAC9B,MAAM,MAAM,KAAK;EACjB,KAAK,OAAO;EACZ,KAAK,cAAc,OAAO,GAAG;EAC7B,IAAI,KAAK,aAAa,KAAK,MAAM,OAAO,UAAU,GAChD,KAAK,aAAa,OAAO,OAAO,UAAU,CAAC;CAE/C;CAEA,IAAI,MAAc;EAChB,OAAO,KAAK;CACd;CAOA,oBAA6B;EAC3B,MAAM,kBAAkB;EACxB,KAAK,UAAU;CACjB;CAEA,UAA6B;EAC3B,IAAI,KAAK,SAAS,KAAK,MAAM;GAC3B,MAAM,MAAM,KAAK;GACjB,KAAK,SAAS,KAAK;GACnB,KAAK,cAAc,SAAS,GAAG;GAC/B,KAAK,aAAa,SAAS,OAAO,KAAK,IAAI,CAAC;EAC9C;EACA,KAAK,UAAU;CACjB;CAEA,YAAoB;EAClB,KAAK,aAAa,QAAQ,aAAa;EACvC,KAAK,aAAa,iBAAiB,GAAG;EACtC,KAAK,aAAa,iBAAiB,OAAO,KAAK,GAAG,CAAC;EAEnD,IAAI,KAAK,eACP,KAAK,gBAAgB,eAAe;OAEpC,KAAK,aAAa,iBAAiB,OAAO,KAAK,KAAK,CAAC;EAGvD,IAAI,CAAC,KAAK,aAAa,YAAY,CAAC,EAAE,KAAK,KAAK,CAAC,KAAK,aAAa,iBAAiB,CAAC,EAAE,KAAK,GAC1F,KAAK,aAAa,cAAc,oBAAoB,UAAU,CAAC;CAEnE;CAEA,SAAkB;EAChB,MAAM,UAAW,KAAK,QAAQ,KAAK,MAAO;EAC1C,MAAM,YAAY,KAAK,gBAAgB,MAAM,GAAG,KAAK,MAAM,OAAO,EAAE;EAEpE,OAAO,IAAI;;;;;;oBAMK,SAAS,EAAE,0BAA0B,GAAG,QAAQ,GAAG,CAAC,EAAE;;;mFAGS,CAAC,KAAK,UAAU;YACvF,UAAU;;;;CAIpB;AACF;AA1FG,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,SAAA,IAAA;AAkBxC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,OAAA,IAAA;AAmBxC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,iBAAA,KAAA,CAAA;AACzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,WAAW;AAAa,CAAC,CAAA,GAAA,cAAA,WAAA,aAAA,KAAA,CAAA;AA1CpE,gBAAA,WAAA,CAAA,cAAc,iBAAiB,CAAA,GAAA,aAAA"}
@@ -0,0 +1,5 @@
1
+ // src/components/progress/style.css?inline
2
+ var style_default = "*,:before,:after{box-sizing:border-box}:host{width:100%;min-width:0;display:block}.wui-progress{gap:var(--wui-space-2,8px);grid-template-columns:minmax(0,1fr) auto;align-items:center;display:grid}.wui-progress-track{width:100%;height:var(--wui-progress-height,8px);border-radius:var(--wui-progress-radius,var(--wui-radius-control,calc(infinity * 1px)));background-color:var(--wui-progress-track-color,var(--wui-color-surface-track,#e5e5ea));overflow:hidden}.wui-progress-indicator{width:var(--wui-progress-percent,0%);border-radius:inherit;background-color:var(--wui-progress-fill-color,var(--wui-color-accent,#0071e3));height:100%;transition:width var(--wui-duration-trigger,.16s) var(--wui-ease-enter,cubic-bezier(.23, 1, .32, 1))}:host([indeterminate]) .wui-progress-indicator{width:38%;animation:wui-progress-indeterminate var(--wui-progress-indeterminate-duration,var(--wui-duration-spinner,.8s)) var(--wui-ease-enter,cubic-bezier(.23, 1, .32, 1)) infinite}.wui-progress-value{min-width:3ch;font-size:var(--wui-font-size-caption,12px);font-variant-numeric:tabular-nums;color:var(--wui-color-text,#1b1b1b);text-align:end;line-height:1}@keyframes wui-progress-indeterminate{0%{transform:translate(-120%)}to{transform:translate(360%)}}\n";
3
+ export { style_default as default };
4
+
5
+ //# sourceMappingURL=style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/progress/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n width: 100%;\n min-width: 0;\n}\n\n.wui-progress {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n gap: var(--wui-space-2, 8px);\n align-items: center;\n}\n\n.wui-progress-track {\n overflow: hidden;\n\n width: 100%;\n height: var(--wui-progress-height, 8px);\n border-radius: var(--wui-progress-radius, var(--wui-radius-control, calc(infinity * 1px)));\n\n background-color: var(--wui-progress-track-color, var(--wui-color-surface-track, #e5e5ea));\n}\n\n.wui-progress-indicator {\n width: var(--wui-progress-percent, 0%);\n height: 100%;\n border-radius: inherit;\n\n background-color: var(--wui-progress-fill-color, var(--wui-color-accent, #0071e3));\n\n transition: width var(--wui-duration-trigger, 160ms) var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1));\n}\n\n:host([indeterminate]) .wui-progress-indicator {\n width: 38%;\n animation: wui-progress-indeterminate var(--wui-progress-indeterminate-duration, var(--wui-duration-spinner, 800ms))\n var(--wui-ease-enter, cubic-bezier(0.23, 1, 0.32, 1)) infinite;\n}\n\n.wui-progress-value {\n min-width: 3ch;\n\n font-size: var(--wui-font-size-caption, 12px);\n font-variant-numeric: tabular-nums;\n line-height: 1;\n color: var(--wui-color-text, #1b1b1b);\n text-align: end;\n}\n\n@keyframes wui-progress-indeterminate {\n from {\n transform: translate3d(-120%, 0, 0);\n }\n\n to {\n transform: translate3d(360%, 0, 0);\n }\n}\n"],"mappings":";AAAA,IAAA,gBAAA"}
@@ -4,6 +4,8 @@ export declare class WebUiSegmentedTrigger extends LitElement {
4
4
  value: string;
5
5
  checked: boolean;
6
6
  disabled: boolean;
7
+ /** 纯图标 trigger 的可访问名;会转发到内部 `role="option"`。 */
8
+ ariaLabel: string | null;
7
9
  private readonly _groupManagement;
8
10
  private get _isDisabled();
9
11
  private get _isManagedByGroup();
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/segmented-trigger/index.ts"],"mappings":";qBAYa,8BAA8B;SACzB,sBAAM;EAEM;EACgB;EACA;mBAE3B;cAML;cAIA;UAIJ;UAUA;EAOC,wBAAM;WAsBE;IACf,QAAQ;;;QAIJ;YACI;IACR,4BAA4B"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/segmented-trigger/index.ts"],"mappings":";qBAaa,8BAA8B;SACzB,sBAAM;EAEM;EACgB;EACA;;EAEkB;mBAE7C;cAML;cAIA;UAIJ;UAUA;EAOC,wBAAM;WAuBE;IACf,QAAQ;;;QAIJ;YACI;IACR,4BAA4B"}
@@ -5,6 +5,7 @@ import style_default from "./style.js";
5
5
  import { LitElement, html, unsafeCSS } from "lit";
6
6
  import { customElement, property } from "lit/decorators.js";
7
7
  import { classMap } from "lit/directives/class-map.js";
8
+ import { ifDefined } from "lit/directives/if-defined.js";
8
9
  // src/components/segmented-trigger/index.ts
9
10
  installPointerFocusSuppression();
10
11
  let WebUiSegmentedTrigger = class WebUiSegmentedTrigger extends LitElement {
@@ -13,6 +14,7 @@ let WebUiSegmentedTrigger = class WebUiSegmentedTrigger extends LitElement {
13
14
  this.value = "";
14
15
  this.checked = false;
15
16
  this.disabled = false;
17
+ this.ariaLabel = null;
16
18
  this._groupManagement = defineGroupManaged(this, {
17
19
  context: selectionGroupContextKey,
18
20
  requestUpdate: () => this.requestUpdate(),
@@ -57,6 +59,7 @@ let WebUiSegmentedTrigger = class WebUiSegmentedTrigger extends LitElement {
57
59
  class=${classMap(cls)}
58
60
  tabindex=${this._isDisabled || this._groupManagement.getContext()?.tabStop === false ? "-1" : "0"}
59
61
  role="option"
62
+ aria-label=${ifDefined(this.ariaLabel ?? void 0)}
60
63
  aria-selected=${String(this.checked)}
61
64
  aria-disabled=${String(this._isDisabled)}
62
65
  @click=${this.handleClick}
@@ -76,6 +79,10 @@ __decorate([property({
76
79
  type: Boolean,
77
80
  reflect: true
78
81
  })], WebUiSegmentedTrigger.prototype, "disabled", void 0);
82
+ __decorate([property({
83
+ type: String,
84
+ attribute: "aria-label"
85
+ })], WebUiSegmentedTrigger.prototype, "ariaLabel", void 0);
79
86
  WebUiSegmentedTrigger = __decorate([customElement("web-ui-segmented-trigger")], WebUiSegmentedTrigger);
80
87
  export { WebUiSegmentedTrigger };
81
88
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["style"],"sources":["../../../src/components/segmented-trigger/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { defineGroupManaged, selectionGroupContextKey, type SelectionGroupContext } from '@/shared/group-management'\n\nimport style from './style.css?inline'\n\ninstallPointerFocusSuppression()\n\n@customElement('web-ui-segmented-trigger')\nexport class WebUiSegmentedTrigger extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: String }) value = ''\n @property({ type: Boolean, reflect: true }) checked = false\n @property({ type: Boolean, reflect: true }) disabled = false\n\n private readonly _groupManagement = defineGroupManaged<SelectionGroupContext>(this, {\n context: selectionGroupContextKey,\n requestUpdate: () => this.requestUpdate(),\n equals: (a, b) => a?.disabled === b?.disabled && a?.tabStop === b?.tabStop\n }).make()\n\n private get _isDisabled(): boolean {\n return this.disabled || this._groupManagement.getContext()?.disabled === true\n }\n\n private get _isManagedByGroup(): boolean {\n return this._groupManagement.getContext() !== undefined\n }\n\n private handleClick() {\n if (this._isDisabled || this.checked) return\n this.checked = true\n // group-managed 时事件不冒泡/不组合,由 segmented 统一派发一次 host 事件\n const opts: EventInit = this._isManagedByGroup\n ? { bubbles: false, composed: false }\n : { bubbles: true, composed: true }\n this.dispatchEvent(new Event('change', opts))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-segmented-trigger': true,\n 'is-checked': this.checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <div\n class=${classMap(cls)}\n tabindex=${this._isDisabled || this._groupManagement.getContext()?.tabStop === false ? '-1' : '0'}\n role=\"option\"\n aria-selected=${String(this.checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented-trigger': WebUiSegmentedTrigger\n }\n}\n"],"mappings":";;;;;;;;AASA,+BAA+B;AAGxB,IAAM,wBAAN,MAAM,8BAA8B,WAAW;;;EAGhB,KAAA,QAAA;EACkB,KAAA,UAAA;EACC,KAAA,WAAA;EAEnB,KAAA,mBAAA,mBAA0C,MAAM;GAClF,SAAS;GACT,qBAAqB,KAAK,cAAc;GACxC,SAAS,GAAG,MAAM,GAAG,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG;EACrE,CAAC,CAAC,CAAC,KAAK;;;EAViB,KAAA,SAAA,UAAUA,aAAK;;CAYxC,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK,iBAAiB,WAAW,CAAC,EAAE,aAAa;CAC3E;CAEA,IAAY,oBAA6B;EACvC,OAAO,KAAK,iBAAiB,WAAW,MAAM,KAAA;CAChD;CAEA,cAAsB;EACpB,IAAI,KAAK,eAAe,KAAK,SAAS;EACtC,KAAK,UAAU;EAEf,MAAM,OAAkB,KAAK,oBACzB;GAAE,SAAS;GAAO,UAAU;EAAM,IAClC;GAAE,SAAS;GAAM,UAAU;EAAK;EACpC,KAAK,cAAc,IAAI,MAAM,UAAU,IAAI,CAAC;CAC9C;CAEA,cAAsB,GAAkB;EACtC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;GACtC,EAAE,eAAe;GACjB,KAAK,YAAY;EACnB;CACF;CAEA,SAAkB;EAChB,MAAM,MAAM;GACV,yBAAyB;GACzB,cAAc,KAAK;GACnB,eAAe,KAAK;EACtB;EAEA,OAAO,IAAI;;gBAEC,SAAS,GAAG,EAAE;mBACX,KAAK,eAAe,KAAK,iBAAiB,WAAW,CAAC,EAAE,YAAY,QAAQ,OAAO,IAAI;;wBAElF,OAAO,KAAK,OAAO,EAAE;wBACrB,OAAO,KAAK,WAAW,EAAE;iBAChC,KAAK,YAAY;mBACf,KAAK,cAAc;;;;;CAKpC;AAKF;AA5DG,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,sBAAA,WAAA,SAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,sBAAA,WAAA,WAAA,KAAA,CAAA;AACzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,sBAAA,WAAA,YAAA,KAAA,CAAA;AAN3C,wBAAA,WAAA,CAAA,cAAc,0BAA0B,CAAA,GAAA,qBAAA"}
1
+ {"version":3,"file":"index.js","names":["style"],"sources":["../../../src/components/segmented-trigger/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { defineGroupManaged, selectionGroupContextKey, type SelectionGroupContext } from '@/shared/group-management'\n\nimport style from './style.css?inline'\n\ninstallPointerFocusSuppression()\n\n@customElement('web-ui-segmented-trigger')\nexport class WebUiSegmentedTrigger extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: String }) value = ''\n @property({ type: Boolean, reflect: true }) checked = false\n @property({ type: Boolean, reflect: true }) disabled = false\n /** 纯图标 trigger 的可访问名;会转发到内部 `role=\"option\"`。 */\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n\n private readonly _groupManagement = defineGroupManaged<SelectionGroupContext>(this, {\n context: selectionGroupContextKey,\n requestUpdate: () => this.requestUpdate(),\n equals: (a, b) => a?.disabled === b?.disabled && a?.tabStop === b?.tabStop\n }).make()\n\n private get _isDisabled(): boolean {\n return this.disabled || this._groupManagement.getContext()?.disabled === true\n }\n\n private get _isManagedByGroup(): boolean {\n return this._groupManagement.getContext() !== undefined\n }\n\n private handleClick() {\n if (this._isDisabled || this.checked) return\n this.checked = true\n // group-managed 时事件不冒泡/不组合,由 segmented 统一派发一次 host 事件\n const opts: EventInit = this._isManagedByGroup\n ? { bubbles: false, composed: false }\n : { bubbles: true, composed: true }\n this.dispatchEvent(new Event('change', opts))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-segmented-trigger': true,\n 'is-checked': this.checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <div\n class=${classMap(cls)}\n tabindex=${this._isDisabled || this._groupManagement.getContext()?.tabStop === false ? '-1' : '0'}\n role=\"option\"\n aria-label=${ifDefined(this.ariaLabel ?? undefined)}\n aria-selected=${String(this.checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented-trigger': WebUiSegmentedTrigger\n }\n}\n"],"mappings":";;;;;;;;;AAUA,+BAA+B;AAGxB,IAAM,wBAAN,MAAM,8BAA8B,WAAW;;;EAGhB,KAAA,QAAA;EACkB,KAAA,UAAA;EACC,KAAA,WAAA;EAEkC,KAAA,YAAA;EAErD,KAAA,mBAAA,mBAA0C,MAAM;GAClF,SAAS;GACT,qBAAqB,KAAK,cAAc;GACxC,SAAS,GAAG,MAAM,GAAG,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG;EACrE,CAAC,CAAC,CAAC,KAAK;;;EAZiB,KAAA,SAAA,UAAUA,aAAK;;CAcxC,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK,iBAAiB,WAAW,CAAC,EAAE,aAAa;CAC3E;CAEA,IAAY,oBAA6B;EACvC,OAAO,KAAK,iBAAiB,WAAW,MAAM,KAAA;CAChD;CAEA,cAAsB;EACpB,IAAI,KAAK,eAAe,KAAK,SAAS;EACtC,KAAK,UAAU;EAEf,MAAM,OAAkB,KAAK,oBACzB;GAAE,SAAS;GAAO,UAAU;EAAM,IAClC;GAAE,SAAS;GAAM,UAAU;EAAK;EACpC,KAAK,cAAc,IAAI,MAAM,UAAU,IAAI,CAAC;CAC9C;CAEA,cAAsB,GAAkB;EACtC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;GACtC,EAAE,eAAe;GACjB,KAAK,YAAY;EACnB;CACF;CAEA,SAAkB;EAChB,MAAM,MAAM;GACV,yBAAyB;GACzB,cAAc,KAAK;GACnB,eAAe,KAAK;EACtB;EAEA,OAAO,IAAI;;gBAEC,SAAS,GAAG,EAAE;mBACX,KAAK,eAAe,KAAK,iBAAiB,WAAW,CAAC,EAAE,YAAY,QAAQ,OAAO,IAAI;;qBAErF,UAAU,KAAK,aAAa,KAAA,CAAS,EAAE;wBACpC,OAAO,KAAK,OAAO,EAAE;wBACrB,OAAO,KAAK,WAAW,EAAE;iBAChC,KAAK,YAAY;mBACf,KAAK,cAAc;;;;;CAKpC;AAKF;AA/DG,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,sBAAA,WAAA,SAAA,KAAA,CAAA;AACzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,sBAAA,WAAA,WAAA,KAAA,CAAA;AACzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,sBAAA,WAAA,YAAA,KAAA,CAAA;AAEzC,WAAA,CAAA,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAa,CAAC,CAAA,GAAA,sBAAA,WAAA,aAAA,KAAA,CAAA;AARpD,wBAAA,WAAA,CAAA,cAAc,0BAA0B,CAAA,GAAA,qBAAA"}
@@ -1,6 +1,7 @@
1
1
  import "../icon/index.js";
2
2
  import { OverlayContainer } from "../../shared/overlay/portal.js";
3
3
  import { LitElement, PropertyValues } from "lit";
4
+ import { Placement } from "@floating-ui/dom";
4
5
  declare const WebUiSelect_base: {
5
6
  new (...args: any[]): {
6
7
  formResetCallback(): void;
@@ -369,8 +370,20 @@ export declare class WebUiSelect extends WebUiSelect_base {
369
370
  static styles: import("lit").CSSResult[];
370
371
  placeholder: string;
371
372
  disabled: boolean;
373
+ /**
374
+ * 触发器外观:`label` 为默认的带选中文本与箭头;`icon` 保留右侧箭头,只把 `trigger` slot
375
+ * 的内容换成左侧图标区——带 trigger slot 时触发器贴合内容宽度,高度不变。
376
+ * 图标模式需要消费方提供 `trigger` slot 与 `aria-label`。
377
+ */
378
+ get trigger(): 'label' | 'icon';
379
+ set trigger(v: string);
380
+ private _trigger;
372
381
  required: boolean;
373
382
  portal: boolean;
383
+ /** 下拉 panel 相对触发器的方向;默认贴着触发器左下角向下展开。 */
384
+ get placement(): Placement;
385
+ set placement(v: string);
386
+ private _placement;
374
387
  noScrollLock: boolean;
375
388
  overlayContainer?: OverlayContainer;
376
389
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/select/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAoCa,oBAAoB;SACf,sBAAM;EAEqB;EACC;EACA;EACA;EAC6B;EACzC,mBAAmB;EACR;EAGmB;UAI7C;MAEb;MAGA,MAAM;mBAQO;mBAsBA;cAEL;UAIK;UACA;UACA;UACA;UAET;UACA;UAEA;UACA;UACA;mBACS;iBAEF;mBAGE;mBA0BA;mBAIA;MAeb;MAIA;UAII;UAQA;EASC;EAQA;EAgBA;EAMA;EAKA,QAAQ,SAAS;UASlB;UAOA;UASA;UAIA;UAQA;mBAgBS;UAOT;UACA;UAEA;UAWA;UASA;UAKA;UAUA;UAMA;UAMA;UAKA;UAqDA;UASA;UAUA;UAyCA;UAIA;mBAwBS;UAsBT;UAKA;UAKA;UAKA;UAIA;UASA;UAMA;UAKA;UAIA;UAMA;UAMA;UA8BA;UAaM;EASL,wBAAM;WAuCE;IACf,OAAO;IACP,QAAQ;IACR,eAAe;MAAc;;;;QAIzB;YACI;IACR,iBAAiB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/select/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAuCa,oBAAoB;SACf,sBAAM;EAEqB;EACC;;;;;;MAQxC;MAGA,QAAQ;UAKJ;EACoC;EACA;;MAGxC,aAAa;MAGb,UAAU;UAKN;EACiE;EACzC,mBAAmB;EACR;EAGmB;UAI7C;MAEb;MAGA,MAAM;mBAQO;mBAsBA;cAEL;UAIK;UACA;UACA;UACA;UAET;UACA;UAEA;UACA;UACA;mBACS;iBAEF;mBAGE;mBA0BA;mBAIA;MAeb;MAIA;UAII;UAQA;EASC;EAQA;EAgBA;EAMA;EAKA,QAAQ,SAAS;UAUlB;UAOA;UASA;UAIA;UAQA;mBAgBS;UAOT;UACA;UAEA;UAWA;UASA;UAKA;UAUA;UAMA;UAMA;UAKA;UAqDA;UASA;UAUA;UAyCA;UAIA;mBAwBS;UAsBT;UAKA;UAKA;UAKA;UAIA;UASA;UAMA;UAKA;UAIA;UAMA;UAMA;UA8BA;UAaM;EASL,wBAAM;WA0CE;IACf,OAAO;IACP,QAAQ;IACR,eAAe;MAAc;;;;QAIzB;YACI;IACR,iBAAiB"}
@@ -4,6 +4,7 @@ import glass_default from "../../classes/glass.js";
4
4
  import lucide_chevron_down_default from "../../icons/generated/lucide-chevron-down.js";
5
5
  import { installPointerFocusSuppression } from "../../shared/focus/pointer-focus.js";
6
6
  import { FormAssociated, FormAssociationController, defineFormAssociation } from "../../shared/form-association/index.js";
7
+ import { normalizeLiteral } from "../../shared/normalize/index.js";
7
8
  import overlay_motion_default from "../../assets/overlay-motion.js";
8
9
  import scrollbar_default from "../../assets/scrollbar.js";
9
10
  import { dispatchOpenChangeEvent } from "../../shared/open-state/index.js";
@@ -11,6 +12,7 @@ import { createComboboxOpenController, createOptionListenerBinding, handleCombob
11
12
  import { defineOptionPortal } from "../../shared/option-portal/index.js";
12
13
  import { defineAnchoredPanel } from "../../shared/overlay/anchored-panel.js";
13
14
  import { defineOpenOverlay } from "../../shared/overlay/open-overlay.js";
15
+ import { FLOATING_PLACEMENTS } from "../../shared/overlay/placement-props.js";
14
16
  import { applyOverlayVariables, defineOverlayPortal } from "../../shared/overlay/portal.js";
15
17
  import { defineScrollLockLease } from "../../shared/scroll-lock/scroll-lock.js";
16
18
  import style_default from "./style.js";
@@ -28,8 +30,10 @@ let WebUiSelect = class WebUiSelect extends FormAssociated(LitElement) {
28
30
  super(..._args);
29
31
  this.placeholder = "";
30
32
  this.disabled = false;
33
+ this._trigger = "label";
31
34
  this.required = false;
32
35
  this.portal = false;
36
+ this._placement = "bottom-start";
33
37
  this.noScrollLock = false;
34
38
  this.name = "";
35
39
  this.ariaLabel = null;
@@ -88,7 +92,7 @@ let WebUiSelect = class WebUiSelect extends FormAssociated(LitElement) {
88
92
  getAnchor: () => this.shadowRoot?.querySelector(".select-trigger") ?? null,
89
93
  getLocalPanel: () => this.shadowRoot?.querySelector(".select-overlay") ?? null,
90
94
  getPositioning: () => ({
91
- placement: "bottom-start",
95
+ placement: this.placement,
92
96
  offset: 4,
93
97
  minAnchorWidth: true,
94
98
  strategy: this.portal ? "fixed" : "absolute"
@@ -216,6 +220,28 @@ let WebUiSelect = class WebUiSelect extends FormAssociated(LitElement) {
216
220
  unsafeCSS(style_default)
217
221
  ];
218
222
  }
223
+ /**
224
+ * 触发器外观:`label` 为默认的带选中文本与箭头;`icon` 保留右侧箭头,只把 `trigger` slot
225
+ * 的内容换成左侧图标区——带 trigger slot 时触发器贴合内容宽度,高度不变。
226
+ * 图标模式需要消费方提供 `trigger` slot 与 `aria-label`。
227
+ */
228
+ get trigger() {
229
+ return this._trigger;
230
+ }
231
+ set trigger(v) {
232
+ const old = this._trigger;
233
+ this._trigger = normalizeLiteral(v, ["label", "icon"], "label");
234
+ this.requestUpdate("trigger", old);
235
+ }
236
+ /** 下拉 panel 相对触发器的方向;默认贴着触发器左下角向下展开。 */
237
+ get placement() {
238
+ return this._placement;
239
+ }
240
+ set placement(v) {
241
+ const old = this._placement;
242
+ this._placement = normalizeLiteral(v, FLOATING_PLACEMENTS, "bottom-start");
243
+ this.requestUpdate("placement", old);
244
+ }
219
245
  get value() {
220
246
  return this._value;
221
247
  }
@@ -271,6 +297,7 @@ let WebUiSelect = class WebUiSelect extends FormAssociated(LitElement) {
271
297
  updated(changed) {
272
298
  if (changed.has("portal") || changed.has("overlayContainer")) requestAnimationFrame(() => this._reconfigureOverlay());
273
299
  if (changed.has("noScrollLock")) this._syncScrollLock();
300
+ if (changed.has("placement")) this._panel.updatePosition();
274
301
  this._syncOpenAttribute();
275
302
  this._syncOverlayInert();
276
303
  this._syncValidity();
@@ -467,8 +494,11 @@ let WebUiSelect = class WebUiSelect extends FormAssociated(LitElement) {
467
494
  aria-activedescendant=${activeDescendant}
468
495
  aria-label=${ifDefined(this.ariaLabel)}
469
496
  >
470
- <slot name="trigger" @slotchange=${this._onTriggerSlotChange}></slot>
471
- ${!this._hasTriggerSlot ? html`<span class="label">${this._selectedLabel}</span>` : nothing}
497
+ <span class="label">
498
+ <slot name="trigger" @slotchange=${this._onTriggerSlotChange}>
499
+ ${this._hasTriggerSlot ? nothing : this._selectedLabel}
500
+ </slot>
501
+ </span>
472
502
  <web-ui-icon class="arrow" .icon=${lucide_chevron_down_default}></web-ui-icon>
473
503
  </div>
474
504
  <div class="select-overlay wui-floating-panel wui-glass" hidden role="listbox" id=${listboxId}>
@@ -490,6 +520,10 @@ __decorate([property({
490
520
  type: Boolean,
491
521
  reflect: true
492
522
  })], WebUiSelect.prototype, "disabled", void 0);
523
+ __decorate([property({
524
+ type: String,
525
+ reflect: true
526
+ })], WebUiSelect.prototype, "trigger", null);
493
527
  __decorate([property({
494
528
  type: Boolean,
495
529
  reflect: true
@@ -498,6 +532,10 @@ __decorate([property({
498
532
  type: Boolean,
499
533
  reflect: true
500
534
  })], WebUiSelect.prototype, "portal", void 0);
535
+ __decorate([property({
536
+ type: String,
537
+ reflect: true
538
+ })], WebUiSelect.prototype, "placement", null);
501
539
  __decorate([property({
502
540
  type: Boolean,
503
541
  reflect: true,