@greypan/web-ui 11.0.0 → 11.2.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 +105 -41
- package/README.md +69 -0
- package/dist/assets/overlay-motion.js +1 -1
- package/dist/assets/overlay-motion.js.map +1 -1
- package/dist/assets/selection-control.js +1 -1
- package/dist/assets/selection-control.js.map +1 -1
- package/dist/classes/glass.js +6 -0
- package/dist/classes/glass.js.map +1 -0
- package/dist/classes/glow.js +6 -0
- package/dist/classes/glow.js.map +1 -0
- package/dist/classes/style.css +1 -0
- package/dist/components/autocomplete/index.d.ts +7 -0
- package/dist/components/autocomplete/index.js +33 -13
- 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/index.js +2 -2
- package/dist/components/avatar/index.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/index.d.ts +4 -0
- package/dist/components/back-top/index.js +60 -22
- package/dist/components/back-top/index.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/index.d.ts +3 -0
- package/dist/components/badge/index.js +29 -14
- package/dist/components/badge/index.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/index.d.ts +3 -0
- package/dist/components/button/index.js +27 -18
- package/dist/components/button/index.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/index.d.ts +3 -0
- package/dist/components/button-group/index.js +15 -2
- package/dist/components/button-group/index.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.js +6 -6
- 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/collapse/index.d.ts +15 -7
- package/dist/components/collapse/index.js +44 -26
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/collapse/style.js +1 -1
- package/dist/components/collapse/style.js.map +1 -1
- package/dist/components/dialog/index.d.ts +1 -0
- package/dist/components/dialog/index.js +5 -2
- 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 +1 -1
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +16 -0
- package/dist/components/dropdown/index.js +147 -18
- package/dist/components/dropdown/index.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/editable-text/index.js +7 -3
- package/dist/components/editable-text/index.js.map +1 -1
- package/dist/components/editable-text/style.js +1 -1
- package/dist/components/editable-text/style.js.map +1 -1
- package/dist/components/empty/index.d.ts +10 -22
- package/dist/components/empty/index.js +19 -35
- package/dist/components/empty/index.js.map +1 -1
- package/dist/components/empty/style.js +1 -1
- package/dist/components/empty/style.js.map +1 -1
- package/dist/components/image-preview/index.js +2 -2
- package/dist/components/image-preview/index.js.map +1 -1
- package/dist/components/input/index.d.ts +1 -0
- package/dist/components/input/index.js +5 -2
- 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 +31 -1
- package/dist/components/input-number/index.js +281 -22
- 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/index.js +44 -39
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/style.js +1 -1
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/middle-ellipsis/index.d.ts +8 -1
- package/dist/components/middle-ellipsis/index.js +68 -10
- package/dist/components/middle-ellipsis/index.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.js +1 -1
- 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 +5 -0
- package/dist/components/radio/index.js +33 -23
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/interaction.d.ts +4 -0
- package/dist/components/radio/interaction.js +17 -0
- package/dist/components/radio/interaction.js.map +1 -0
- 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 +22 -0
- package/dist/components/radio-group/index.js +219 -28
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/segmented/index.d.ts +2 -0
- package/dist/components/segmented/index.js +74 -18
- 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/index.js +3 -2
- package/dist/components/segmented-trigger/index.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 +8 -0
- package/dist/components/select/index.js +76 -25
- 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 +15 -0
- package/dist/components/slider/index.js +175 -39
- 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/index.d.ts +15 -0
- package/dist/components/spinner/index.js +79 -22
- package/dist/components/spinner/index.js.map +1 -1
- package/dist/components/spinner/style.js +1 -1
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/svg-draw-lines/index.js +48 -12
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/switch/index.d.ts +11 -3
- package/dist/components/switch/index.js +57 -53
- 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.js +2 -2
- 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/index.d.ts +1 -0
- package/dist/components/theme/index.js +26 -15
- package/dist/components/theme/index.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/toast/toast.js +1 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/tooltip/index.d.ts +1 -0
- package/dist/components/tooltip/index.js +10 -5
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/icons/generated/andrsrxn-inbox.d.ts +6 -0
- package/dist/icons/generated/andrsrxn-inbox.js +10 -0
- package/dist/icons/generated/andrsrxn-inbox.js.map +1 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +75 -74
- package/dist/shared/focus/pointer-focus.js +12 -10
- package/dist/shared/focus/pointer-focus.js.map +1 -1
- package/dist/shared/gesture/drag-gesture.js +4 -4
- package/dist/shared/gesture/drag-gesture.js.map +1 -1
- package/dist/shared/group-management/index.js +43 -18
- package/dist/shared/group-management/index.js.map +1 -1
- package/dist/shared/menu-portal/menu-portal.js +1 -1
- package/dist/shared/menu-portal/menu-portal.js.map +1 -1
- package/dist/shared/overlay/overlay-root.js +1 -1
- package/dist/shared/overlay/overlay-root.js.map +1 -1
- package/dist/shared/overlay/overlay.js +7 -1
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/package.json +5 -1
- package/dist/assets/glass.js +0 -6
- package/dist/assets/glass.js.map +0 -1
package/README.CN.md
CHANGED
|
@@ -60,6 +60,70 @@ import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue' // 或 overla
|
|
|
60
60
|
声明它会让引擎放弃平台的覆盖式 scrollbar、固定占一条布局宽度,而组件内部 scrollbar 正是不能占宽度。
|
|
61
61
|
导入本样式表,组件内部 scrollbar 才会跟随外观,与整页 scrollbar 同一机制。
|
|
62
62
|
|
|
63
|
+
## Classes
|
|
64
|
+
|
|
65
|
+
`@greypan/web-ui/classes.css` 汇总可复用的公共 class,组件内部与消费方共用同一份源码:
|
|
66
|
+
`.wui-glass`(毛玻璃表面)与 `.wui-glow`(装饰性背景晕染)。
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
import '@greypan/web-ui/classes.css'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### .wui-glass
|
|
73
|
+
|
|
74
|
+
给任意容器加 `.wui-glass` 即可获得毛玻璃表面;组件内部(drawer body、dialog / toast、tooltip /
|
|
75
|
+
popover、input 等)用的也是同一份样式。
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<div class="wui-glass">...</div>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- 同时提供半透明底色、`backdrop-filter`(模糊 / 饱和 / 亮度)、元素自身的 inset 高光与投影,
|
|
82
|
+
以及用 `::before` 挖出的 1px 描边环:环的左上 / 右下受光、右上 / 左下背光,半径由
|
|
83
|
+
`--wui-glass-corner-radius` 控制。
|
|
84
|
+
- 容器需要有确定的盒子尺寸和可被采样的背景。`.wui-glass` 只在宿主没有其他 `position` 时补
|
|
85
|
+
`position: relative`,并移除自身 border(描边由环承担);圆角仍跟随宿主的 `border-radius`。
|
|
86
|
+
- 非 pill 表面应把 `--wui-glass-corner-radius` 覆盖成与自身圆角同源的值,否则角部光影半径与
|
|
87
|
+
盒形不匹配。颜色 token 由主题给出浅 / 深两套默认值,优先覆盖 token 而不是重写 `backdrop-filter`。
|
|
88
|
+
|
|
89
|
+
| token | 默认值 | 说明 |
|
|
90
|
+
| ------------------------------ | ------------------------- | ---------------------------------------------------- |
|
|
91
|
+
| `--wui-color-surface-glass` | `rgb(250 250 250 / 0.34)` | 半透明底色;深色主题为 `rgb(44 44 46 / 0.42)` |
|
|
92
|
+
| `--wui-glass-blur` | `4px` | `backdrop-filter` 模糊半径;设 `0px` 关闭 |
|
|
93
|
+
| `--wui-glass-saturation` | `160%` | 背景饱和度 |
|
|
94
|
+
| `--wui-glass-brightness` | `1.06` | 背景亮度;深色主题为 `1.02` |
|
|
95
|
+
| `--wui-color-glass-highlight` | `rgb(255 255 255 / 0.9)` | 元素 inset 高光;深色主题为 `rgb(255 255 255 / 0.1)` |
|
|
96
|
+
| `--wui-glass-corner-radius` | `32px` | 描边环径向光影的半径 |
|
|
97
|
+
| `--wui-color-glass-ring` | `rgb(0 0 0 / 0.05)` | 1px 环底色;深色主题为 `rgb(255 255 255 / 0.05)` |
|
|
98
|
+
| `--wui-color-glass-ring-sheen` | `rgb(255 255 255 / 0.5)` | 受光角光泽;深色主题为 `rgb(255 255 255 / 0.2)` |
|
|
99
|
+
| `--wui-color-glass-ring-shade` | `rgb(0 0 0 / 0.03)` | 背光角压暗;深色主题为 `rgb(0 0 0 / 0.5)` |
|
|
100
|
+
| `--wui-shadow-glass` | 四层扩散阴影 | 元素投影;未设置时使用类内默认值 |
|
|
101
|
+
|
|
102
|
+
### .wui-glow
|
|
103
|
+
|
|
104
|
+
给任意容器加 `.wui-glow` 即可,不需要额外组件或 DOM;`web-ui-layout` 的 `header-glow` 与
|
|
105
|
+
collapse 的 peek 边缘用的也是同一份样式。
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<div class="wui-glow">...</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- 渐变与模糊都是容器的背景层,内容始终位于其上方。容器需要有确定的盒子尺寸;`.wui-glow` 只在
|
|
112
|
+
宿主没有其他 `position` 时补 `position: relative`,并加 `isolation: isolate`。
|
|
113
|
+
- 默认从容器顶部向下铺 `--wui-color-page` 渐变,再叠 `blur(4px)`;模糊层向下探出 24px 后收尾。
|
|
114
|
+
容器或祖先的 `overflow: hidden` 会裁掉这段尾巴。
|
|
115
|
+
- 宿主是不透明背景时,渐变会叠在它上方,但模糊采样不到宿主背后的内容——只会模糊自身的纯色背景。
|
|
116
|
+
想要毛玻璃观感,宿主表面应保持半透明。
|
|
117
|
+
|
|
118
|
+
| token | 默认值 | 说明 |
|
|
119
|
+
| ------------------------------- | -------------------------------------- | ------------------------------------------- |
|
|
120
|
+
| `--wui-glow-color` | `var(--wui-color-page, #fff)` | 渐变起点色 |
|
|
121
|
+
| `--wui-glow-gradient-direction` | `to bottom` | `linear-gradient` 的方向 |
|
|
122
|
+
| `--wui-glow-gradient` | 由起点色与方向生成的 `linear-gradient` | 完整 background-image;设 `none` 关闭渐变 |
|
|
123
|
+
| `--wui-glow-blur` | `4px` | `backdrop-filter` 模糊半径;设 `0px` 关闭 |
|
|
124
|
+
| `--wui-glow-overhang` | `24px` | 模糊层向容器下方探出的高度 |
|
|
125
|
+
| `--wui-glow-fade` | `36px` | 从全强度到透明的衰减总长,应不小于 overhang |
|
|
126
|
+
|
|
63
127
|
## Vite
|
|
64
128
|
|
|
65
129
|
`@greypan/web-ui/vite` 导出 `webUiOptimizeDeps`,即需要并进应用 `optimizeDeps.include` 的 web-ui 运行时
|
|
@@ -305,44 +369,44 @@ dropdown、tooltip)不需要它。
|
|
|
305
369
|
|
|
306
370
|
每个组件都有自己的文档页,API 参考、行为说明和可交互示例都在 [`docs/`](./docs/) 下。下面的表只是索引。
|
|
307
371
|
|
|
308
|
-
| 分类 | 组件
|
|
309
|
-
| --------------------- |
|
|
310
|
-
| **表单控件** | [`<web-ui-input>`](./docs/input.md) |
|
|
311
|
-
| | [`<web-ui-textarea>`](./docs/textarea.md) |
|
|
312
|
-
| | [`<web-ui-editable-text>`](./docs/editable-text.md) |
|
|
313
|
-
| | [`<web-ui-input-number>`](./docs/input-number.md) |
|
|
314
|
-
| | [`<web-ui-select>`](./docs/select.md) |
|
|
315
|
-
| | [`<web-ui-autocomplete>`](./docs/autocomplete.md) |
|
|
316
|
-
| | [`<web-ui-slider>`](./docs/slider.md) |
|
|
317
|
-
| | [`<web-ui-checkbox>`](./docs/checkbox.md) |
|
|
318
|
-
| | [`<web-ui-radio>`](./docs/radio.md) |
|
|
319
|
-
| | [`<web-ui-switch>`](./docs/switch.md) |
|
|
320
|
-
| | [`<web-ui-segmented>`](./docs/segmented.md) |
|
|
321
|
-
| | [`<web-ui-checkbox-group>`](./docs/checkbox-group.md) |
|
|
322
|
-
| | [`<web-ui-radio-group>`](./docs/radio-group.md) |
|
|
323
|
-
| **button** | [`<web-ui-button>`](./docs/button.md) |
|
|
324
|
-
| | [`<web-ui-button-group>`](./docs/button-group.md) |
|
|
325
|
-
| **overlay / 模态** | [`<web-ui-dialog>`](./docs/dialog.md) |
|
|
326
|
-
| | [`<web-ui-drawer>`](./docs/drawer.md) |
|
|
327
|
-
| | [`imagePreview()`](./docs/image-preview.md) |
|
|
328
|
-
| **文档流 Disclosure** | [`<web-ui-collapse>`](./docs/collapse.md) |
|
|
329
|
-
| **浮动** | [`<web-ui-popover>`](./docs/popover.md) |
|
|
330
|
-
| | [`<web-ui-tooltip>`](./docs/tooltip.md) |
|
|
331
|
-
| | [`<web-ui-context-menu>`](./docs/context-menu.md) |
|
|
332
|
-
| **menu** | [`<web-ui-dropdown>`](./docs/dropdown.md) |
|
|
333
|
-
| | [`<web-ui-dropdown-item>`](./docs/dropdown-item.md) |
|
|
334
|
-
| | [`<web-ui-dropdown-divider>`](./docs/dropdown-divider.md) |
|
|
335
|
-
| | [`<web-ui-dropdown-header>`](./docs/dropdown-header.md) |
|
|
336
|
-
| **数据展示** | [`<web-ui-avatar>`](./docs/avatar.md) |
|
|
337
|
-
| | [`<web-ui-badge>`](./docs/badge.md) |
|
|
338
|
-
| | [`<web-ui-empty>`](./docs/empty.md) |
|
|
339
|
-
| | [`<web-ui-middle-ellipsis>`](./docs/middle-ellipsis.md) |
|
|
340
|
-
| | [`<web-ui-icon>`](./docs/icon.md) |
|
|
341
|
-
| | [`<web-ui-spinner>`](./docs/spinner.md) |
|
|
342
|
-
| **布局与工具** | [`<web-ui-layout>`](./docs/layout.md) |
|
|
343
|
-
| | [`<web-ui-back-top>`](./docs/back-top.md) |
|
|
344
|
-
| | [`<web-ui-svg-draw-lines>`](./docs/svg-draw-lines.md) |
|
|
345
|
-
| | [`<web-ui-theme>`](./docs/theme.md) |
|
|
346
|
-
| **通知** | [`<web-ui-toast>`](./docs/toast.md) |
|
|
347
|
-
| **子项** | [`<web-ui-option>`](./docs/option.md) |
|
|
348
|
-
| | [`<web-ui-segmented-trigger>`](./docs/segmented-trigger.md) |
|
|
372
|
+
| 分类 | 组件 |
|
|
373
|
+
| --------------------- | -------------------------------------------------------------- |
|
|
374
|
+
| **表单控件** | [`<web-ui-input>`](./docs/input.CN.md) |
|
|
375
|
+
| | [`<web-ui-textarea>`](./docs/textarea.CN.md) |
|
|
376
|
+
| | [`<web-ui-editable-text>`](./docs/editable-text.CN.md) |
|
|
377
|
+
| | [`<web-ui-input-number>`](./docs/input-number.CN.md) |
|
|
378
|
+
| | [`<web-ui-select>`](./docs/select.CN.md) |
|
|
379
|
+
| | [`<web-ui-autocomplete>`](./docs/autocomplete.CN.md) |
|
|
380
|
+
| | [`<web-ui-slider>`](./docs/slider.CN.md) |
|
|
381
|
+
| | [`<web-ui-checkbox>`](./docs/checkbox.CN.md) |
|
|
382
|
+
| | [`<web-ui-radio>`](./docs/radio.CN.md) |
|
|
383
|
+
| | [`<web-ui-switch>`](./docs/switch.CN.md) |
|
|
384
|
+
| | [`<web-ui-segmented>`](./docs/segmented.CN.md) |
|
|
385
|
+
| | [`<web-ui-checkbox-group>`](./docs/checkbox-group.CN.md) |
|
|
386
|
+
| | [`<web-ui-radio-group>`](./docs/radio-group.CN.md) |
|
|
387
|
+
| **button** | [`<web-ui-button>`](./docs/button.CN.md) |
|
|
388
|
+
| | [`<web-ui-button-group>`](./docs/button-group.CN.md) |
|
|
389
|
+
| **overlay / 模态** | [`<web-ui-dialog>`](./docs/dialog.CN.md) |
|
|
390
|
+
| | [`<web-ui-drawer>`](./docs/drawer.CN.md) |
|
|
391
|
+
| | [`imagePreview()`](./docs/image-preview.CN.md) |
|
|
392
|
+
| **文档流 Disclosure** | [`<web-ui-collapse>`](./docs/collapse.CN.md) |
|
|
393
|
+
| **浮动** | [`<web-ui-popover>`](./docs/popover.CN.md) |
|
|
394
|
+
| | [`<web-ui-tooltip>`](./docs/tooltip.CN.md) |
|
|
395
|
+
| | [`<web-ui-context-menu>`](./docs/context-menu.CN.md) |
|
|
396
|
+
| **menu** | [`<web-ui-dropdown>`](./docs/dropdown.CN.md) |
|
|
397
|
+
| | [`<web-ui-dropdown-item>`](./docs/dropdown-item.CN.md) |
|
|
398
|
+
| | [`<web-ui-dropdown-divider>`](./docs/dropdown-divider.CN.md) |
|
|
399
|
+
| | [`<web-ui-dropdown-header>`](./docs/dropdown-header.CN.md) |
|
|
400
|
+
| **数据展示** | [`<web-ui-avatar>`](./docs/avatar.CN.md) |
|
|
401
|
+
| | [`<web-ui-badge>`](./docs/badge.CN.md) |
|
|
402
|
+
| | [`<web-ui-empty>`](./docs/empty.CN.md) |
|
|
403
|
+
| | [`<web-ui-middle-ellipsis>`](./docs/middle-ellipsis.CN.md) |
|
|
404
|
+
| | [`<web-ui-icon>`](./docs/icon.CN.md) |
|
|
405
|
+
| | [`<web-ui-spinner>`](./docs/spinner.CN.md) |
|
|
406
|
+
| **布局与工具** | [`<web-ui-layout>`](./docs/layout.CN.md) |
|
|
407
|
+
| | [`<web-ui-back-top>`](./docs/back-top.CN.md) |
|
|
408
|
+
| | [`<web-ui-svg-draw-lines>`](./docs/svg-draw-lines.CN.md) |
|
|
409
|
+
| | [`<web-ui-theme>`](./docs/theme.CN.md) |
|
|
410
|
+
| **通知** | [`<web-ui-toast>`](./docs/toast.CN.md) |
|
|
411
|
+
| **子项** | [`<web-ui-option>`](./docs/option.CN.md) |
|
|
412
|
+
| | [`<web-ui-segmented-trigger>`](./docs/segmented-trigger.CN.md) |
|
package/README.md
CHANGED
|
@@ -64,6 +64,75 @@ import { OverlayScrollbarsComponent } from 'overlayscrollbars-react' // or overl
|
|
|
64
64
|
not do. Import this stylesheet for the internal scrollbars to follow the appearance, just like the
|
|
65
65
|
page-level ones.
|
|
66
66
|
|
|
67
|
+
## Classes
|
|
68
|
+
|
|
69
|
+
`@greypan/web-ui/classes.css` bundles the reusable public classes shared by components and consumers:
|
|
70
|
+
`.wui-glass` (frosted surface) and `.wui-glow` (decorative backdrop).
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
import '@greypan/web-ui/classes.css'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### .wui-glass
|
|
77
|
+
|
|
78
|
+
Add `.wui-glass` to any container for a frosted surface. Components use the same stylesheet internally
|
|
79
|
+
(drawer body, dialog / toast, tooltip / popover, input, and so on).
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<div class="wui-glass">...</div>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- It provides the translucent background, the `backdrop-filter` (blur / saturation / brightness), the
|
|
86
|
+
element's own inset highlight and shadow, and a 1px ring cut out with `::before`: the ring lights the
|
|
87
|
+
top-left / bottom-right corners and shades the top-right / bottom-left ones, with the radius controlled
|
|
88
|
+
by `--wui-glass-corner-radius`.
|
|
89
|
+
- The container needs a box size and a background that can be sampled. `.wui-glass` only adds
|
|
90
|
+
`position: relative` when the host has no other `position`, and removes the host's own border (the ring
|
|
91
|
+
replaces it); the corner radius still follows the host's `border-radius`.
|
|
92
|
+
- For non-pill surfaces, override `--wui-glass-corner-radius` with a value derived from the element's own
|
|
93
|
+
radius, otherwise the corner lighting will not match the box shape. Colours come from the theme with
|
|
94
|
+
separate light / dark defaults; prefer overriding tokens over rewriting `backdrop-filter`.
|
|
95
|
+
|
|
96
|
+
| token | default | description |
|
|
97
|
+
| ------------------------------ | ------------------------- | ---------------------------------------------------- |
|
|
98
|
+
| `--wui-color-surface-glass` | `rgb(250 250 250 / 0.34)` | Translucent surface; `rgb(44 44 46 / 0.42)` in dark |
|
|
99
|
+
| `--wui-glass-blur` | `4px` | `backdrop-filter` radius; set `0px` to disable |
|
|
100
|
+
| `--wui-glass-saturation` | `160%` | Backdrop saturation |
|
|
101
|
+
| `--wui-glass-brightness` | `1.06` | Backdrop brightness; `1.02` in dark |
|
|
102
|
+
| `--wui-color-glass-highlight` | `rgb(255 255 255 / 0.9)` | Inset highlight; `rgb(255 255 255 / 0.1)` in dark |
|
|
103
|
+
| `--wui-glass-corner-radius` | `32px` | Radius of the ring's corner lighting |
|
|
104
|
+
| `--wui-color-glass-ring` | `rgb(0 0 0 / 0.05)` | 1px ring base; `rgb(255 255 255 / 0.05)` in dark |
|
|
105
|
+
| `--wui-color-glass-ring-sheen` | `rgb(255 255 255 / 0.5)` | Lit-corner sheen; `rgb(255 255 255 / 0.2)` in dark |
|
|
106
|
+
| `--wui-color-glass-ring-shade` | `rgb(0 0 0 / 0.03)` | Unlit-corner shade; `rgb(0 0 0 / 0.5)` in dark |
|
|
107
|
+
| `--wui-shadow-glass` | four-layer diffuse shadow | Element shadow; the class default applies when unset |
|
|
108
|
+
|
|
109
|
+
### .wui-glow
|
|
110
|
+
|
|
111
|
+
Add `.wui-glow` to any container; no extra component or DOM is needed. `web-ui-layout`'s
|
|
112
|
+
`header-glow` and collapse's peek edge use the same stylesheet.
|
|
113
|
+
|
|
114
|
+
```html
|
|
115
|
+
<div class="wui-glow">...</div>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- Both the gradient and the blur are background layers; content always sits above them. The container
|
|
119
|
+
needs a box size. `.wui-glow` only adds `position: relative` when the host has no other `position`, and
|
|
120
|
+
adds `isolation: isolate`.
|
|
121
|
+
- By default it lays a `--wui-color-page` gradient from the top edge down, then overlays `blur(4px)`; the
|
|
122
|
+
blurred layer extends 24px below the container before fading out. `overflow: hidden` on the container or
|
|
123
|
+
an ancestor clips that tail.
|
|
124
|
+
- On an opaque host the gradient still shows above its background, but the blur cannot sample what is behind
|
|
125
|
+
the host — it only blurs the host's own flat colour. Keep the host surface translucent for a frosted look.
|
|
126
|
+
|
|
127
|
+
| token | default | description |
|
|
128
|
+
| ------------------------------- | ----------------------------------------------- | ---------------------------------------------------- |
|
|
129
|
+
| `--wui-glow-color` | `var(--wui-color-page, #fff)` | Gradient start colour |
|
|
130
|
+
| `--wui-glow-gradient-direction` | `to bottom` | `linear-gradient` direction |
|
|
131
|
+
| `--wui-glow-gradient` | `linear-gradient` built from colour + direction | Full background-image; set `none` to disable |
|
|
132
|
+
| `--wui-glow-blur` | `4px` | `backdrop-filter` radius; set `0px` to disable |
|
|
133
|
+
| `--wui-glow-overhang` | `24px` | How far the blurred layer extends below the box |
|
|
134
|
+
| `--wui-glow-fade` | `36px` | Full-strength-to-transparent length; keep ≥ overhang |
|
|
135
|
+
|
|
67
136
|
## Vite
|
|
68
137
|
|
|
69
138
|
`@greypan/web-ui/vite` exports `webUiOptimizeDeps`, the list of web-ui runtime dependencies an app has to merge
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/assets/overlay-motion.css?inline
|
|
2
|
-
var e = ".wui-floating-panel{transform-origin:var(--wui-internal-overlay-transform-origin,center);opacity:1;-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));transition:opacity var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1)), -webkit-backdrop-filter var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1)), backdrop-filter var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1)), transform var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1));transform:scale(1)}.wui-floating-panel[data-wui-presence=entering],.wui-floating-panel[data-wui-presence=closing]{transform:scale(var(--wui-scale-enter,.9));opacity:0;-webkit-backdrop-filter:blur(0) saturate(160%) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(0) saturate(160%) brightness(var(--wui-glass-brightness,1.06))}.wui-floating-panel[data-wui-presence=closing]{pointer-events:none;transition-duration:var(--wui-internal-duration-float-exit,var(--wui-duration-float-exit,.16s))}@media (prefers-reduced-motion:reduce){.wui-floating-panel,.wui-floating-panel[data-wui-presence=entering],.wui-floating-panel[data-wui-presence=closing]{transition-duration:.12s;transform:none}}";
|
|
2
|
+
var e = ".wui-floating-panel{transform-origin:var(--wui-internal-overlay-transform-origin,center);opacity:1;-webkit-backdrop-filter:blur(var(--wui-glass-blur,4px)) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(var(--wui-glass-blur,4px)) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06));transition:opacity var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1)), -webkit-backdrop-filter var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1)), backdrop-filter var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1)), transform var(--wui-internal-duration-float-enter,var(--wui-duration-float-enter,.24s)) var(--wui-ease-float,cubic-bezier(.4, .38, .2, 1));transform:scale(1)}.wui-floating-panel[data-wui-presence=entering],.wui-floating-panel[data-wui-presence=closing]{transform:scale(var(--wui-scale-enter,.9));opacity:0;-webkit-backdrop-filter:blur(0) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(0) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06))}.wui-floating-panel[data-wui-presence=closing]{pointer-events:none;transition-duration:var(--wui-internal-duration-float-exit,var(--wui-duration-float-exit,.16s))}@media (prefers-reduced-motion:reduce){.wui-floating-panel,.wui-floating-panel[data-wui-presence=entering],.wui-floating-panel[data-wui-presence=closing]{transition-duration:.12s;transform:none}}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay-motion.js","names":[],"sources":["../../src/assets/overlay-motion.css?inline"],"sourcesContent":["/*\n * overlay panel 共享动效(单层玻璃)。\n *\n * backdrop-filter 的 blur(0px) ↔ blur(4px) 在 Chrome/Safari 均平滑插值(Manager\n * 双引擎实测,Safari 逐帧采样 blur 值连续),当年「生硬跳变」的根因是 none↔blur\n * 不可插值,而不是 backdrop-filter 不可动画。因此 panel 自身直接承担玻璃:背景、\n * 阴影与 backdrop-filter 都在 panel 元素上(wui-glass 类也回 panel),打开/关闭时\n * opacity 与 backdrop-filter 同步过渡,无需双层结构——双层带来的全部层间问题\n * (变白、关闭残影、双重模糊、阴影作用域承接)一并消失。\n */\n\n.wui-floating-panel {\n transform-origin: var(--wui-internal-overlay-transform-origin, center);\n transform: scale(1);\n\n opacity: 1;\n\n /* 玻璃由 panel 自身承担(wui-glass 提供背景/描边/阴影)。打开目标态 blur(4px),\n entering/closing 切到 blur(0px) 作为插值起点——blur(0px) 与 blur(4px) 平滑过渡\n (none↔blur 不可插值才是当年生硬跳变的根因)。 */\n backdrop-filter: blur(4px) saturate(160%)
|
|
1
|
+
{"version":3,"file":"overlay-motion.js","names":[],"sources":["../../src/assets/overlay-motion.css?inline"],"sourcesContent":["/*\n * overlay panel 共享动效(单层玻璃)。\n *\n * backdrop-filter 的 blur(0px) ↔ blur(4px) 在 Chrome/Safari 均平滑插值(Manager\n * 双引擎实测,Safari 逐帧采样 blur 值连续),当年「生硬跳变」的根因是 none↔blur\n * 不可插值,而不是 backdrop-filter 不可动画。因此 panel 自身直接承担玻璃:背景、\n * 阴影与 backdrop-filter 都在 panel 元素上(wui-glass 类也回 panel),打开/关闭时\n * opacity 与 backdrop-filter 同步过渡,无需双层结构——双层带来的全部层间问题\n * (变白、关闭残影、双重模糊、阴影作用域承接)一并消失。\n */\n\n.wui-floating-panel {\n transform-origin: var(--wui-internal-overlay-transform-origin, center);\n transform: scale(1);\n\n opacity: 1;\n\n /* 玻璃由 panel 自身承担(wui-glass 提供背景/描边/阴影)。打开目标态 blur(4px),\n entering/closing 切到 blur(0px) 作为插值起点——blur(0px) 与 blur(4px) 平滑过渡\n (none↔blur 不可插值才是当年生硬跳变的根因)。 */\n backdrop-filter: blur(var(--wui-glass-blur, 4px)) saturate(var(--wui-glass-saturation, 160%))\n brightness(var(--wui-glass-brightness, 1.06));\n\n /* transition 列表需手写 -webkit-backdrop-filter:lightningcss 不会在 transition\n value 内追加 -webkit 项,iOS 16.4 上 blur 过渡依赖它(属性前缀会自动生成)。\n 缓动取 --wui-ease-float:--wui-ease-enter 会在开局就冲到 85% 进度,锚定 panel 的展开\n 需要可读的过程。 */\n transition:\n opacity var(--wui-internal-duration-float-enter, var(--wui-duration-float-enter, 240ms))\n var(--wui-ease-float, cubic-bezier(0.4, 0.38, 0.2, 1)),\n -webkit-backdrop-filter var(--wui-internal-duration-float-enter, var(--wui-duration-float-enter, 240ms))\n var(--wui-ease-float, cubic-bezier(0.4, 0.38, 0.2, 1)),\n backdrop-filter var(--wui-internal-duration-float-enter, var(--wui-duration-float-enter, 240ms))\n var(--wui-ease-float, cubic-bezier(0.4, 0.38, 0.2, 1)),\n transform var(--wui-internal-duration-float-enter, var(--wui-duration-float-enter, 240ms))\n var(--wui-ease-float, cubic-bezier(0.4, 0.38, 0.2, 1));\n}\n\n.wui-floating-panel[data-wui-presence='entering'],\n.wui-floating-panel[data-wui-presence='closing'] {\n transform: scale(var(--wui-scale-enter, 0.9));\n opacity: 0;\n backdrop-filter: blur(0) saturate(var(--wui-glass-saturation, 160%)) brightness(var(--wui-glass-brightness, 1.06));\n}\n\n.wui-floating-panel[data-wui-presence='closing'] {\n pointer-events: none;\n transition-duration: var(--wui-internal-duration-float-exit, var(--wui-duration-float-exit, 160ms));\n}\n\n@media (prefers-reduced-motion: reduce) {\n .wui-floating-panel,\n .wui-floating-panel[data-wui-presence='entering'],\n .wui-floating-panel[data-wui-presence='closing'] {\n transform: none;\n transition-duration: 120ms;\n }\n}\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/assets/selection-control.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{cursor:default;vertical-align:middle;align-items:center;display:inline-flex}:host([disabled]){cursor:not-allowed}:where(.wui-radio,.wui-checkbox){cursor:inherit;-webkit-user-select:none;user-select:none;font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);align-items:center;gap:10px;line-height:1;display:inline-flex}:where(.wui-radio,.wui-checkbox):focus-visible{border-radius:var(--wui-radius-control,calc(infinity * 1px));outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{cursor:default;vertical-align:middle;align-items:center;display:inline-flex}:host([disabled]){cursor:not-allowed}:where(.wui-radio,.wui-checkbox){cursor:inherit;-webkit-user-select:none;user-select:none;font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);align-items:center;gap:10px;line-height:1;display:inline-flex}:where(.wui-radio,.wui-checkbox):focus-visible{border-radius:var(--wui-radius-control,calc(infinity * 1px));outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#0071e3) 40%, transparent));outline-offset:2px}:where(.wui-radio.is-label-empty,.wui-checkbox.is-label-empty){gap:0}:host([data-wui-pointer-focus]) :where(.wui-radio,.wui-checkbox):focus-visible{outline-color:#0000}:where(.wui-radio.is-disabled,.wui-checkbox.is-disabled){cursor:not-allowed;color:var(--wui-color-text-secondary,#6a6a6a);opacity:.4}:where(.wui-radio-circle,.wui-checkbox-box){isolation:isolate;width:var(--wui-selection-control-size,18px);height:var(--wui-selection-control-size,18px);background-color:var(--wui-color-surface-control,#dfdfdf);transition:background-color var(--wui-duration-trigger,.16s) ease;flex-shrink:0;justify-content:center;align-items:center;display:flex;position:relative}:where(.wui-radio-circle,.wui-checkbox-box):before{content:\"\";z-index:-1;border-radius:inherit;position:absolute;inset:0}:where(.wui-radio-label,.wui-checkbox-label){pointer-events:none}@media (hover:hover) and (pointer:fine){:where(.wui-radio,.wui-checkbox):hover:not(.is-disabled,.is-checked) :where(.wui-radio-circle,.wui-checkbox-box):before{background-color:color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent)}}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-control.js","names":[],"sources":["../../src/assets/selection-control.css?inline"],"sourcesContent":["/*\n * radio / checkbox 共享外壳。\n *\n * indicator 只有 18px。宿主一旦走 inline-block,页面行高会在宿主内生成匿名行盒,把盒子撑到\n * 行高(Tailwind preflight 下是 24px),且多出的空隙落在哪一侧取决于内部基线落点,radio 与\n * checkbox 因此一个贴顶一个贴底。改成 inline-flex 后宿主高度由内容决定,行高不再参与,\n * 与相邻文字的对齐交给 vertical-align 显式声明。\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: default;\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n/* :where() 保持零特异性,组件级配置(圆角、选中色、内部图形)始终覆盖共享层。 */\n:where(.wui-radio, .wui-checkbox) {\n cursor: inherit;\n user-select: none;\n\n display: inline-flex;\n gap: 10px;\n align-items: center;\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text, #1b1b1b);\n\n &:focus-visible {\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #
|
|
1
|
+
{"version":3,"file":"selection-control.js","names":[],"sources":["../../src/assets/selection-control.css?inline"],"sourcesContent":["/*\n * radio / checkbox 共享外壳。\n *\n * indicator 只有 18px。宿主一旦走 inline-block,页面行高会在宿主内生成匿名行盒,把盒子撑到\n * 行高(Tailwind preflight 下是 24px),且多出的空隙落在哪一侧取决于内部基线落点,radio 与\n * checkbox 因此一个贴顶一个贴底。改成 inline-flex 后宿主高度由内容决定,行高不再参与,\n * 与相邻文字的对齐交给 vertical-align 显式声明。\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: default;\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n/* :where() 保持零特异性,组件级配置(圆角、选中色、内部图形)始终覆盖共享层。 */\n:where(.wui-radio, .wui-checkbox) {\n cursor: inherit;\n user-select: none;\n\n display: inline-flex;\n gap: 10px;\n align-items: center;\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text, #1b1b1b);\n\n &:focus-visible {\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #0071e3) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n/*\n * label 没有可渲染内容时把间距一并收掉。gap 只认「这里有个 flex item」,不认它有没有宽度,所以空槽位\n * 或只挂了一个视觉隐藏的无障碍名时,indicator 右边照样多出这一段;判据见 LabelEmptinessController。\n */\n:where(.wui-radio.is-label-empty, .wui-checkbox.is-label-empty) {\n gap: 0;\n}\n\n:host([data-wui-pointer-focus]) :where(.wui-radio, .wui-checkbox):focus-visible {\n outline-color: transparent;\n}\n\n:where(.wui-radio.is-disabled, .wui-checkbox.is-disabled) {\n cursor: not-allowed;\n color: var(--wui-color-text-secondary, #6a6a6a);\n opacity: 0.4;\n}\n\n/*\n * indicator 底色取控件档。surface-raised 在深色下(#2c2c2e)离页面底色(#242628)只有 8 个\n * 亮度点,未选中时几乎看不出有一个圆/方框;surface-control 才是主题里「控件自己的底」\n * 那一档(中性 button 同档),深色比页面高 22 个亮度点,浅色下也从近白的 #f2f2f7 变成可读的 #dfdfdf。\n */\n:where(.wui-radio-circle, .wui-checkbox-box) {\n isolation: isolate;\n position: relative;\n\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: var(--wui-selection-control-size, 18px);\n height: var(--wui-selection-control-size, 18px);\n\n background-color: var(--wui-color-surface-control, #dfdfdf);\n\n transition: background-color var(--wui-duration-trigger, 160ms) ease;\n}\n\n/*\n * 状态层走覆盖层,不占用 indicator 自己的 background-color:同一个属性没法一半过渡一半即时,\n * 而这里要的是 hover 当帧切换、选中态的 accent 按 --wui-duration-trigger 淡入淡出。\n * z-index: -1 配父级 isolation 把覆盖层夹在控件底与圆点/勾之间,半径跟着 indicator 走。\n */\n:where(.wui-radio-circle, .wui-checkbox-box)::before {\n content: '';\n\n position: absolute;\n z-index: -1;\n inset: 0;\n\n border-radius: inherit;\n}\n\n:where(.wui-radio-label, .wui-checkbox-label) {\n pointer-events: none;\n}\n\n/*\n * 未激活态的 hover 状态层。用半透明色而不是混进控件底:覆盖层本就压在不透明的控件底上,\n * 合成结果与 color-mix(text 6%, surface-control) 一致,深色档同样成立。\n * label 文字带 pointer-events: none,命中落回交互元素自身,所以整条触发区(含右侧文字)\n * 的 hover 都会作用到 indicator。hover 只在真正的指针设备上生效,避免触屏留态。\n */\n@media (hover: hover) and (pointer: fine) {\n :where(.wui-radio, .wui-checkbox):hover:not(.is-disabled, .is-checked)\n :where(.wui-radio-circle, .wui-checkbox-box)::before {\n background-color: color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent);\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/classes/glass.css?inline
|
|
2
|
+
var e = ":where(.wui-glass){position:relative}.wui-glass{--wui-internal-glass-shadow:var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004);background-color:var(--wui-color-surface-glass,#fafafa57);-webkit-backdrop-filter:blur(var(--wui-glass-blur,4px)) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(var(--wui-glass-blur,4px)) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06));box-shadow:inset 0 0 0 .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 38%, transparent), inset 0 1px .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 52%, transparent), inset 0 -.5px 1px #00000008, var(--wui-internal-glass-shadow,var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004));background-clip:padding-box;border:none}.wui-glass:before{pointer-events:none;content:\"\";border-radius:inherit;background-color:var(--wui-color-glass-ring,#0000000d);background-image:radial-gradient(var(--wui-glass-corner-radius,32px) at 100% 0, var(--wui-color-glass-ring-shade,#00000008), transparent), radial-gradient(var(--wui-glass-corner-radius,32px) at 0 100%, var(--wui-color-glass-ring-shade,#00000008), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 0 0, var(--wui-color-glass-ring-sheen,#ffffff80), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 100% 100%, var(--wui-color-glass-ring-sheen,#ffffff80), transparent);-webkit-mask-composite:xor;-webkit-mask-source-type:auto,auto;padding:1px;position:absolute;inset:0;-webkit-mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;-webkit-mask-size:auto,auto;mask-size:auto,auto;-webkit-mask-repeat:repeat,repeat;mask-repeat:repeat,repeat;-webkit-mask-clip:content-box,border-box;mask-clip:content-box,border-box;-webkit-mask-origin:content-box,border-box;mask-origin:content-box,border-box;-webkit-mask-composite:xor;mask-composite:exclude;-webkit-mask-source-type:auto,auto;mask-mode:match-source,match-source}";
|
|
3
|
+
//#endregion
|
|
4
|
+
export { e as default };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=glass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glass.js","names":[],"sources":["../../src/classes/glass.css?inline"],"sourcesContent":["/* 只在宿主没有其他 position 时补定位,避免盖掉消费方的绝对/固定定位。 */\n:where(.wui-glass) {\n position: relative;\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.02),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n );\n\n border: none;\n\n background-color: var(--wui-color-surface-glass, rgb(250 250 250 / 0.34));\n background-clip: padding-box;\n\n /* Safari 16.4 只支持带 -webkit- 前缀的 backdrop-filter(无前缀 18 才支持);\n 前缀由 lightningcss 按 ?inline 管线默认 targets(含 ios16.4)自动生成,无需手写。 */\n backdrop-filter: blur(var(--wui-glass-blur, 4px)) saturate(var(--wui-glass-saturation, 160%))\n brightness(var(--wui-glass-brightness, 1.06));\n box-shadow:\n inset 0 0 0 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 38%, transparent),\n inset 0 1px 0.5px color-mix(in srgb, var(--wui-color-glass-highlight, rgb(255 255 255 / 0.9)) 52%, transparent),\n inset 0 -0.5px 1px rgb(0 0 0 / 0.03),\n var(\n --wui-internal-glass-shadow,\n var(\n --wui-shadow-glass,\n 0 0 1px rgb(0 0 0 / 0.02),\n 0 0 8px rgb(0 0 0 / 0.03),\n 0 2px 16px rgb(0 0 0 / 0.025),\n 0 8px 32px rgb(0 0 0 / 0.015)\n )\n );\n}\n\n/*\n * 玻璃描边环:底色铺满整圈,其上叠两枚 sheen→transparent radial 作左上/右下受光\n * 光泽,再叠两枚 shade→transparent radial(置于最上层)压暗右上/左下背光角,形成\n * 对角光影的玻璃立体感。\n *\n * 底色(--wui-color-glass-ring)不是可选项:四枚 radial 全部锚定角点、半径固定\n * (R = --wui-glass-corner-radius,sheen 用 2R、shade 用 R),一条边只有长过约 3R\n * 才有一段落在所有 radial 之外。底色是唯一覆盖那一段的一层,也是圆角弧段(如 pill\n * 的半圆端)不发暗的原因。三枚 token 同属 ring 前缀,因为它们共同描述这一枚环,\n * 而非三个独立效果。\n *\n * 底色字面量取明色值 rgb(0 0 0 / 0.05) 而非 transparent:本文件其余玻璃 token 的\n * fallback 一律等于明色真值(surface-glass / brightness / highlight / sheen / shade),\n * token 缺省时(未挂 <web-ui-theme>,或 theme 未设 appearance —— 颜色 token 只定义在\n * [appearance] 三个选择器下)整套玻璃面就是明色观感,这一层没有理由例外。\n *\n * 渐变半径为 --wui-glass-corner-radius 的固定物理尺寸正圆——视觉覆盖范围不随元素\n * 宽高缩放(百分比方案在大 panel 上暗边过长、小控件上过弱),各组件用与自身\n * border-radius 同源的值覆盖该变量即可联动。\n *\n * 同源的 --wui-color-glass-highlight 不在此层:它是元素自身 box-shadow 的 inset\n * 高光,与本环无关。-webkit-mask-* 旧语法(含 mask-composite:xor)由 lightningcss\n * 按 targets 自动生成,无前缀 mask-composite 留给 Chrome 120+。\n */\n.wui-glass::before {\n pointer-events: none;\n content: '';\n\n position: absolute;\n inset: 0;\n\n padding: 1px;\n border-radius: inherit;\n\n background-color: var(--wui-color-glass-ring, rgb(0 0 0 / 0.05));\n background-image:\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 100% 0,\n var(--wui-color-glass-ring-shade, rgb(0 0 0 / 0.03)),\n transparent\n ),\n radial-gradient(\n var(--wui-glass-corner-radius, 32px) at 0 100%,\n var(--wui-color-glass-ring-shade, rgb(0 0 0 / 0.03)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 0 0,\n var(--wui-color-glass-ring-sheen, rgb(255 255 255 / 0.5)),\n transparent\n ),\n radial-gradient(\n calc(var(--wui-glass-corner-radius, 32px) * 2) at 100% 100%,\n var(--wui-color-glass-ring-sheen, rgb(255 255 255 / 0.5)),\n transparent\n );\n\n mask:\n linear-gradient(#000 0 0) content-box,\n linear-gradient(#000 0 0);\n mask-composite: exclude;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/classes/glow.css?inline
|
|
2
|
+
var e = ":where(.wui-glow){position:relative}.wui-glow{isolation:isolate}.wui-glow:before,.wui-glow:after{pointer-events:none;content:\"\";z-index:-1;border-radius:inherit;position:absolute;inset:0}.wui-glow:before{background:var(--wui-glow-gradient,linear-gradient(var(--wui-glow-gradient-direction,to bottom), var(--wui-glow-color,var(--wui-color-page,#fff)), transparent))}.wui-glow:after{inset:0 0 calc(-1 * var(--wui-glow-overhang,24px));-webkit-backdrop-filter:blur(var(--wui-glow-blur,4px));backdrop-filter:blur(var(--wui-glow-blur,4px));-webkit-mask-image:linear-gradient(to bottom, black 0, black calc(100% - var(--wui-glow-fade,36px)), transparent 100%);-webkit-mask-image:linear-gradient(to bottom, black 0, black calc(100% - var(--wui-glow-fade,36px)), transparent 100%);mask-image:linear-gradient(to bottom, black 0, black calc(100% - var(--wui-glow-fade,36px)), transparent 100%);-webkit-mask-size:100% 100%;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}";
|
|
3
|
+
//#endregion
|
|
4
|
+
export { e as default };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=glow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glow.js","names":[],"sources":["../../src/classes/glow.css?inline"],"sourcesContent":["/*\n * 通用晕染层\n * ==========\n *\n * 给任意有盒子尺寸的容器加一层装饰性背景:::before 画渐变,::after 叠真实模糊\n * (backdrop-filter)。两层都放在 z-index: -1,因此内容与插槽始终位于其上方。\n *\n * 用法是给容器加 `.wui-glow`,并从 `@greypan/web-ui/classes.css` 引入本文件(该文件\n * 同时导出 `.wui-glass`)。组件内部需要同一效果时(如 `header-glow`、collapse peek)\n * 用 `?inline` 引入同一份源码,避免复制规则。\n *\n * 定位与层叠\n * ----------\n * `:where()` 让 position 只做兜底:宿主自己声明了 sticky / absolute / fixed 时一律\n * 让位。`isolation: isolate` 是必要的,否则负层级伪元素会落到更外层 stacking context\n * 的背景之后。容器若有 `overflow: hidden`,向外的模糊尾巴会被裁掉;要保留尾巴就\n * 让 overflow 保持 `visible`。\n *\n * 参数\n * ----\n * 渐变是否出现、颜色与方向都由 token 决定:\n *\n * - `--wui-glow-gradient`:完整 background-image 值;设 `none` 即只保留模糊。\n * - `--wui-glow-gradient-direction`:`linear-gradient` 的方向,默认 `to bottom`。\n * - `--wui-glow-color`:渐变起点色,默认跟随页面底色 `--wui-color-page`。\n * - `--wui-glow-blur`:`backdrop-filter` 的模糊半径,默认 `4px`;设 `0px` 关闭模糊。\n * - `--wui-glow-overhang`:模糊层向盒下探的高度,默认 `24px`。\n * - `--wui-glow-fade`:从全强度到 0 的衰减总长度,默认 `36px`,应不小于 overhang。\n *\n * 盒底缘的 alpha = overhang / fade。旧版对 52px header 是向下外扩 30px、衰减约 45px,\n * 底缘 alpha ≈ 0.67;24 / 36 在同样高度上保持这个强度,盒内曲线与原版基本重合,盒外\n * 只剩 24px 的模糊尾巴。旧版的百分比 mask 会让更高的 header 底缘更淡;新版改用绝对\n * 长度,底缘强度不随容器高度变化。fade 小于 overhang 时,全强度段会延伸到盒外。\n *\n * 端点用裸 `transparent`(即 rgb(0 0 0 / 0))而不是与起点色做 color-mix:后者按\n * 预乘 alpha 混色会得到完全不透明的原色,终点没有羽化。裸 transparent 在渐变插值\n * 中同样按预乘处理,各引擎一致淡到 0,且不引入新色相。\n */\n:where(.wui-glow) {\n position: relative;\n}\n\n.wui-glow {\n isolation: isolate;\n}\n\n.wui-glow::before,\n.wui-glow::after {\n pointer-events: none;\n content: '';\n\n position: absolute;\n z-index: -1;\n inset: 0;\n\n border-radius: inherit;\n}\n\n.wui-glow::before {\n background: var(\n --wui-glow-gradient,\n linear-gradient(\n var(--wui-glow-gradient-direction, to bottom),\n var(--wui-glow-color, var(--wui-color-page, #fff)),\n transparent\n )\n );\n}\n\n.wui-glow::after {\n inset: 0 0 calc(-1 * var(--wui-glow-overhang, 24px));\n\n backdrop-filter: blur(var(--wui-glow-blur, 4px));\n\n mask-image: linear-gradient(to bottom, black 0, black calc(100% - var(--wui-glow-fade, 36px)), transparent 100%);\n mask-repeat: no-repeat;\n mask-size: 100% 100%;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:where(.wui-glass){position:relative}.wui-glass{--wui-internal-glass-shadow:var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004);background-color:var(--wui-color-surface-glass,#fafafa57);-webkit-backdrop-filter:blur(var(--wui-glass-blur,4px)) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06));backdrop-filter:blur(var(--wui-glass-blur,4px)) saturate(var(--wui-glass-saturation,160%)) brightness(var(--wui-glass-brightness,1.06));box-shadow:inset 0 0 0 .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 38%, transparent), inset 0 1px .5px color-mix(in srgb, var(--wui-color-glass-highlight,#ffffffe6) 52%, transparent), inset 0 -.5px 1px #00000008, var(--wui-internal-glass-shadow,var(--wui-shadow-glass,0 0 1px #00000005, 0 0 8px #00000008, 0 2px 16px #00000006, 0 8px 32px #00000004));background-clip:padding-box;border:none}.wui-glass:before{pointer-events:none;content:"";border-radius:inherit;background-color:var(--wui-color-glass-ring,#0000000d);background-image:radial-gradient(var(--wui-glass-corner-radius,32px) at 100% 0, var(--wui-color-glass-ring-shade,#00000008), transparent), radial-gradient(var(--wui-glass-corner-radius,32px) at 0 100%, var(--wui-color-glass-ring-shade,#00000008), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 0 0, var(--wui-color-glass-ring-sheen,#ffffff80), transparent), radial-gradient(calc(var(--wui-glass-corner-radius,32px) * 2) at 100% 100%, var(--wui-color-glass-ring-sheen,#ffffff80), transparent);-webkit-mask-composite:xor;-webkit-mask-source-type:auto,auto;padding:1px;position:absolute;inset:0;-webkit-mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);mask-image:linear-gradient(#000 0 0),linear-gradient(#000 0 0);-webkit-mask-position:0 0,0 0;mask-position:0 0,0 0;-webkit-mask-size:auto,auto;mask-size:auto,auto;-webkit-mask-repeat:repeat,repeat;mask-repeat:repeat,repeat;-webkit-mask-clip:content-box,border-box;mask-clip:content-box,border-box;-webkit-mask-origin:content-box,border-box;mask-origin:content-box,border-box;-webkit-mask-composite:xor;mask-composite:exclude;-webkit-mask-source-type:auto,auto;mask-mode:match-source,match-source}:where(.wui-glow){position:relative}.wui-glow{isolation:isolate}.wui-glow:before,.wui-glow:after{pointer-events:none;content:"";z-index:-1;border-radius:inherit;position:absolute;inset:0}.wui-glow:before{background:var(--wui-glow-gradient,linear-gradient(var(--wui-glow-gradient-direction,to bottom), var(--wui-glow-color,var(--wui-color-page,#fff)), transparent))}.wui-glow:after{inset:0 0 calc(-1 * var(--wui-glow-overhang,24px));-webkit-backdrop-filter:blur(var(--wui-glow-blur,4px));backdrop-filter:blur(var(--wui-glow-blur,4px));-webkit-mask-image:linear-gradient(to bottom, black 0, black calc(100% - var(--wui-glow-fade,36px)), transparent 100%);-webkit-mask-image:linear-gradient(to bottom, black 0, black calc(100% - var(--wui-glow-fade,36px)), transparent 100%);mask-image:linear-gradient(to bottom, black 0, black calc(100% - var(--wui-glow-fade,36px)), transparent 100%);-webkit-mask-size:100% 100%;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
|
|
@@ -417,6 +417,8 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
|
|
|
417
417
|
private _options;
|
|
418
418
|
private _portal?;
|
|
419
419
|
private _portalContent?;
|
|
420
|
+
private _keyboardNavigationActive;
|
|
421
|
+
private _scrollInteractionElement?;
|
|
420
422
|
private readonly _scrollLock;
|
|
421
423
|
private readonly _optionPortal;
|
|
422
424
|
private readonly _trigger;
|
|
@@ -454,12 +456,17 @@ export declare class WebUiAutocomplete extends WebUiAutocomplete_base {
|
|
|
454
456
|
private _handleOptionClick;
|
|
455
457
|
private _onOptionUpdate;
|
|
456
458
|
private _handleOptionPointerOver;
|
|
459
|
+
private _syncScrollInteractionListeners;
|
|
460
|
+
private _clearKeyboardNavigation;
|
|
461
|
+
private _handleListPointerMove;
|
|
462
|
+
private _handleListWheel;
|
|
457
463
|
private _handleOptionPointerDown;
|
|
458
464
|
private _onSlotChange;
|
|
459
465
|
private _onKeydown;
|
|
460
466
|
private _navigateActive;
|
|
461
467
|
private _setInitialActiveOption;
|
|
462
468
|
private _syncActiveOption;
|
|
469
|
+
private _scrollActiveOptionIntoView;
|
|
463
470
|
private _selectOption;
|
|
464
471
|
private _findExactOption;
|
|
465
472
|
private _hasExactOption;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
2
|
-
import t from "../../
|
|
2
|
+
import t from "../../classes/glass.js";
|
|
3
3
|
import { FormAssociated as n, FormAssociationController as r, defineFormAssociation as i } from "../../shared/form-association/index.js";
|
|
4
4
|
import { normalizeLiteral as a } from "../../shared/normalize/index.js";
|
|
5
5
|
import "../input/index.js";
|
|
@@ -49,7 +49,7 @@ var N = class extends n(x) {
|
|
|
49
49
|
typeof e == "string" && (this.value = e);
|
|
50
50
|
},
|
|
51
51
|
syncValidity: () => this._syncValidity()
|
|
52
|
-
}).make(), this._formAssociationController = new r(this, this._formAssociation), this._isOpen = !1, this._activeIndex = -1, this._focused = !1, this._hasTriggerSlot = !1, this._idPrefix = `web-ui-autocomplete-${++k._nextInstanceId}`, this._a11yOptionIds = /* @__PURE__ */ new WeakMap(), this._nextA11yOptionId = 0, this._options = [], this._scrollLock = y().make(), this._optionPortal = m().make({
|
|
52
|
+
}).make(), this._formAssociationController = new r(this, this._formAssociation), this._isOpen = !1, this._activeIndex = -1, this._focused = !1, this._hasTriggerSlot = !1, this._idPrefix = `web-ui-autocomplete-${++k._nextInstanceId}`, this._a11yOptionIds = /* @__PURE__ */ new WeakMap(), this._nextA11yOptionId = 0, this._options = [], this._keyboardNavigationActive = !1, this._scrollLock = y().make(), this._optionPortal = m().make({
|
|
53
53
|
element: this,
|
|
54
54
|
idPrefix: `${this._idPrefix}-option`,
|
|
55
55
|
getPortal: () => this._portal,
|
|
@@ -106,7 +106,11 @@ var N = class extends n(x) {
|
|
|
106
106
|
}, this._onOptionUpdate = () => {
|
|
107
107
|
this._optionPortal.scheduleRefresh();
|
|
108
108
|
}, this._handleOptionPointerOver = (e) => {
|
|
109
|
-
e.pointerType !== "touch" && this._isOpen && e.currentTarget instanceof HTMLElement && (this._activeIndex = -1, this._syncActiveOption());
|
|
109
|
+
e.pointerType !== "touch" && this._isOpen && e.currentTarget instanceof HTMLElement && (this._keyboardNavigationActive || (this._activeIndex = -1, this._syncActiveOption()));
|
|
110
|
+
}, this._handleListPointerMove = () => {
|
|
111
|
+
this._isOpen && this._clearKeyboardNavigation();
|
|
112
|
+
}, this._handleListWheel = () => {
|
|
113
|
+
this._isOpen && this._clearKeyboardNavigation();
|
|
110
114
|
}, this._handleOptionPointerDown = (e) => {
|
|
111
115
|
e.preventDefault();
|
|
112
116
|
}, this._onSlotChange = () => {
|
|
@@ -139,7 +143,7 @@ var N = class extends n(x) {
|
|
|
139
143
|
}
|
|
140
144
|
}
|
|
141
145
|
}, this._onTriggerInput = (e) => {
|
|
142
|
-
this._isDisabled || this.readonly || e !== this._value && (this.value = e, this._activeIndex = -1, this._syncActiveOption(), this._open());
|
|
146
|
+
this._isDisabled || this.readonly || e !== this._value && (this.value = e, this._keyboardNavigationActive = !1, this._activeIndex = -1, this._syncActiveOption(), this._open());
|
|
143
147
|
}, this._onTriggerClick = () => {
|
|
144
148
|
this._isDisabled || this.readonly || this._open();
|
|
145
149
|
}, this._onTriggerFocusIn = (e) => {
|
|
@@ -164,13 +168,13 @@ var N = class extends n(x) {
|
|
|
164
168
|
openOverlay: (e) => this._openOverlay(e),
|
|
165
169
|
closeOverlay: () => void this._closeOverlay(),
|
|
166
170
|
onOpen: (e) => {
|
|
167
|
-
e ? this._setInitialActiveOption() : this._syncActiveOption();
|
|
171
|
+
this._keyboardNavigationActive = e, e ? this._setInitialActiveOption() : this._syncActiveOption();
|
|
168
172
|
},
|
|
169
173
|
onBeforeClose: () => {
|
|
170
174
|
this._optionPortal.syncPortalContent();
|
|
171
175
|
},
|
|
172
176
|
onAfterClose: () => {
|
|
173
|
-
this._activeIndex = -1, this._options.forEach((e) => e.removeAttribute("active"));
|
|
177
|
+
this._keyboardNavigationActive = !1, this._activeIndex = -1, this._options.forEach((e) => e.removeAttribute("active")), this._syncScrollInteractionListeners();
|
|
174
178
|
}
|
|
175
179
|
});
|
|
176
180
|
}
|
|
@@ -234,7 +238,7 @@ var N = class extends n(x) {
|
|
|
234
238
|
});
|
|
235
239
|
}
|
|
236
240
|
disconnectedCallback() {
|
|
237
|
-
super.disconnectedCallback(), this._optionPortal.dispose(), this._trigger.dispose(), this.removeEventListener("keydown", this._onKeydown), this.removeEventListener("focusout", this._onFocusOut), document.removeEventListener("click", this._onClickOutside), this._options.forEach(this._unbindOption), this._close(), this._portal = void 0, this._portalContent = void 0, this._panel.dispose(), this._scrollLock.release();
|
|
241
|
+
super.disconnectedCallback(), this._optionPortal.dispose(), this._trigger.dispose(), this.removeEventListener("keydown", this._onKeydown), this.removeEventListener("focusout", this._onFocusOut), document.removeEventListener("click", this._onClickOutside), this._options.forEach(this._unbindOption), this._close(), this._syncScrollInteractionListeners(), this._portal = void 0, this._portalContent = void 0, this._panel.dispose(), this._scrollLock.release();
|
|
238
242
|
}
|
|
239
243
|
firstUpdated() {
|
|
240
244
|
this._trigger.bind(), requestAnimationFrame(() => {
|
|
@@ -292,18 +296,34 @@ var N = class extends n(x) {
|
|
|
292
296
|
let e = this._options[this._activeIndex], t = this._optionPortal.refresh(this._options, e);
|
|
293
297
|
this._options = t.options, this._activeIndex = t.activeIndex;
|
|
294
298
|
}
|
|
299
|
+
_syncScrollInteractionListeners() {
|
|
300
|
+
let e = this._isOpen ? this._panel.getPanel()?.querySelector(".autocomplete-scroll") : void 0;
|
|
301
|
+
e !== this._scrollInteractionElement && (this._scrollInteractionElement?.removeEventListener("pointermove", this._handleListPointerMove), this._scrollInteractionElement?.removeEventListener("wheel", this._handleListWheel), this._scrollInteractionElement = e ?? void 0, this._scrollInteractionElement?.addEventListener("pointermove", this._handleListPointerMove), this._scrollInteractionElement?.addEventListener("wheel", this._handleListWheel));
|
|
302
|
+
}
|
|
303
|
+
_clearKeyboardNavigation() {
|
|
304
|
+
this._keyboardNavigationActive && (this._keyboardNavigationActive = !1, this._activeIndex = -1, this._syncActiveOption());
|
|
305
|
+
}
|
|
295
306
|
_navigateActive(e) {
|
|
296
307
|
let t = this._options.filter((e) => !e.disabled && !e.hasAttribute("data-filtered"));
|
|
297
308
|
if (!t.length) return;
|
|
309
|
+
this._keyboardNavigationActive = !0;
|
|
298
310
|
let n = this._activeIndex >= 0 ? t.indexOf(this._options[this._activeIndex]) : e > 0 ? -1 : 0;
|
|
299
311
|
this._activeIndex = this._options.indexOf(t[p(t.length, n, e)]), this._syncActiveOption();
|
|
300
312
|
}
|
|
301
313
|
_setInitialActiveOption() {
|
|
302
314
|
let e = this._options.findIndex((e) => !e.disabled && !e.hasAttribute("data-filtered"));
|
|
303
|
-
this._activeIndex = e, this._syncActiveOption();
|
|
315
|
+
this._keyboardNavigationActive = !0, this._activeIndex = e, this._syncActiveOption();
|
|
304
316
|
}
|
|
305
317
|
_syncActiveOption() {
|
|
306
|
-
this._options.forEach((e, t) => e.toggleAttribute("active", t === this._activeIndex));
|
|
318
|
+
this._options.forEach((e, t) => e.toggleAttribute("active", t === this._activeIndex)), this._isOpen && this._scrollActiveOptionIntoView();
|
|
319
|
+
}
|
|
320
|
+
_scrollActiveOptionIntoView() {
|
|
321
|
+
let e = this._options[this._activeIndex], t = this._panel.getPanel()?.querySelector(".autocomplete-scroll");
|
|
322
|
+
if (!e || !t?.clientHeight) return;
|
|
323
|
+
let n = e.getBoundingClientRect(), r = t.getBoundingClientRect(), i = t.offsetHeight ? r.height / t.offsetHeight : 1;
|
|
324
|
+
if (!i) return;
|
|
325
|
+
let a = r.top + t.clientTop * i, o = a + t.clientHeight * i;
|
|
326
|
+
n.top < a ? t.scrollTop -= (a - n.top) / i : n.bottom > o && (t.scrollTop += (n.bottom - o) / i);
|
|
307
327
|
}
|
|
308
328
|
_selectOption(e) {
|
|
309
329
|
this.readonly || (this.value = e.label, this._setSelectedValue(e.value), this._close(), this.dispatchEvent(new Event("input", {
|
|
@@ -352,13 +372,13 @@ var N = class extends n(x) {
|
|
|
352
372
|
c(this, this._isOpen);
|
|
353
373
|
}
|
|
354
374
|
_openOverlay(e = !1) {
|
|
355
|
-
this._panel.open(e), this._syncOverlayInert();
|
|
375
|
+
this._panel.open(e), this._syncScrollInteractionListeners(), this._syncActiveOption(), this._syncOverlayInert();
|
|
356
376
|
}
|
|
357
377
|
async _closeOverlay() {
|
|
358
|
-
await this._panel.close(() => this._isOpen) && (this._portal = void 0, this._portalContent = void 0);
|
|
378
|
+
await this._panel.close(() => this._isOpen) && (this._syncScrollInteractionListeners(), this._portal = void 0, this._portalContent = void 0);
|
|
359
379
|
}
|
|
360
380
|
_reconfigureOverlay() {
|
|
361
|
-
this._portal = void 0, this._portalContent = void 0, this._panel.reconfigure(this._isOpen), this._syncOverlayInert();
|
|
381
|
+
this._portal = void 0, this._portalContent = void 0, this._panel.reconfigure(this._isOpen), this._syncScrollInteractionListeners(), this._syncOverlayInert();
|
|
362
382
|
}
|
|
363
383
|
_syncScrollLock(e = this._isOpen) {
|
|
364
384
|
this._scrollLock.sync(e && !this.noScrollLock);
|
|
@@ -367,7 +387,7 @@ var N = class extends n(x) {
|
|
|
367
387
|
let e = v().make({
|
|
368
388
|
container: this.overlayContainer,
|
|
369
389
|
target: this,
|
|
370
|
-
style: `${t}\n${o}\n${b}`,
|
|
390
|
+
style: `${t}\n${o}\n${s}\n${b}`,
|
|
371
391
|
className: "wui-glass autocomplete-overlay portal wui-floating-panel",
|
|
372
392
|
onContentChange: () => {
|
|
373
393
|
this._optionPortal.scheduleRefresh();
|