@greypan/web-ui 5.0.0 → 6.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.
- package/README.CN.md +97 -23
- package/README.md +112 -21
- package/dist/assets/glass.js +1 -1
- package/dist/assets/glass.js.map +1 -1
- package/dist/assets/menu-portal.js +1 -1
- package/dist/assets/menu-portal.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +367 -4
- package/dist/components/autocomplete/index.js +83 -77
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/autocomplete/style.js +1 -1
- package/dist/components/autocomplete/style.js.map +1 -1
- package/dist/components/avatar/style.js +1 -1
- package/dist/components/avatar/style.js.map +1 -1
- package/dist/components/back-top/style.js +1 -1
- package/dist/components/back-top/style.js.map +1 -1
- package/dist/components/badge/style.js +1 -1
- package/dist/components/badge/style.js.map +1 -1
- package/dist/components/button/style.js +1 -1
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/button-group/style.js +1 -1
- package/dist/components/button-group/style.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +366 -5
- package/dist/components/checkbox/index.js +19 -31
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +1 -1
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/checkbox-group/index.d.ts +366 -4
- package/dist/components/checkbox-group/index.js +16 -25
- package/dist/components/checkbox-group/index.js.map +1 -1
- package/dist/components/collapse/index.js +24 -27
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +6 -34
- package/dist/components/context-menu/index.js +88 -201
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/dialog/index.js +20 -23
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +1 -1
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.js +54 -57
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js +1 -1
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +11 -14
- package/dist/components/dropdown/index.js +128 -155
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown-header/style.js +1 -1
- package/dist/components/dropdown-header/style.js.map +1 -1
- package/dist/components/dropdown-item/style.js +1 -1
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/empty/style.js +1 -1
- package/dist/components/empty/style.js.map +1 -1
- package/dist/components/input/index.d.ts +366 -5
- package/dist/components/input/index.js +35 -47
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/style.js +1 -1
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/index.d.ts +366 -5
- package/dist/components/input-number/index.js +31 -44
- package/dist/components/input-number/index.js.map +1 -1
- package/dist/components/input-number/style.js +1 -1
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/style.js +1 -1
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/option/style.js +1 -1
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/popover/index.js +33 -44
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/style.js +1 -1
- package/dist/components/popover/style.js.map +1 -1
- package/dist/components/radio/index.d.ts +366 -5
- package/dist/components/radio/index.js +19 -31
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/style.js +1 -1
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/radio-group/index.d.ts +366 -4
- package/dist/components/radio-group/index.js +16 -25
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/segmented/index.d.ts +366 -4
- package/dist/components/segmented/index.js +26 -35
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +1 -1
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +1 -1
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.d.ts +368 -5
- package/dist/components/select/index.js +65 -67
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/select/style.js +1 -1
- package/dist/components/select/style.js.map +1 -1
- package/dist/components/slider/index.d.ts +366 -5
- package/dist/components/slider/index.js +38 -50
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/slider/style.js +1 -1
- package/dist/components/slider/style.js.map +1 -1
- package/dist/components/spinner/style.js +1 -1
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/switch/index.d.ts +366 -5
- package/dist/components/switch/index.js +26 -38
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/style.js +1 -1
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.d.ts +366 -5
- package/dist/components/textarea/index.js +43 -57
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +1 -1
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/style.js +1 -1
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/style.js +1 -1
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/tooltip/index.d.ts +1 -0
- package/dist/components/tooltip/index.js +32 -46
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/style.js +1 -1
- package/dist/components/tooltip/style.js.map +1 -1
- package/dist/shared/form-association/index.js +31 -4
- package/dist/shared/form-association/index.js.map +1 -1
- package/dist/shared/menu-behavior/index.js +112 -0
- package/dist/shared/menu-behavior/index.js.map +1 -0
- package/dist/shared/menu-portal/menu-tree.js +60 -1
- package/dist/shared/menu-portal/menu-tree.js.map +1 -1
- package/dist/shared/open-state/index.js +12 -0
- package/dist/shared/open-state/index.js.map +1 -0
- package/dist/shared/option-portal/combobox-shell.js +41 -0
- package/dist/shared/option-portal/combobox-shell.js.map +1 -0
- package/dist/shared/option-portal/index.js +23 -22
- package/dist/shared/option-portal/index.js.map +1 -1
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/dist/shared/overlay/placement-props.js +19 -0
- package/dist/shared/overlay/placement-props.js.map +1 -0
- package/dist/shared/overlay/portal.js +94 -20
- package/dist/shared/overlay/portal.js.map +1 -1
- package/package.json +6 -7
package/README.CN.md
CHANGED
|
@@ -120,10 +120,30 @@ useEffect(() => {
|
|
|
120
120
|
<web-ui-dropdown-item ref={itemRef}>粘贴并关闭</web-ui-dropdown-item>
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
+
在 `portal` 模式下,库会把面板内容物理移入浮层 Shadow DOM:
|
|
124
|
+
|
|
125
|
+
- React 按记录的插入父节点执行删除,因此裸条件子元素(`{condition && <el/>}`)的节点一旦已迁移,在面板打开期间无法删除:commit 失败,且该节点可能在面板关闭时重新出现。
|
|
126
|
+
- 请改为在稳定的包装元素内部做条件渲染——React 记录的插入父节点是包装元素,包装元素内部的增删在面板打开期间与开合周期内都保持可用(示例如下)。
|
|
127
|
+
- 面板打开期间的裸条件新增(向宿主追加内容)不受影响,会自动迁入面板。
|
|
128
|
+
- 保持内容始终挂载、仅切换可见性仍是有效的回退方案。
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
<web-ui-popover portal open={open} trigger="manual">
|
|
132
|
+
<div className="panel-body">{editing && <TagEditor />}</div>
|
|
133
|
+
</web-ui-popover>
|
|
134
|
+
```
|
|
135
|
+
|
|
123
136
|
### Vue
|
|
124
137
|
|
|
125
138
|
需要 `vue >= 3.5` 作为可选 peer 依赖。
|
|
126
139
|
|
|
140
|
+
Portal 面板支持实时渲染:浮层打开期间条件新增或删除的内容(`web-ui-select`、`web-ui-autocomplete`、
|
|
141
|
+
`web-ui-popover`、`web-ui-tooltip`、`web-ui-dropdown`、`web-ui-context-menu` 内的 Vue `v-if`)会按模板序
|
|
142
|
+
自动迁入打开中的面板;关闭时所有内容按原锚点位置恢复,后续 patch 继续正常工作。边界:面板打开期间对
|
|
143
|
+
keyed `v-for` 列表做中段 splice 或重排不受支持——Vue 的 keyed children diff 会以已迁入面板的兄弟节点
|
|
144
|
+
计算插入锚点,patch 失败且可能丢项;与编译路径无关(编译模板同样命中)。此类列表更新请在面板关闭后
|
|
145
|
+
进行,或只做尾部追加/删除。
|
|
146
|
+
|
|
127
147
|
```ts
|
|
128
148
|
// vite.config.ts
|
|
129
149
|
import vue from '@vitejs/plugin-vue'
|
|
@@ -198,16 +218,22 @@ hover 与按压反馈阶段保持箭头光标,仅在真实拖拽进行中切
|
|
|
198
218
|
|
|
199
219
|
**请求-写回模式(仅 dialog 与 drawer 的 `controlled`)。**
|
|
200
220
|
`controlled=true` 时,用户关闭操作(Escape、backdrop、内置关闭、拖拽释放)只*请求* `open=false`;组件不改自己的
|
|
201
|
-
|
|
221
|
+
状态,保持打开,直到Consumer写回 `open=false`。这是模态确认语义——关对话框/抽屉通常是需要Consumer批准的操作(未保存
|
|
202
222
|
表单、需确认),与即时开合不同,不能由组件自行提交。只有这两个模态组件使用该模式;即时开合家族(collapse、popover、
|
|
203
223
|
dropdown、tooltip)不需要它。
|
|
204
224
|
|
|
205
225
|
**原生表单模型(input、textarea、input-number、select、checkbox、radio、switch、autocomplete)。**
|
|
206
226
|
控件内部自管理 value/checked 状态;用户交互立即翻转,然后派发原生 `input`/`change` 事件。程序化赋值
|
|
207
227
|
(`el.checked = true`)覆盖内部状态。这与原生 `<input type="checkbox">` 一致——**没有 `controlled` prop 是因为
|
|
208
|
-
值总是可读可写**,React/Vue
|
|
209
|
-
|
|
210
|
-
|
|
228
|
+
值总是可读可写**,React/Vue 层自备受控包装。
|
|
229
|
+
|
|
230
|
+
若翻转的持久化需要外部往返(例如开关应只有 API 调用成功后保持开启),使用**乐观更新**路径:
|
|
231
|
+
|
|
232
|
+
- 立即翻转,然后监听 `change`。
|
|
233
|
+
- 请求期间设 `loading`,阻断后续交互并显示 spinner。
|
|
234
|
+
- 失败后回写 property(`el.checked = false`)并提示 toast。
|
|
235
|
+
|
|
236
|
+
翻转先于批准的窗口被接受;不提供「批准前不翻转」的 `controlled` prop。
|
|
211
237
|
|
|
212
238
|
### 表单关联控件
|
|
213
239
|
|
|
@@ -670,18 +696,27 @@ Portal 面板创建时会镜像 host 上解析后的这些变量;更新 host
|
|
|
670
696
|
|
|
671
697
|
关闭时保留原生 dialog 的 top layer,待退出过渡完成后调用 `dialog.close()`。Escape 始终走此关闭路径;`no-backdrop-close` 仅控制遮罩点击。
|
|
672
698
|
|
|
673
|
-
**拖拽关闭:** 启用 `draggable` 后,打开的抽屉在内缘显示灰色胶囊 drag bar
|
|
699
|
+
**拖拽关闭:** 启用 `draggable` 后,打开的抽屉在内缘显示灰色胶囊 drag bar(默认 4×56px,视觉中线距内缘 10px,位于 32px 厚的命中热区内;`right` 在左缘、`left` 在右缘、`top` 在下缘、`bottom` 在上缘):
|
|
700
|
+
|
|
701
|
+
- 拖拽实时跟手,遮罩透明度按比例淡出。
|
|
702
|
+
- 松手时位移超过抽屉尺寸约 1/3 或快速甩动即弹簧关闭,否则弹回打开位;方向随 placement 适配。
|
|
703
|
+
- 启用 `controlled` 后,超过阈值松手仅派发 `open-change(false)`;抽屉在闭合位短暂等待(120ms 回写窗口),Consumer 拒绝或超时未回写时弹回打开位。
|
|
704
|
+
- 不支持拖拽打开——关闭态的抽屉在原生 dialog 之外没有任何渲染物。
|
|
705
|
+
- `prefers-reduced-motion` 下松手即时到位,不播放弹簧动画。
|
|
674
706
|
|
|
675
707
|
**CSS 自定义属性:**
|
|
676
708
|
|
|
677
|
-
| 属性
|
|
678
|
-
|
|
|
679
|
-
| `--wui-drawer-width`
|
|
680
|
-
| `--wui-drawer-height`
|
|
681
|
-
| `--wui-drawer-bg`
|
|
682
|
-
| `--wui-drawer-radius`
|
|
683
|
-
| `--wui-drawer-inset`
|
|
684
|
-
| `--wui-drawer-overlay-bg`
|
|
709
|
+
| 属性 | 默认值 | 说明 |
|
|
710
|
+
| --------------------------------- | ---------------------------------- | -------------------------------------------------- |
|
|
711
|
+
| `--wui-drawer-width` | `320px` | 抽屉宽度 |
|
|
712
|
+
| `--wui-drawer-height` | `300px` | 抽屉高度(上/下) |
|
|
713
|
+
| `--wui-drawer-bg` | `var(--wui-color-surface-overlay)` | 抽屉背景色 |
|
|
714
|
+
| `--wui-drawer-radius` | `var(--wui-radius-overlay, 28px)` | 浮动卡片圆角(非 headless) |
|
|
715
|
+
| `--wui-drawer-inset` | `8px` | 浮动卡片视口留边(非 headless);置 `0` 为贴边几何 |
|
|
716
|
+
| `--wui-drawer-overlay-bg` | `rgb(0 0 0 / 0.12)` | 遮罩背景色 |
|
|
717
|
+
| `--wui-drawer-drag-zone-size` | `32px` | Drag-to-close 命中热区厚度(draggable) |
|
|
718
|
+
| `--wui-drawer-drag-bar-thickness` | `4px` | Drag bar 胶囊厚度(短轴) |
|
|
719
|
+
| `--wui-drawer-drag-bar-length` | `56px` | Drag bar 胶囊长度(沿抽屉边缘) |
|
|
685
720
|
|
|
686
721
|
---
|
|
687
722
|
|
|
@@ -715,7 +750,7 @@ Portal 面板创建时会镜像 host 上解析后的这些变量;更新 host
|
|
|
715
750
|
|
|
716
751
|
**trigger 语义:** 交互语义完全来自 default slot 放入的元素——原生 `<button>`、`<web-ui-button>` 或其他可交互元素原生提供 Enter/Space 激活与焦点。collapse 把 `aria-expanded` / `aria-controls`(指向内容轨道)与 `aria-disabled` 回写到 trigger slot 的首个 assigned element。trigger 请使用可交互元素:纯 `<span>` 可点击但没有键盘/焦点语义。
|
|
717
752
|
|
|
718
|
-
**关闭稳态语义:**
|
|
753
|
+
**关闭稳态语义:** Consumer的 light DOM 永不移动或卸载。默认关闭稳态在内部内容容器上设 `hidden`;`keep-mounted` 时内部容器标记 `inert`,保留在收起轨道内可测量。
|
|
719
754
|
|
|
720
755
|
**已知限制:** `horizontal` 动画期间内容随宽度变化 reflow。
|
|
721
756
|
|
|
@@ -793,7 +828,7 @@ Hover 模式使用 `pointerenter`/`pointerleave` 加延迟控制。Click 模式
|
|
|
793
828
|
|
|
794
829
|
通过 `contextmenu` 事件打开。菜单项:`web-ui-dropdown-item`、`web-ui-dropdown-divider`、`web-ui-dropdown-header`。支持键盘导航和子菜单 hover。
|
|
795
830
|
|
|
796
|
-
|
|
831
|
+
菜单打开期间,Consumer可以安全地使用条件渲染(如 Vue `v-if`)切换、移动或删除菜单项,无需重新插入到宿主元素;portal 内的变更会自动 reconcile,关闭时框架锚点随元素迁回宿主,保证后续框架更新正常。
|
|
797
832
|
|
|
798
833
|
---
|
|
799
834
|
|
|
@@ -974,7 +1009,12 @@ WebUiSpinner.hide() // 隐藏
|
|
|
974
1009
|
|
|
975
1010
|
**事件:** `sidebar-collapsed-change`(`CustomEvent<{ collapsed: boolean }>`)用于请求更新桌面端折叠状态;`sidebar-open-change`(`CustomEvent<{ open: boolean }>`)用于请求更新移动端 Drawer 打开状态;`sidebar-width-change`(`CustomEvent<{ width: string }>`)用于请求在拖拽调整结束后更新侧边栏宽度。Consumer 必须将请求值回写到对应的受控属性。
|
|
976
1011
|
|
|
977
|
-
**侧边栏调整宽度:** 启用 `sidebar-resizable`
|
|
1012
|
+
**侧边栏调整宽度:** 启用 `sidebar-resizable` 后,桌面端侧边栏右边缘会出现调整手柄(折叠状态下隐藏);悬停或拖拽时显示 3px 宽的强调色垂直线和 `col-resize` 光标。
|
|
1013
|
+
|
|
1014
|
+
- 拖拽时实时更新宽度(禁止过渡动画,限制在 `[min, max]` 和视口范围内)。
|
|
1015
|
+
- 释放时触发 `sidebar-width-change` 事件并携带最终像素宽度,Consumer 回写后宽度重新由 `sidebar-width` 属性接管;`pointercancel` 会恢复属性控制的宽度且不触发事件。
|
|
1016
|
+
- 键盘操作(WAI-ARIA splitter 模式):聚焦后用 ←/→ 以 16px 步进调整(Shift 加速到 64px),Home/End 跳到 min/max,Enter 以同一 `sidebar-width-change` 请求提交,Escape 撤回未提交的调整。
|
|
1017
|
+
- 移动端 Drawer 始终通过其内置 `draggable` 抽屉支持拖拽关闭。
|
|
978
1018
|
|
|
979
1019
|
| 插槽 | 说明 |
|
|
980
1020
|
| --------- | ------------------------------------------------------------ |
|
|
@@ -984,7 +1024,33 @@ WebUiSpinner.hide() // 隐藏
|
|
|
984
1024
|
| `default` | 主内容区 |
|
|
985
1025
|
| `tabbar` | 底部 tabbar |
|
|
986
1026
|
|
|
987
|
-
`web-ui-layout` 只约束侧边栏卡片的可用空间并管理桌面端 Toggle,不创建侧边栏 scrollport。若仅让侧边栏的一部分滚动,请将 `sidebar` 插槽根节点设为 `height: 100%; min-height: 0` 的 flex column,再将 `overflow-y: auto` 设置到目标子元素。这样 Consumer 可自行固定头部和底部,无需额外的公共 slot
|
|
1027
|
+
`web-ui-layout` 只约束侧边栏卡片的可用空间并管理桌面端 Toggle,不创建侧边栏 scrollport。若仅让侧边栏的一部分滚动,请将 `sidebar` 插槽根节点设为 `height: 100%; min-height: 0` 的 flex column,再将 `overflow-y: auto` 设置到目标子元素。这样 Consumer 可自行固定头部和底部,无需额外的公共 slot:
|
|
1028
|
+
|
|
1029
|
+
```html
|
|
1030
|
+
<div slot="sidebar" class="sidebar-root">
|
|
1031
|
+
<div class="sidebar-title">组件列表</div>
|
|
1032
|
+
<nav class="sidebar-nav">...</nav>
|
|
1033
|
+
</div>
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
```css
|
|
1037
|
+
.sidebar-root {
|
|
1038
|
+
display: flex;
|
|
1039
|
+
flex-direction: column;
|
|
1040
|
+
height: 100%;
|
|
1041
|
+
min-height: 0;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.sidebar-title {
|
|
1045
|
+
flex-shrink: 0;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.sidebar-nav {
|
|
1049
|
+
flex: 1;
|
|
1050
|
+
min-height: 0;
|
|
1051
|
+
overflow-y: auto;
|
|
1052
|
+
}
|
|
1053
|
+
```
|
|
988
1054
|
|
|
989
1055
|
在 `640px` 及以下,侧边栏会切换为 headless 模式的 `web-ui-drawer`。Consumer 内容仍渲染在相同的圆角侧边栏卡片中,移动端 Toggle 以 glass 变体位于 header 行内。其左缩进默认 `8px`,可通过 `--wui-layout-mobile-toggle-inset` 与 Consumer 自身的 header 内边距对齐。
|
|
990
1056
|
|
|
@@ -992,10 +1058,10 @@ WebUiSpinner.hide() // 隐藏
|
|
|
992
1058
|
|
|
993
1059
|
**CSS 自定义属性:**
|
|
994
1060
|
|
|
995
|
-
| 属性 | 默认值
|
|
996
|
-
| ---------------------------------- |
|
|
997
|
-
| `--wui-layout-sidebar-radius` | `
|
|
998
|
-
| `--wui-layout-mobile-toggle-inset` | `8px`
|
|
1061
|
+
| 属性 | 默认值 | 说明 |
|
|
1062
|
+
| ---------------------------------- | --------------------------------- | ------------------------------------ |
|
|
1063
|
+
| `--wui-layout-sidebar-radius` | `var(--wui-radius-overlay, 28px)` | 侧边栏卡片圆角(桌面端和移动端共用) |
|
|
1064
|
+
| `--wui-layout-mobile-toggle-inset` | `8px` | 移动端 header Toggle 的左缩进 |
|
|
999
1065
|
|
|
1000
1066
|
#### `<web-ui-back-top>`
|
|
1001
1067
|
|
|
@@ -1067,6 +1133,14 @@ SVG 线条绘制动画,基于 `stroke-dashoffset`。直接在原元素上动
|
|
|
1067
1133
|
| `--wui-overlay-min-width` | `200px` | 锚定浮层最小宽度 |
|
|
1068
1134
|
| `--wui-focus-ring-width` | `3px` | Focus 指示器宽度 |
|
|
1069
1135
|
|
|
1136
|
+
**圆角 token:**
|
|
1137
|
+
|
|
1138
|
+
| 属性 | 默认值 | 说明 |
|
|
1139
|
+
| ---------------------- | ---------------------- | ---------------------------------------------------- |
|
|
1140
|
+
| `--wui-radius-control` | `calc(infinity * 1px)` | 小型控件的胶囊圆角(button、input、switch、option…) |
|
|
1141
|
+
| `--wui-radius-menu` | `18px` | 菜单/Popover 浮动面板、多行 textarea 与 toast |
|
|
1142
|
+
| `--wui-radius-overlay` | `28px` | 大型覆盖层:dialog、drawer、layout sidebar |
|
|
1143
|
+
|
|
1070
1144
|
**层级 token:**
|
|
1071
1145
|
|
|
1072
1146
|
| 属性 | 默认值 | 说明 |
|
|
@@ -1130,9 +1204,9 @@ SVG 线条绘制动画,基于 `stroke-dashoffset`。直接在原元素上动
|
|
|
1130
1204
|
| `--wui-shadow-panel` | `0 3px 9px rgb(0 0 0 / 0.27)` | `0 4px 16px rgb(0 0 0 / 0.32)` | 小型浮动面板阴影 |
|
|
1131
1205
|
| `--wui-shadow-glass` | 四层扩散阴影 | `0 8px 24px rgb(0 0 0 / 0.08)` | 液态玻璃基础阴影 |
|
|
1132
1206
|
|
|
1133
|
-
**玻璃效果 token:** `--wui-glass-brightness` 浅色模式为 `1.06`,深色模式为 `1.02`。`--wui-glass-corner-radius` 默认值为 `32px
|
|
1207
|
+
**玻璃效果 token:** `--wui-glass-brightness` 浅色模式为 `1.06`,深色模式为 `1.02`。`--wui-glass-corner-radius` 默认值为 `32px`;非 pill 玻璃表面以自身语义圆角(`--wui-radius-menu` / `--wui-radius-overlay`,drawer 为 `--wui-drawer-radius`)覆盖它,使对角描边光影跟随 token 覆盖联动。pill 控件例外:光影渐变需要物理尺寸,继续使用由控件实际尺寸或内部尺寸 token 派生的有限圆角值。
|
|
1134
1208
|
|
|
1135
|
-
**内部 token:** 以 `--wui-internal-*` 为前缀的变量是 Shadow DOM 内部接线变量,不属于公共 token API
|
|
1209
|
+
**内部 token:** 以 `--wui-internal-*` 为前缀的变量是 Shadow DOM 内部接线变量,不属于公共 token API,Consumer 不应覆盖。
|
|
1136
1210
|
|
|
1137
1211
|
---
|
|
1138
1212
|
|
package/README.md
CHANGED
|
@@ -123,10 +123,48 @@ useEffect(() => {
|
|
|
123
123
|
<web-ui-dropdown-item ref={itemRef}>Paste and close</web-ui-dropdown-item>
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
In `portal` mode the library physically moves panel content into the overlay Shadow DOM:
|
|
127
|
+
|
|
128
|
+
- React removes nodes through its recorded insertion parent, so a bare conditional child (`{condition && <el/>}`) whose node was already migrated cannot be removed while the panel is open: the commit fails and the node can reappear when the panel closes.
|
|
129
|
+
- Conditionally render inside a stable wrapper element instead — React records the wrapper as the insertion parent, so wrapper-local additions and removals keep working while the panel is open and across open/close cycles (example below).
|
|
130
|
+
- Bare conditional additions while the panel is open (appending to the host) keep working and migrate into the panel automatically.
|
|
131
|
+
- Keeping content mounted and toggling visibility remains a valid fallback.
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
<web-ui-popover portal open={open} trigger="manual">
|
|
135
|
+
<div className="panel-body">{editing && <TagEditor />}</div>
|
|
136
|
+
</web-ui-popover>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Lit
|
|
140
|
+
|
|
141
|
+
Portal panels support live rendering for Lit child parts: `${condition ? html`<el/>` : nothing}` inside
|
|
142
|
+
`web-ui-popover`, `web-ui-tooltip`, `web-ui-select` and `web-ui-autocomplete` migrates into the open panel
|
|
143
|
+
automatically, removals and element-to-element swaps work while the panel is open, and on close content is
|
|
144
|
+
restored to its original anchor position. lit-html child-part markers stay in the host light DOM, so
|
|
145
|
+
subsequent patches keep anchoring correctly. Boundary: reordering a `repeat()` list while a panel is open is
|
|
146
|
+
not supported — lit inserts relative to host part markers while sibling items already live in the panel, the
|
|
147
|
+
same cross-container anchoring boundary as Vue's keyed `v-for`. Apply list reorders while the panel is closed.
|
|
148
|
+
|
|
149
|
+
`web-ui-dropdown` manages menu items through the shared menu portal, which reconciles from both the host and
|
|
150
|
+
the panel: child-part additions while the panel is open work, but lit cannot reach items that already live in
|
|
151
|
+
the panel, so removals and element swaps there are not supported — apply them while the panel is closed.
|
|
152
|
+
`web-ui-context-menu` does not observe host-side insertions and is not covered by these live-rendering
|
|
153
|
+
guarantees.
|
|
154
|
+
|
|
126
155
|
### Vue
|
|
127
156
|
|
|
128
157
|
Requires `vue >= 3.5` as optional peer dependency.
|
|
129
158
|
|
|
159
|
+
Portal panels support live rendering: content conditionally added or removed while a panel is open (Vue
|
|
160
|
+
`v-if` inside `web-ui-select`, `web-ui-autocomplete`, `web-ui-popover`, `web-ui-tooltip`, `web-ui-dropdown`,
|
|
161
|
+
`web-ui-context-menu`) migrates into the open panel automatically in template order, and on close everything
|
|
162
|
+
is restored to its original anchor position so subsequent patches keep working. Boundary: splicing or
|
|
163
|
+
reordering a keyed `v-for` list while a panel is open is not supported — Vue's keyed children diff resolves
|
|
164
|
+
insertion anchors against sibling nodes already migrated into the panel, so its patch fails and items can be
|
|
165
|
+
lost, regardless of compilation path (compiled templates included). Apply such list updates while the panel
|
|
166
|
+
is closed, or keep to appends/removals at the list tail.
|
|
167
|
+
|
|
130
168
|
```ts
|
|
131
169
|
// vite.config.ts
|
|
132
170
|
import vue from '@vitejs/plugin-vue'
|
|
@@ -216,11 +254,16 @@ components use this mode; the instant open/close family (collapse, popover, drop
|
|
|
216
254
|
The control manages its own value/checked state internally; user interaction flips it immediately and then dispatches
|
|
217
255
|
native `input`/`change` events. Assigning the property programmatically (`el.checked = true`) overrides the internal
|
|
218
256
|
state. This mirrors native `<input type="checkbox">` — there is no `controlled` prop because the value is always readable
|
|
219
|
-
and writable, and React/Vue layers provide their own controlled wrappers on top.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
257
|
+
and writable, and React/Vue layers provide their own controlled wrappers on top.
|
|
258
|
+
|
|
259
|
+
For interactions that need an external round-trip before the flip is durable (e.g. a switch that should only stay on
|
|
260
|
+
after an API call succeeds), use the optimistic-update path:
|
|
261
|
+
|
|
262
|
+
- Flip immediately, then observe `change`.
|
|
263
|
+
- Set the control's `loading` during the request; this blocks further interaction and shows a spinner.
|
|
264
|
+
- On failure, write the property back (`el.checked = false`) and surface a toast.
|
|
265
|
+
|
|
266
|
+
The flip-before-approval window is accepted; there is no `controlled` prop for a reject-before-flip contract.
|
|
224
267
|
|
|
225
268
|
### Form-associated controls
|
|
226
269
|
|
|
@@ -689,18 +732,27 @@ Side drawer using native `<dialog>` with closing animation. In non-headless mode
|
|
|
689
732
|
|
|
690
733
|
Closing keeps the native dialog in the top layer until the `--wui-duration-drawer-exit` transition completes (240ms by default), then calls `dialog.close()`. Escape always follows this close path; `no-backdrop-close` controls backdrop clicks only.
|
|
691
734
|
|
|
692
|
-
**Drag to close:** With `draggable`, a gray capsule drag bar appears on the drawer's inner edge (left edge for `right`, right edge for `left`, bottom edge for `top`, top edge for `bottom`) while open
|
|
735
|
+
**Drag to close:** With `draggable`, a gray capsule drag bar (4×56px by default, visually centered 10px from the inner edge inside a 32px-thick hit zone) appears on the drawer's inner edge (left edge for `right`, right edge for `left`, bottom edge for `top`, top edge for `bottom`) while open:
|
|
736
|
+
|
|
737
|
+
- Dragging follows the pointer in real time; the backdrop fades proportionally.
|
|
738
|
+
- Releasing past ~1/3 of the drawer size, or with a fast closing flick, springs the drawer shut; otherwise it springs back open. The close direction is placement-aware.
|
|
739
|
+
- With `controlled`, release past the threshold only emits `open-change(false)`; the drawer holds at the closed position briefly (120ms write-back window) and springs back open if the consumer rejects or misses the write-back.
|
|
740
|
+
- Drag-to-open is not supported because the closed drawer renders nothing outside the native dialog.
|
|
741
|
+
- Under `prefers-reduced-motion`, release snaps instantly without spring animation.
|
|
693
742
|
|
|
694
743
|
**CSS Custom Properties:**
|
|
695
744
|
|
|
696
|
-
| Property
|
|
697
|
-
|
|
|
698
|
-
| `--wui-drawer-width`
|
|
699
|
-
| `--wui-drawer-height`
|
|
700
|
-
| `--wui-drawer-bg`
|
|
701
|
-
| `--wui-drawer-radius`
|
|
702
|
-
| `--wui-drawer-inset`
|
|
703
|
-
| `--wui-drawer-overlay-bg`
|
|
745
|
+
| Property | Default | Description |
|
|
746
|
+
| --------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------- |
|
|
747
|
+
| `--wui-drawer-width` | `320px` | Drawer width |
|
|
748
|
+
| `--wui-drawer-height` | `300px` | Drawer height (top/bottom) |
|
|
749
|
+
| `--wui-drawer-bg` | `var(--wui-color-surface-overlay)` | Drawer body background |
|
|
750
|
+
| `--wui-drawer-radius` | `var(--wui-radius-overlay, 28px)` | Floating card corner radius (non-headless) |
|
|
751
|
+
| `--wui-drawer-inset` | `8px` | Floating card viewport inset (non-headless); `0` gives edge-to-edge geometry |
|
|
752
|
+
| `--wui-drawer-overlay-bg` | `rgb(0 0 0 / 0.12)` | Backdrop background |
|
|
753
|
+
| `--wui-drawer-drag-zone-size` | `32px` | Drag-to-close hit zone thickness on the inner edge (draggable) |
|
|
754
|
+
| `--wui-drawer-drag-bar-thickness` | `4px` | Drag bar capsule thickness (short axis) |
|
|
755
|
+
| `--wui-drawer-drag-bar-length` | `56px` | Drag bar capsule length (along the drawer edge) |
|
|
704
756
|
|
|
705
757
|
---
|
|
706
758
|
|
|
@@ -993,7 +1045,12 @@ Responsive page layout with an optional full-width banner, a collapsible desktop
|
|
|
993
1045
|
|
|
994
1046
|
**Events:** `sidebar-collapsed-change` (`CustomEvent<{ collapsed: boolean }>`) requests a desktop collapse-state update. `sidebar-open-change` (`CustomEvent<{ open: boolean }>`) requests a mobile drawer open-state update. `sidebar-width-change` (`CustomEvent<{ width: string }>`) requests a sidebar width update after a resize drag ends. Consumers must write the requested value back to the corresponding controlled property.
|
|
995
1047
|
|
|
996
|
-
**Sidebar resize:** With `sidebar-resizable`, a resize handle appears on the desktop sidebar's right edge (hidden while collapsed)
|
|
1048
|
+
**Sidebar resize:** With `sidebar-resizable`, a resize handle appears on the desktop sidebar's right edge (hidden while collapsed); hovering or dragging shows a 3px accent vertical line with a `col-resize` cursor.
|
|
1049
|
+
|
|
1050
|
+
- Dragging updates the width in real time (transition suppressed, clamped to `[min, max]` and the viewport).
|
|
1051
|
+
- Releasing emits `sidebar-width-change` with the final pixel width; the width is property-controlled again once the consumer writes it back. `pointercancel` restores the property-controlled width without emitting.
|
|
1052
|
+
- Keyboard (WAI-ARIA splitter pattern): focus the handle and use ←/→ to step by 16px (Shift for 64px), Home/End to jump to min/max, Enter to commit via the same `sidebar-width-change` request, and Escape to revert an uncommitted adjustment.
|
|
1053
|
+
- The mobile drawer always supports drag-to-close via its built-in `draggable` drawer.
|
|
997
1054
|
|
|
998
1055
|
| Slot | Description |
|
|
999
1056
|
| --------- | ----------------------------------------------------------------------------------------- |
|
|
@@ -1003,7 +1060,33 @@ Responsive page layout with an optional full-width banner, a collapsible desktop
|
|
|
1003
1060
|
| `default` | Main content |
|
|
1004
1061
|
| `tabbar` | Bottom tab bar |
|
|
1005
1062
|
|
|
1006
|
-
`web-ui-layout` constrains the sidebar card and owns the desktop toggle area, but does not create a sidebar scrollport. To make only part of the sidebar scroll, make the `sidebar` slot root a `height: 100%; min-height: 0` flex column and apply `overflow-y: auto` to the intended child. This keeps consumer-defined headers and footers fixed without adding extra public slots
|
|
1063
|
+
`web-ui-layout` constrains the sidebar card and owns the desktop toggle area, but does not create a sidebar scrollport. To make only part of the sidebar scroll, make the `sidebar` slot root a `height: 100%; min-height: 0` flex column and apply `overflow-y: auto` to the intended child. This keeps consumer-defined headers and footers fixed without adding extra public slots:
|
|
1064
|
+
|
|
1065
|
+
```html
|
|
1066
|
+
<div slot="sidebar" class="sidebar-root">
|
|
1067
|
+
<div class="sidebar-title">Components</div>
|
|
1068
|
+
<nav class="sidebar-nav">...</nav>
|
|
1069
|
+
</div>
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
```css
|
|
1073
|
+
.sidebar-root {
|
|
1074
|
+
display: flex;
|
|
1075
|
+
flex-direction: column;
|
|
1076
|
+
height: 100%;
|
|
1077
|
+
min-height: 0;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
.sidebar-title {
|
|
1081
|
+
flex-shrink: 0;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
.sidebar-nav {
|
|
1085
|
+
flex: 1;
|
|
1086
|
+
min-height: 0;
|
|
1087
|
+
overflow-y: auto;
|
|
1088
|
+
}
|
|
1089
|
+
```
|
|
1007
1090
|
|
|
1008
1091
|
At `640px` and below, the sidebar becomes a headless `web-ui-drawer`. The consumer content is rendered in the same rounded sidebar card; the mobile toggle appears in the header row as a glass button. Its left inset defaults to `8px`; align it with your own header padding via `--wui-layout-mobile-toggle-inset`.
|
|
1009
1092
|
|
|
@@ -1011,10 +1094,10 @@ At `640px` and below, the sidebar becomes a headless `web-ui-drawer`. The consum
|
|
|
1011
1094
|
|
|
1012
1095
|
**CSS Custom Properties:**
|
|
1013
1096
|
|
|
1014
|
-
| Property | Default
|
|
1015
|
-
| ---------------------------------- |
|
|
1016
|
-
| `--wui-layout-sidebar-radius` | `
|
|
1017
|
-
| `--wui-layout-mobile-toggle-inset` | `8px`
|
|
1097
|
+
| Property | Default | Description |
|
|
1098
|
+
| ---------------------------------- | --------------------------------- | ------------------------------------------------ |
|
|
1099
|
+
| `--wui-layout-sidebar-radius` | `var(--wui-radius-overlay, 28px)` | Border radius of sidebar card (desktop & mobile) |
|
|
1100
|
+
| `--wui-layout-mobile-toggle-inset` | `8px` | Left inset of the mobile header toggle |
|
|
1018
1101
|
|
|
1019
1102
|
#### `<web-ui-back-top>`
|
|
1020
1103
|
|
|
@@ -1086,6 +1169,14 @@ Defines foundation, color, layer, shadow, and motion tokens for its subtree. `mo
|
|
|
1086
1169
|
| `--wui-overlay-min-width` | `200px` | Minimum anchored overlay width |
|
|
1087
1170
|
| `--wui-focus-ring-width` | `3px` | Focus indicator width |
|
|
1088
1171
|
|
|
1172
|
+
**Radius tokens:**
|
|
1173
|
+
|
|
1174
|
+
| Property | Default | Description |
|
|
1175
|
+
| ---------------------- | ---------------------- | --------------------------------------------------------------- |
|
|
1176
|
+
| `--wui-radius-control` | `calc(infinity * 1px)` | Pill radius for small controls (button, input, switch, option…) |
|
|
1177
|
+
| `--wui-radius-menu` | `18px` | Menu/popover floating panels, multiline textarea and toast |
|
|
1178
|
+
| `--wui-radius-overlay` | `28px` | Large overlay surfaces: dialog, drawer, layout sidebar |
|
|
1179
|
+
|
|
1089
1180
|
**Layer tokens:**
|
|
1090
1181
|
|
|
1091
1182
|
| Property | Default | Description |
|
|
@@ -1149,7 +1240,7 @@ Defines foundation, color, layer, shadow, and motion tokens for its subtree. `mo
|
|
|
1149
1240
|
| `--wui-shadow-panel` | `0 3px 9px rgb(0 0 0 / 0.27)` | `0 4px 16px rgb(0 0 0 / 0.32)` | Small floating panel shadow |
|
|
1150
1241
|
| `--wui-shadow-glass` | four-layer diffuse shadow | `0 8px 24px rgb(0 0 0 / 0.08)` | Base liquid glass shadow |
|
|
1151
1242
|
|
|
1152
|
-
**Glass effect tokens:** `--wui-glass-brightness` is `1.06` in light mode and `1.02` in dark mode. `--wui-glass-corner-radius` defaults to `32px`; glass
|
|
1243
|
+
**Glass effect tokens:** `--wui-glass-brightness` is `1.06` in light mode and `1.02` in dark mode. `--wui-glass-corner-radius` defaults to `32px`; non-pill glass surfaces set it from their own semantic radius (`--wui-radius-menu` / `--wui-radius-overlay`, or `--wui-drawer-radius` for the drawer) so the diagonal border lighting follows token overrides. Pill controls keep a finite corner radius derived from their physical size or internal size token instead, because the lighting gradient needs a physical size.
|
|
1153
1244
|
|
|
1154
1245
|
**Internal tokens:** variables prefixed `--wui-internal-*` are private wiring between shadow DOM parts; they are not part of the public token API and must not be overridden by consumers.
|
|
1155
1246
|
|
package/dist/assets/glass.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/assets/glass.css?inline
|
|
2
|
-
var e = ".wui-glass{--wui-internal-glass-
|
|
2
|
+
var e = ".wui-glass{--wui-internal-glass-shadow:var(--wui-shadow-glass,0 0 1px #0000000d, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004);background-color:var(--wui-color-surface-glass,#fafafa57);-webkit-backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(4px) saturate(160%) brightness(var(--wui-glass-brightness,1.06));box-shadow:inset 0 0 0 .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 38%, transparent), inset 0 1px .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 52%, transparent), inset 0 -.5px 1px #00000008, var(--wui-internal-glass-shadow,var(--wui-shadow-glass,0 0 1px #0000000d, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004));background-clip:padding-box;border:none;position:relative}.wui-glass:before{pointer-events:none;content:\"\";border-radius:inherit;background-color:var(--wui-color-glass-border,transparent);background-image:radial-gradient(var(--wui-glass-corner-radius,32px) at 100% 0, var(--wui-color-glass-shade,#0000000f), transparent), radial-gradient(var(--wui-glass-corner-radius,32px) at 0 100%, var(--wui-color-glass-shade,#0000000f), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 0 0, var(--wui-color-glass-corner,#ffffff14), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 100% 100%, var(--wui-color-glass-corner,#ffffff14), transparent);-webkit-mask-composite:xor;-webkit-mask-composite:xor;-webkit-mask-source-type:auto,auto;padding:1px;position:absolute;inset:0;-webkit-mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;-webkit-mask-size:auto,auto;mask-size:auto,auto;-webkit-mask-repeat:repeat,repeat;mask-repeat:repeat,repeat;-webkit-mask-clip:content-box,border-box;mask-clip:content-box,border-box;-webkit-mask-origin:content-box,border-box;mask-origin:content-box,border-box;-webkit-mask-composite:xor;mask-composite:exclude;-webkit-mask-source-type:auto,auto;mask-mode:match-source,match-source}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
package/dist/assets/glass.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glass.js","names":[],"sources":["../../src/assets/glass.css?inline"],"sourcesContent":["/*\n * 玻璃公共样式\n */\n\n.wui-glass {\n /*\n *
|
|
1
|
+
{"version":3,"file":"glass.js","names":[],"sources":["../../src/assets/glass.css?inline"],"sourcesContent":["/*\n * 玻璃公共样式\n */\n\n.wui-glass {\n /*\n * 内部阴影变量在 glass 元素上自声明默认值,切断从祖先 glass 容器(drawer/dialog\n * body 等声明了 overlay 阴影的元素)沿 flattened tree 继承进 slotted 内容的\n * 通道;各组件在自身元素上的同变量配置(特异性/源顺序恒胜出)不受影响。\n */\n --wui-internal-glass-shadow: var(\n --wui-shadow-glass,\n 0 0 1px rgb(0 0 0 / 0.05),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n );\n\n position: relative;\n\n border: none;\n\n background-color: var(--wui-color-surface-glass, rgb(250 250 250 / 0.34));\n background-clip: padding-box;\n\n /* Safari 16.4 只支持带 -webkit- 前缀的 backdrop-filter(无前缀 18 才支持),\n lightningcss 对 ?inline 导入不做自动前缀,需手动写前缀版本 */\n /* stylelint-disable-next-line property-no-vendor-prefix */\n -webkit-backdrop-filter: blur(4px) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n backdrop-filter: blur(4px) saturate(160%) brightness(var(--wui-glass-brightness, 1.06));\n box-shadow:\n inset 0 0 0 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 38%, transparent),\n inset 0 1px 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 52%, transparent),\n inset 0 -0.5px 1px rgb(0 0 0 / 0.03),\n var(\n --wui-internal-glass-shadow,\n var(\n --wui-shadow-glass,\n 0 0 1px rgb(0 0 0 / 0.05),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n )\n );\n}\n\n/*\n * 玻璃描边:底环 + 对角受光/背光。background-color 用 border 色铺满整圈(含圆角\n * 弧段,修复胶囊弧段无着色发暗的问题);叠两枚 corner→transparent radial 作左上/\n * 右下受光光泽,再叠两枚 shade→transparent radial(置于最上层)压暗右上/左下背光\n * 角,形成对角光影的玻璃立体感。四枚渐变均为锚定角点、半径 --wui-glass-corner-radius\n * 的固定物理尺寸正圆——视觉覆盖范围不随元素宽高缩放(百分比方案在大面板上暗边\n * 过长、小控件上过弱),各组件用与自身 border-radius 同源的值覆盖该变量即可联动。\n * 颜色由 theme 按明暗主题提供 --wui-color-glass-corner / --wui-color-glass-shade /\n * --wui-color-glass-border;-webkit-mask-composite 旧语法覆盖 Chrome 111-119,\n * 无前缀 mask-composite 留给 Chrome 120+。\n */\n.wui-glass::before {\n pointer-events: none;\n content: '';\n\n position: absolute;\n inset: 0;\n\n padding: 1px;\n border-radius: inherit;\n\n background-color: var(--wui-color-glass-border, transparent);\n background-image:\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 100% 0,\n var(--wui-color-glass-shade, rgb(0 0 0 / 0.06)),\n transparent\n ),\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 0 100%,\n var(--wui-color-glass-shade, rgb(0 0 0 / 0.06)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 0 0,\n var(--wui-color-glass-corner, rgb(255 255 255 / 0.08)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 100% 100%,\n var(--wui-color-glass-corner, rgb(255 255 255 / 0.08)),\n transparent\n );\n /* stylelint-disable-next-line property-no-vendor-prefix */\n -webkit-mask:\n linear-gradient(#000 0 0) content-box,\n linear-gradient(#000 0 0);\n mask:\n linear-gradient(#000 0 0) content-box,\n linear-gradient(#000 0 0);\n /* stylelint-disable-next-line property-no-vendor-prefix */\n -webkit-mask-composite: xor;\n mask-composite: exclude;\n}\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/assets/menu-portal.css?inline
|
|
2
|
-
var e = ".wui-menu-portal-overlay.wui-glass{--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-internal-duration-overlay-enter:var(--wui-duration-menu-enter,.14s);--wui-internal-duration-overlay-exit:var(--wui-duration-menu-exit,.1s);-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);max-width:90vw;max-height:80vh;color:var(--wui-color-text,#1b1b1b);background-color:var(--wui-color-surface-menu,#f6f6f6d1);
|
|
2
|
+
var e = ".wui-menu-portal-overlay.wui-glass{--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-internal-duration-overlay-enter:var(--wui-duration-menu-enter,.14s);--wui-internal-duration-overlay-exit:var(--wui-duration-menu-exit,.1s);--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-glass .wui-menu-scroll{max-height:80vh;overflow-y:auto}.wui-menu-portal-overlay.wui-glass .wui-menu-content{padding:4px}.wui-menu-portal-overlay.wui-glass.dropdown-overlay .wui-menu-scroll{max-height:320px}.wui-menu-portal-overlay.wui-glass.dropdown-overlay[data-level]:not([data-level=\"0\"]),.wui-menu-portal-overlay.wui-glass.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 { position: relative },保持 fixed 定位。 */\n.wui-menu-portal-overlay.wui-glass {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-internal-duration-overlay-enter: var(--wui-duration-menu-enter, 140ms);\n --wui-internal-duration-overlay-exit: var(--wui-duration-menu-exit, 100ms);\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:
|
|
1
|
+
{"version":3,"file":"menu-portal.js","names":[],"sources":["../../src/assets/menu-portal.css?inline"],"sourcesContent":["/* 双类选择器覆盖 .wui-glass { position: relative },保持 fixed 定位。 */\n.wui-menu-portal-overlay.wui-glass {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-internal-duration-overlay-enter: var(--wui-duration-menu-enter, 140ms);\n --wui-internal-duration-overlay-exit: var(--wui-duration-menu-exit, 100ms);\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 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":""}
|