@greypan/web-ui 6.0.0 → 6.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 +285 -93
- package/README.md +266 -87
- 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/assets/overlay-motion.js +1 -1
- package/dist/assets/overlay-motion.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +367 -4
- package/dist/components/autocomplete/index.js +87 -80
- 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/index.js +36 -32
- 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/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.d.ts +29 -1
- package/dist/components/collapse/index.js +105 -46
- 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/context-menu/index.d.ts +7 -14
- package/dist/components/context-menu/index.js +113 -164
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/dialog/index.js +26 -25
- 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 +71 -64
- 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 +6 -14
- package/dist/components/dropdown/index.js +100 -156
- 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/image-preview/index.d.ts +58 -0
- package/dist/components/image-preview/index.js +481 -0
- package/dist/components/image-preview/index.js.map +1 -0
- package/dist/components/image-preview/style.js +6 -0
- package/dist/components/image-preview/style.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +20 -19
- 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/index.d.ts +1 -1
- package/dist/components/layout/index.js +5 -3
- 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/option/style.js +1 -1
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +1 -0
- package/dist/components/popover/index.js +55 -60
- 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 +21 -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 +28 -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/index.js +17 -15
- 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 +368 -5
- package/dist/components/select/index.js +71 -68
- 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 +40 -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/svg-draw-lines/index.js +1 -1
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/switch/index.d.ts +366 -5
- package/dist/components/switch/index.js +28 -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/index.js +1 -1
- 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/manager.js +2 -2
- package/dist/components/toast/manager.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 +43 -58
- 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/icons/generated/radix-icons-reset.d.ts +6 -0
- package/dist/icons/generated/radix-icons-reset.js +10 -0
- package/dist/icons/generated/radix-icons-reset.js.map +1 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +2 -1
- package/dist/shared/focus/pointer-focus.js +37 -0
- package/dist/shared/focus/pointer-focus.js.map +1 -0
- package/dist/shared/form-association/index.js +31 -4
- package/dist/shared/form-association/index.js.map +1 -1
- package/dist/shared/gesture/drag-gesture.js +53 -30
- package/dist/shared/gesture/drag-gesture.js.map +1 -1
- package/dist/shared/gesture/pinch-gesture.js +84 -0
- package/dist/shared/gesture/pinch-gesture.js.map +1 -0
- package/dist/shared/group-management/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-portal.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 +43 -0
- package/dist/shared/option-portal/combobox-shell.js.map +1 -0
- package/dist/shared/option-portal/index.js +22 -21
- package/dist/shared/option-portal/index.js.map +1 -1
- package/dist/shared/overlay/anchored-panel.js +33 -30
- package/dist/shared/overlay/anchored-panel.js.map +1 -1
- package/dist/shared/overlay/composition.js +57 -0
- package/dist/shared/overlay/composition.js.map +1 -0
- package/dist/shared/overlay/lifecycle.js +41 -0
- package/dist/shared/overlay/lifecycle.js.map +1 -0
- package/dist/shared/overlay/native-dialog-presence.js +15 -15
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/{theme → overlay}/overlay-root.js +1 -1
- package/dist/shared/overlay/overlay-root.js.map +1 -0
- package/dist/shared/overlay/overlay.js +43 -41
- 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 +6 -4
- package/dist/shared/overlay/portal.js.map +1 -1
- package/dist/shared/overlay/positioning-generation.js +20 -0
- package/dist/shared/overlay/positioning-generation.js.map +1 -0
- package/dist/shared/{theme/theme-scope.js → overlay/theme-overlay-scope.js} +2 -2
- package/dist/shared/overlay/theme-overlay-scope.js.map +1 -0
- package/package.json +6 -10
- package/dist/shared/theme/overlay-root.js.map +0 -1
- package/dist/shared/theme/theme-scope.js.map +0 -1
|
@@ -4,21 +4,27 @@ import t from "../../icons/generated/lucide-chevron-down.js";
|
|
|
4
4
|
import "../option/index.js";
|
|
5
5
|
import n from "../../assets/glass.js";
|
|
6
6
|
import r from "../../assets/overlay-motion.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
7
|
+
import { FormAssociated as i, FormAssociationController as a, defineFormAssociation as o } from "../../shared/form-association/index.js";
|
|
8
|
+
import { dispatchOpenChangeEvent as s } from "../../shared/open-state/index.js";
|
|
9
|
+
import { overlayComposition as c } from "../../shared/overlay/composition.js";
|
|
10
|
+
import { createComboboxOpenController as l, createOptionListenerBinding as u, handleComboboxFocusOut as d, nextWrappingIndex as f } from "../../shared/option-portal/combobox-shell.js";
|
|
11
|
+
import { defineOptionPortal as p } from "../../shared/option-portal/index.js";
|
|
12
|
+
import { defineAnchoredPanel as m } from "../../shared/overlay/anchored-panel.js";
|
|
13
|
+
import { applyOverlayVariables as h, defineOverlayPortal as g } from "../../shared/overlay/portal.js";
|
|
14
|
+
import { defineScrollLockLease as _ } from "../../shared/scroll-lock/scroll-lock.js";
|
|
15
|
+
import { installPointerFocusSuppression as v } from "../../shared/focus/pointer-focus.js";
|
|
16
|
+
import y from "./style.js";
|
|
17
|
+
import { LitElement as b, html as x, nothing as S, unsafeCSS as C } from "lit";
|
|
18
|
+
import { customElement as w, property as T, state as E } from "lit/decorators.js";
|
|
15
19
|
//#region src/components/select/index.ts
|
|
16
|
-
var
|
|
20
|
+
var D;
|
|
21
|
+
v();
|
|
22
|
+
var O = class extends i(b) {
|
|
17
23
|
static {
|
|
18
|
-
|
|
24
|
+
D = this;
|
|
19
25
|
}
|
|
20
26
|
constructor(...e) {
|
|
21
|
-
super(...e), this.placeholder = "", this.disabled = !1, this.required = !1, this.portal = !1, this.noScrollLock = !1, this.name = "", this._value = "", this._formAssociation =
|
|
27
|
+
super(...e), this.placeholder = "", this.disabled = !1, this.required = !1, this.portal = !1, this.noScrollLock = !1, this.name = "", this._value = "", this._formAssociation = o({
|
|
22
28
|
host: this,
|
|
23
29
|
initialize: () => {
|
|
24
30
|
let e = this.getAttribute("value");
|
|
@@ -34,9 +40,9 @@ var y, b = class extends f {
|
|
|
34
40
|
typeof e == "string" && (this.value = e);
|
|
35
41
|
},
|
|
36
42
|
syncValidity: () => this._syncValidity()
|
|
37
|
-
}).make(), this._formAssociationController = new
|
|
43
|
+
}).make(), this._formAssociationController = new a(this, this._formAssociation), this._isOpen = !1, this._activeIndex = -1, this._selectedLabel = "", this._hasTriggerSlot = !1, this._options = [], this._scrollLock = _().make(), this._optionPortal = p().make({
|
|
38
44
|
element: this,
|
|
39
|
-
idPrefix: `web-ui-select-${++
|
|
45
|
+
idPrefix: `web-ui-select-${++D._nextInstanceId}`,
|
|
40
46
|
getPortal: () => this._portal,
|
|
41
47
|
getPortalContent: () => this._portalContent,
|
|
42
48
|
isOpen: () => this.portal && this._isOpen,
|
|
@@ -48,7 +54,7 @@ var y, b = class extends f {
|
|
|
48
54
|
onImmediateSync: () => {
|
|
49
55
|
this._refreshOptions(), this._syncSelected(), this._syncActiveOption();
|
|
50
56
|
}
|
|
51
|
-
}), this._panel =
|
|
57
|
+
}), this._panel = m().make({
|
|
52
58
|
getAnchor: () => this.shadowRoot?.querySelector(".select-trigger") ?? null,
|
|
53
59
|
getLocalPanel: () => this.shadowRoot?.querySelector(".select-overlay") ?? null,
|
|
54
60
|
getPositioning: () => ({
|
|
@@ -60,19 +66,19 @@ var y, b = class extends f {
|
|
|
60
66
|
isPortal: () => this.portal,
|
|
61
67
|
createPortal: () => this._createPortal()
|
|
62
68
|
}), this._onClickOutside = (e) => {
|
|
63
|
-
|
|
69
|
+
let t = this._panel.getPanel(), n = e.composedPath().includes(this) || t && c.containsEvent(t, e);
|
|
70
|
+
this._isOpen && !n && this._close();
|
|
64
71
|
}, this._onFocusOut = () => {
|
|
65
|
-
|
|
66
|
-
this._isOpen && !this.matches(":focus-within") && !this._panel.getPanel()?.matches(":focus-within") && this._close();
|
|
67
|
-
});
|
|
72
|
+
d(this, () => this._panel.getPanel(), () => this._isOpen, () => this._close());
|
|
68
73
|
}, this._onTriggerSlotChange = (e) => {
|
|
69
74
|
let t = e.target.assignedElements().length > 0;
|
|
70
75
|
this._hasTriggerSlot !== t && (this._hasTriggerSlot = t, this._reconfigureOverlay());
|
|
71
|
-
}, this.
|
|
72
|
-
e
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
}, this._optionListeners = u({
|
|
77
|
+
onClick: (e) => this._handleOptionClick(e),
|
|
78
|
+
onPointerOver: (e) => this._handleOptionPointerOver(e),
|
|
79
|
+
onPointerDown: (e) => this._handleOptionPointerDown(e),
|
|
80
|
+
onUpdate: () => this._onOptionUpdate()
|
|
81
|
+
}), this._bindOption = (e) => this._optionListeners.bind(e), this._unbindOption = (e) => this._optionListeners.unbind(e), this._handleOptionClick = (e) => {
|
|
76
82
|
if (!(e.currentTarget instanceof HTMLElement)) return;
|
|
77
83
|
let t = e.currentTarget;
|
|
78
84
|
t.disabled || !this._isLive(t) || (this.value = t.value, this._close(), this._notifyValueChange());
|
|
@@ -100,18 +106,32 @@ var y, b = class extends f {
|
|
|
100
106
|
t && this._isLive(t) && !t.disabled && (this.value = t.value, this._notifyValueChange()), this._close(), e.preventDefault();
|
|
101
107
|
}
|
|
102
108
|
}
|
|
103
|
-
}
|
|
109
|
+
}, this._openController = l({
|
|
110
|
+
canOpen: () => !this._isDisabled,
|
|
111
|
+
getIsOpen: () => this._isOpen,
|
|
112
|
+
setIsOpen: (e) => {
|
|
113
|
+
this._isOpen = e;
|
|
114
|
+
},
|
|
115
|
+
dispatchOpenChange: () => this._dispatchOpenChange(),
|
|
116
|
+
syncScrollLock: (e) => this._syncScrollLock(e),
|
|
117
|
+
isPortal: () => this.portal,
|
|
118
|
+
openOverlay: (e) => this._openOverlay(e),
|
|
119
|
+
closeOverlay: () => void this._closeOverlay(),
|
|
120
|
+
onOpen: (e) => {
|
|
121
|
+
this._syncSelected(), e ? this._setInitialActiveOption() : this._syncActiveOption();
|
|
122
|
+
},
|
|
123
|
+
onAfterClose: () => {
|
|
124
|
+
this._activeIndex = -1, this._options.forEach((e) => e.removeAttribute("active"));
|
|
125
|
+
}
|
|
126
|
+
});
|
|
104
127
|
}
|
|
105
128
|
static {
|
|
106
129
|
this.styles = [
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
130
|
+
C(n),
|
|
131
|
+
C(r),
|
|
132
|
+
C(y)
|
|
110
133
|
];
|
|
111
134
|
}
|
|
112
|
-
static {
|
|
113
|
-
this.formAssociated = !0;
|
|
114
|
-
}
|
|
115
135
|
get value() {
|
|
116
136
|
return this._value;
|
|
117
137
|
}
|
|
@@ -148,15 +168,6 @@ var y, b = class extends f {
|
|
|
148
168
|
updated(e) {
|
|
149
169
|
(e.has("portal") || e.has("overlayContainer")) && requestAnimationFrame(() => this._reconfigureOverlay()), e.has("noScrollLock") && this._syncScrollLock(), this._syncOpenAttribute(), this._syncValidity();
|
|
150
170
|
}
|
|
151
|
-
formResetCallback() {
|
|
152
|
-
this._formAssociation.reset();
|
|
153
|
-
}
|
|
154
|
-
formDisabledCallback(e) {
|
|
155
|
-
this._formAssociation.setDisabled(e);
|
|
156
|
-
}
|
|
157
|
-
formStateRestoreCallback(e) {
|
|
158
|
-
this._formAssociation.restore(e);
|
|
159
|
-
}
|
|
160
171
|
_syncValidity() {
|
|
161
172
|
let e = this._formAssociation.getInternals();
|
|
162
173
|
!e || typeof e.setValidity != "function" || (this._isDisabled || !this.required || this.value ? e.setValidity({}) : e.setValidity({ valueMissing: !0 }, "请选择一项"));
|
|
@@ -185,25 +196,17 @@ var y, b = class extends f {
|
|
|
185
196
|
_navigateActive(e) {
|
|
186
197
|
let t = this._options.filter((e) => !e.disabled && this._isLive(e));
|
|
187
198
|
if (!t.length) return;
|
|
188
|
-
let n = this._options.find((e) => e.value === this.value && !e.disabled && this._isLive(e)), r =
|
|
189
|
-
r < 0 && (r = t.length - 1), r >= t.length && (r = 0);
|
|
190
|
-
let i = t[r];
|
|
199
|
+
let n = this._options.find((e) => e.value === this.value && !e.disabled && this._isLive(e)), r = this._activeIndex >= 0 && this._isLive(this._options[this._activeIndex]) ? t.indexOf(this._options[this._activeIndex]) : n ? t.indexOf(n) : e > 0 ? -1 : 0, i = t[f(t.length, r, e)];
|
|
191
200
|
this._activeIndex = this._options.indexOf(i), this._syncActiveOption();
|
|
192
201
|
}
|
|
193
202
|
_open(e = !1) {
|
|
194
|
-
this.
|
|
195
|
-
this._isOpen && this._openOverlay(e);
|
|
196
|
-
}) : this._openOverlay(e));
|
|
203
|
+
this._openController.open(e);
|
|
197
204
|
}
|
|
198
205
|
_close() {
|
|
199
|
-
this.
|
|
206
|
+
this._openController.close();
|
|
200
207
|
}
|
|
201
208
|
_dispatchOpenChange() {
|
|
202
|
-
this
|
|
203
|
-
detail: { open: this._isOpen },
|
|
204
|
-
bubbles: !0,
|
|
205
|
-
composed: !0
|
|
206
|
-
}));
|
|
209
|
+
s(this, this._isOpen);
|
|
207
210
|
}
|
|
208
211
|
_setInitialActiveOption() {
|
|
209
212
|
let e = this._options.findIndex((e) => e.value === this.value && !e.disabled && this._isLive(e)), t = this._options.findIndex((e) => !e.disabled && this._isLive(e));
|
|
@@ -231,14 +234,14 @@ var y, b = class extends f {
|
|
|
231
234
|
this._panel.open(e);
|
|
232
235
|
}
|
|
233
236
|
_createPortal() {
|
|
234
|
-
let e =
|
|
237
|
+
let e = g().make({
|
|
235
238
|
container: this.overlayContainer,
|
|
236
239
|
target: this,
|
|
237
|
-
style: `${n}\n${r}\n${
|
|
240
|
+
style: `${n}\n${r}\n${y}`,
|
|
238
241
|
className: "wui-glass select-overlay portal wui-floating-panel",
|
|
239
242
|
onContentChange: () => this._optionPortal.scheduleRefresh()
|
|
240
243
|
});
|
|
241
|
-
this._portal = e,
|
|
244
|
+
this._portal = e, h(e.panel, this, [
|
|
242
245
|
"--wui-overlay-min-width",
|
|
243
246
|
"--wui-select-max-width",
|
|
244
247
|
"--wui-select-max-height"
|
|
@@ -255,8 +258,8 @@ var y, b = class extends f {
|
|
|
255
258
|
await this._panel.close(() => this._isOpen) && (this._portal = void 0, this._portalContent = void 0);
|
|
256
259
|
}
|
|
257
260
|
render() {
|
|
258
|
-
let e = `${this.localName}-listbox`, n = !this.portal && this._isOpen && this._activeIndex >= 0 ? this._options[this._activeIndex]?.id ??
|
|
259
|
-
return
|
|
261
|
+
let e = `${this.localName}-listbox`, n = !this.portal && this._isOpen && this._activeIndex >= 0 ? this._options[this._activeIndex]?.id ?? S : S;
|
|
262
|
+
return x`
|
|
260
263
|
<div class="wui-select-inner">
|
|
261
264
|
<div
|
|
262
265
|
class="wui-glass select-trigger"
|
|
@@ -266,15 +269,15 @@ var y, b = class extends f {
|
|
|
266
269
|
role="combobox"
|
|
267
270
|
aria-expanded=${this._isOpen}
|
|
268
271
|
aria-haspopup="listbox"
|
|
269
|
-
aria-controls=${this.portal ?
|
|
272
|
+
aria-controls=${this.portal ? S : e}
|
|
270
273
|
aria-disabled=${String(this._isDisabled)}
|
|
271
274
|
aria-activedescendant=${n}
|
|
272
275
|
>
|
|
273
276
|
<slot name="trigger" @slotchange=${this._onTriggerSlotChange}></slot>
|
|
274
|
-
${this._hasTriggerSlot ?
|
|
277
|
+
${this._hasTriggerSlot ? S : x`<span class="label">${this._selectedLabel}</span>`}
|
|
275
278
|
<web-ui-icon class="arrow" .icon=${t}></web-ui-icon>
|
|
276
279
|
</div>
|
|
277
|
-
<div class="
|
|
280
|
+
<div class="select-overlay wui-floating-panel wui-glass" hidden role="listbox" id=${e}>
|
|
278
281
|
<div class="select-scroll">
|
|
279
282
|
<div class="select-content">
|
|
280
283
|
<slot @slotchange=${this._onSlotChange}></slot>
|
|
@@ -285,30 +288,30 @@ var y, b = class extends f {
|
|
|
285
288
|
`;
|
|
286
289
|
}
|
|
287
290
|
};
|
|
288
|
-
e([
|
|
291
|
+
e([T({
|
|
289
292
|
type: String,
|
|
290
293
|
reflect: !0
|
|
291
|
-
})],
|
|
294
|
+
})], O.prototype, "placeholder", void 0), e([T({
|
|
292
295
|
type: Boolean,
|
|
293
296
|
reflect: !0
|
|
294
|
-
})],
|
|
297
|
+
})], O.prototype, "disabled", void 0), e([T({
|
|
295
298
|
type: Boolean,
|
|
296
299
|
reflect: !0
|
|
297
|
-
})],
|
|
300
|
+
})], O.prototype, "required", void 0), e([T({
|
|
298
301
|
type: Boolean,
|
|
299
302
|
reflect: !0
|
|
300
|
-
})],
|
|
303
|
+
})], O.prototype, "portal", void 0), e([T({
|
|
301
304
|
type: Boolean,
|
|
302
305
|
reflect: !0,
|
|
303
306
|
attribute: "no-scroll-lock"
|
|
304
|
-
})],
|
|
307
|
+
})], O.prototype, "noScrollLock", void 0), e([T({ attribute: !1 })], O.prototype, "overlayContainer", void 0), e([T({
|
|
305
308
|
type: String,
|
|
306
309
|
reflect: !0
|
|
307
|
-
})],
|
|
310
|
+
})], O.prototype, "name", void 0), e([E()], O.prototype, "_value", void 0), e([T({
|
|
308
311
|
type: String,
|
|
309
312
|
reflect: !0
|
|
310
|
-
})],
|
|
313
|
+
})], O.prototype, "value", null), e([E()], O.prototype, "_isOpen", void 0), e([E()], O.prototype, "_activeIndex", void 0), e([E()], O.prototype, "_selectedLabel", void 0), e([E()], O.prototype, "_hasTriggerSlot", void 0), O = D = e([w("web-ui-select")], O);
|
|
311
314
|
//#endregion
|
|
312
|
-
export {
|
|
315
|
+
export { O as WebUiSelect };
|
|
313
316
|
|
|
314
317
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/select/index.ts"],"sourcesContent":["import { html, LitElement, nothing, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport '@/components/icon'\nimport '@/components/option'\nimport glass from '@/assets/glass.css?inline'\nimport overlayMotion from '@/assets/overlay-motion.css?inline'\nimport type { WebUiOption } from '@/components/option'\nimport { lucideChevronDown } from '@/icons'\nimport { defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { defineOptionPortal } from '@/shared/option-portal'\nimport { defineAnchoredPanel } from '@/shared/overlay/anchored-panel'\nimport { applyOverlayVariables, defineOverlayPortal } from '@/shared/overlay/portal'\nimport type { OverlayContainer, OverlayPortal } from '@/shared/overlay/portal'\nimport { defineScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-select')\nexport class WebUiSelect extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(overlayMotion), unsafeCSS(style)]\n\n static formAssociated = true\n\n @property({ type: String, reflect: true }) placeholder = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n @property({ type: Boolean, reflect: true }) portal = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n @property({ attribute: false }) overlayContainer?: OverlayContainer\n @property({ type: String, reflect: true }) name = ''\n\n // value 使用内部状态 + 访问器模式,在变更时同步 ElementInternals;\n // @property + reflect 让它与 input/textarea/slider/input-number 的 value 反射语义保持一致。\n @state() private _value = ''\n @property({ type: String, reflect: true })\n get value(): string {\n return this._value\n }\n set value(v: string) {\n const old = this._value\n this._value = v\n this._formAssociation.sync()\n this.toggleAttribute('data-has-value', !!v)\n this.requestUpdate('value', old)\n }\n\n private readonly _formAssociation = defineFormAssociation<string>({\n host: this,\n initialize: () => {\n // 同步 HTML 属性中预设的 value,补全访问器模式不处理 attribute 反射。\n const attrValue = this.getAttribute('value')\n if (attrValue !== null) {\n this._value = attrValue\n this.toggleAttribute('data-has-value', !!attrValue)\n }\n },\n getState: () => this._value,\n setState: value => {\n this.value = value\n },\n getFormValue: () => this._value,\n getFormState: () => this._value,\n restoreState: state => {\n if (typeof state === 'string') this.value = state\n },\n syncValidity: () => this._syncValidity()\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formAssociation.isFormDisabled()\n }\n\n @state() private _isOpen = false\n @state() private _activeIndex = -1\n @state() private _selectedLabel = ''\n @state() private _hasTriggerSlot = false\n\n private _options: WebUiOption[] = []\n private _portal?: OverlayPortal\n private _portalContent?: HTMLElement\n private readonly _scrollLock = defineScrollLockLease().make()\n\n private static _nextInstanceId = 0\n\n // option 注册表 / portal 同步 / 微任务调度收敛到 shared 模块(autocomplete 同款)\n private readonly _optionPortal = defineOptionPortal().make({\n element: this,\n // 实例级前缀保证多实例同时展开时 option id 不冲突(aria 引用按 id 定位)\n idPrefix: `web-ui-select-${++WebUiSelect._nextInstanceId}`,\n getPortal: () => this._portal,\n getPortalContent: () => this._portalContent,\n isOpen: () => this.portal && this._isOpen,\n getMigratableNodes: () => [...this.querySelectorAll<WebUiOption>('web-ui-option')],\n hasUpdated: () => this.hasUpdated,\n requestUpdate: () => this.requestUpdate(),\n bindOption: option => this._bindOption(option),\n unbindOption: option => this._unbindOption(option),\n onImmediateSync: () => {\n this._refreshOptions()\n this._syncSelected()\n this._syncActiveOption()\n }\n })\n private readonly _panel = defineAnchoredPanel().make({\n getAnchor: () => this.shadowRoot?.querySelector<HTMLElement>('.select-trigger') ?? null,\n getLocalPanel: () => this.shadowRoot?.querySelector<HTMLElement>('.select-overlay') ?? null,\n getPositioning: () => ({\n placement: 'bottom-start',\n offset: 4,\n // 面板宽度统一为 max(内容, trigger, --wui-overlay-min-width),内容自适应展开\n minAnchorWidth: true,\n strategy: this.portal ? 'fixed' : 'absolute'\n }),\n isPortal: () => this.portal,\n createPortal: () => this._createPortal()\n })\n\n get isOpen(): boolean {\n return this._isOpen\n }\n\n get open(): boolean {\n return this._isOpen\n }\n\n private _onClickOutside = (e: MouseEvent) => {\n if (\n this._isOpen &&\n e.target instanceof Node &&\n !this.contains(e.target) &&\n !this._panel.getPanel()?.contains(e.target)\n ) {\n this._close()\n }\n }\n\n private _onFocusOut = () => {\n requestAnimationFrame(() => {\n if (this._isOpen && !this.matches(':focus-within') && !this._panel.getPanel()?.matches(':focus-within')) {\n this._close()\n }\n })\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._optionPortal.bindHost()\n this.addEventListener('keydown', this._onKeydown)\n this.addEventListener('focusout', this._onFocusOut)\n document.addEventListener('click', this._onClickOutside)\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._optionPortal.dispose()\n this.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('focusout', this._onFocusOut)\n document.removeEventListener('click', this._onClickOutside)\n this._options.forEach(this._unbindOption)\n this._options = []\n this._portal = undefined\n this._portalContent = undefined\n this._close()\n this._panel.dispose()\n this._scrollLock.release()\n }\n\n override firstUpdated() {\n requestAnimationFrame(() => {\n if (this.isConnected) this._optionPortal.scheduleRefresh()\n })\n }\n\n override willUpdate() {\n this._refreshOptions()\n this._syncSelected()\n }\n\n override updated(changed: PropertyValues) {\n if (changed.has('portal') || changed.has('overlayContainer'))\n requestAnimationFrame(() => this._reconfigureOverlay())\n if (changed.has('noScrollLock')) this._syncScrollLock()\n this._syncOpenAttribute()\n this._syncValidity()\n }\n\n formResetCallback() {\n this._formAssociation.reset()\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formAssociation.setDisabled(disabled)\n }\n\n formStateRestoreCallback(state: string | File | FormData | null) {\n this._formAssociation.restore(state)\n }\n\n private _syncValidity() {\n const internals = this._formAssociation.getInternals()\n if (!internals || typeof internals.setValidity !== 'function') return\n if (this._isDisabled || !this.required || this.value) internals.setValidity({})\n else internals.setValidity({ valueMissing: true }, '请选择一项')\n }\n\n private _syncOpenAttribute() {\n this.toggleAttribute('open', this._isOpen)\n }\n\n private _onTriggerSlotChange = (e: Event) => {\n const slot = e.target as HTMLSlotElement\n const hasContent = slot.assignedElements().length > 0\n if (this._hasTriggerSlot === hasContent) return\n this._hasTriggerSlot = hasContent\n this._reconfigureOverlay()\n }\n\n private _syncSelected() {\n this._options.forEach(o => {\n o.selected = o.value === this.value\n })\n if (!this.value) {\n this._selectedLabel = this.placeholder\n return\n }\n const option = this._options.find(o => o.value === this.value)\n this._selectedLabel = option?.label || this.placeholder\n }\n\n private _bindOption = (option: WebUiOption) => {\n option.addEventListener('click', this._handleOptionClick)\n option.addEventListener('pointerover', this._handleOptionPointerOver)\n option.addEventListener('pointerdown', this._handleOptionPointerDown)\n option.addEventListener('option-update', this._onOptionUpdate)\n }\n\n private _unbindOption = (option: WebUiOption) => {\n option.removeEventListener('click', this._handleOptionClick)\n option.removeEventListener('pointerover', this._handleOptionPointerOver)\n option.removeEventListener('pointerdown', this._handleOptionPointerDown)\n option.removeEventListener('option-update', this._onOptionUpdate)\n }\n\n private _refreshOptions() {\n const activeOption = this._options[this._activeIndex]\n // diff 绑定/解绑与激活索引按 option 身份保持在 shared 内完成,\n // 避免移除中间项后激活静默偏移到相邻项\n const next = this._optionPortal.refresh(this._options, activeOption)\n this._options = next.options\n this._activeIndex = next.activeIndex\n // 非 portal 模式 aria-activedescendant 引用真实 option id,需保证已分配\n this._optionPortal.ensureOptionIds(this._options)\n }\n\n private _handleOptionClick = (e: Event) => {\n if (!(e.currentTarget instanceof HTMLElement)) return\n const option = e.currentTarget as WebUiOption\n if (option.disabled || !this._isLive(option)) return\n this.value = option.value\n this._close()\n this._notifyValueChange()\n }\n\n private _onOptionUpdate = () => {\n this._syncSelected()\n this._syncActiveOption()\n }\n\n private _handleOptionPointerOver = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (!this._isOpen || this._activeIndex < 0 || !(e.currentTarget instanceof HTMLElement)) return\n\n // 指针接管后只保留 :hover,避免键盘激活项与悬停项同时高亮。\n this._activeIndex = -1\n this._syncActiveOption()\n }\n\n private _handleOptionPointerDown = (e: PointerEvent) => {\n // 保持 trigger 焦点,避免 focusout 在 click 前关闭浮层。\n e.preventDefault()\n }\n\n // slotchange 不冒泡,只能由模板内 slot 自行监听;稳定引用避免 Lit 重挂载\n private _onSlotChange = () => {\n this._optionPortal.scheduleRefresh()\n }\n\n // slotchange/unregister 的刷新依赖 Lit 渲染调度;键盘或 click 事件可能先于其触发,\n // 已从 DOM 移除或被移出 Select/portal 面板的选项不得再被激活或选中。\n private _isLive(option: WebUiOption): boolean {\n const panel = this.portal ? this._panel.getPanel() : null\n return option.isConnected && (this.contains(option) || (!!panel && panel.contains(option)))\n }\n\n private _onKeydown = (e: KeyboardEvent) => {\n if (this._isDisabled) return\n\n switch (e.key) {\n case 'Escape':\n if (this._isOpen) {\n this._close()\n e.preventDefault()\n }\n break\n case 'ArrowDown':\n e.preventDefault()\n if (!this._isOpen) {\n this._open(true)\n } else {\n this._navigateActive(1)\n }\n break\n case 'ArrowUp':\n e.preventDefault()\n if (!this._isOpen) this._open(true)\n else this._navigateActive(-1)\n break\n case 'Enter': {\n if (this._isOpen && this._activeIndex >= 0) {\n const option = this._options[this._activeIndex]\n if (option && this._isLive(option) && !option.disabled) {\n this.value = option.value\n this._notifyValueChange()\n }\n this._close()\n e.preventDefault()\n }\n break\n }\n }\n }\n\n private _navigateActive(delta: number) {\n const enabled = this._options.filter(o => !o.disabled && this._isLive(o))\n if (!enabled.length) return\n\n const selectedOption = this._options.find(\n option => option.value === this.value && !option.disabled && this._isLive(option)\n )\n const currentIdx =\n this._activeIndex >= 0 && this._isLive(this._options[this._activeIndex])\n ? enabled.indexOf(this._options[this._activeIndex])\n : selectedOption\n ? enabled.indexOf(selectedOption)\n : delta > 0\n ? -1\n : 0\n let nextIdx = currentIdx + delta\n if (nextIdx < 0) nextIdx = enabled.length - 1\n if (nextIdx >= enabled.length) nextIdx = 0\n\n const nextOption = enabled[nextIdx]\n this._activeIndex = this._options.indexOf(nextOption)\n\n this._syncActiveOption()\n }\n\n private _open(isKeyboardNavigation = false) {\n if (this._isDisabled || this._isOpen) return\n this._isOpen = true\n this._dispatchOpenChange()\n this._syncSelected()\n if (isKeyboardNavigation) this._setInitialActiveOption()\n else this._syncActiveOption()\n this._syncScrollLock()\n if (this.portal) {\n requestAnimationFrame(() => {\n if (this._isOpen) this._openOverlay(isKeyboardNavigation)\n })\n } else {\n this._openOverlay(isKeyboardNavigation)\n }\n }\n\n private _close() {\n if (!this._isOpen) return\n this._isOpen = false\n this._dispatchOpenChange()\n this._activeIndex = -1\n this._options.forEach(o => o.removeAttribute('active'))\n this._syncScrollLock(false)\n void this._closeOverlay()\n }\n\n private _dispatchOpenChange() {\n this.dispatchEvent(\n new CustomEvent('open-change', {\n detail: { open: this._isOpen },\n bubbles: true,\n composed: true\n })\n )\n }\n\n private _setInitialActiveOption() {\n const selectedIndex = this._options.findIndex(\n option => option.value === this.value && !option.disabled && this._isLive(option)\n )\n const firstEnabledIndex = this._options.findIndex(option => !option.disabled && this._isLive(option))\n this._activeIndex = selectedIndex >= 0 ? selectedIndex : firstEnabledIndex\n this._syncActiveOption()\n }\n\n private _syncActiveOption() {\n this._options.forEach((option, index) =>\n option.toggleAttribute('active', index === this._activeIndex && this._isLive(option))\n )\n }\n\n private _notifyValueChange() {\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private _syncScrollLock(isOpen = this._isOpen) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n private _togglePopup() {\n if (this._isDisabled) return\n if (this._isOpen) this._close()\n else this._open()\n }\n\n private _openOverlay(isKeyboardNavigation = false) {\n this._panel.open(isKeyboardNavigation)\n }\n\n private _createPortal(): OverlayPortal {\n const portal = defineOverlayPortal().make({\n container: this.overlayContainer,\n target: this,\n style: `${glass}\\n${overlayMotion}\\n${style}`,\n className: 'wui-glass select-overlay portal wui-floating-panel',\n onContentChange: () => this._optionPortal.scheduleRefresh()\n })\n this._portal = portal\n applyOverlayVariables(portal.panel, this, [\n '--wui-overlay-min-width',\n '--wui-select-max-width',\n '--wui-select-max-height'\n ])\n portal.panel.setAttribute('role', 'listbox')\n const scroll = document.createElement('div')\n scroll.className = 'select-scroll'\n const content = document.createElement('div')\n content.className = 'select-content'\n this._portalContent = content\n scroll.append(content)\n portal.panel.append(scroll)\n // 自定义 trigger 必须留在宿主内,不能随 options 迁入 portal 面板\n portal.moveContent(\n Array.from(this.children).filter(child => child.slot !== 'trigger'),\n content\n )\n return portal\n }\n\n private _reconfigureOverlay() {\n // reconfigure 会 dispose 并按需重建 portal,旧引用必须同步失效\n this._portal = undefined\n this._portalContent = undefined\n this._panel.reconfigure(this._isOpen)\n }\n\n private async _closeOverlay() {\n const closed = await this._panel.close(() => this._isOpen)\n // portal 已随关闭 dispose,与 autocomplete 对齐同步失效引用\n if (closed) {\n this._portal = undefined\n this._portalContent = undefined\n }\n }\n\n override render() {\n // portal 模式下 options 被 moveContent 移入浮层 shadow root,id 引用无法跨树作用域\n // 解析,因此 activedescendant 仅在非 portal 模式输出;aria-controls 同理指向同根内 listbox\n const listboxId = `${this.localName}-listbox`\n const activeDescendant =\n !this.portal && this._isOpen && this._activeIndex >= 0\n ? (this._options[this._activeIndex]?.id ?? nothing)\n : nothing\n\n return html`\n <div class=\"wui-select-inner\">\n <div\n class=\"wui-glass select-trigger\"\n ?data-custom-trigger=${this._hasTriggerSlot}\n @click=${this._togglePopup}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"combobox\"\n aria-expanded=${this._isOpen}\n aria-haspopup=\"listbox\"\n aria-controls=${this.portal ? nothing : listboxId}\n aria-disabled=${String(this._isDisabled)}\n aria-activedescendant=${activeDescendant}\n >\n <slot name=\"trigger\" @slotchange=${this._onTriggerSlotChange}></slot>\n ${!this._hasTriggerSlot ? html`<span class=\"label\">${this._selectedLabel}</span>` : nothing}\n <web-ui-icon class=\"arrow\" .icon=${lucideChevronDown}></web-ui-icon>\n </div>\n <div class=\"wui-glass select-overlay wui-floating-panel\" hidden role=\"listbox\" id=${listboxId}>\n <div class=\"select-scroll\">\n <div class=\"select-content\">\n <slot @slotchange=${this._onSlotChange}></slot>\n </div>\n </div>\n </div>\n </div>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-select': WebUiSelect\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/select/index.ts"],"sourcesContent":["import { html, LitElement, nothing, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport '@/components/icon'\nimport '@/components/option'\nimport glass from '@/assets/glass.css?inline'\nimport overlayMotion from '@/assets/overlay-motion.css?inline'\nimport type { WebUiOption } from '@/components/option'\nimport { lucideChevronDown } from '@/icons'\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { dispatchOpenChangeEvent } from '@/shared/open-state'\nimport {\n createComboboxOpenController,\n createOptionListenerBinding,\n handleComboboxFocusOut,\n nextWrappingIndex\n} from '@/shared/option-portal'\nimport { defineOptionPortal } from '@/shared/option-portal'\nimport { defineAnchoredPanel } from '@/shared/overlay/anchored-panel'\nimport { overlayComposition } from '@/shared/overlay/composition'\nimport { applyOverlayVariables, defineOverlayPortal } from '@/shared/overlay/portal'\nimport type { OverlayContainer, OverlayPortal } from '@/shared/overlay/portal'\nimport { defineScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\ninstallPointerFocusSuppression()\n\n@customElement('web-ui-select')\nexport class WebUiSelect extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(glass), unsafeCSS(overlayMotion), unsafeCSS(style)]\n\n @property({ type: String, reflect: true }) placeholder = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n @property({ type: Boolean, reflect: true }) portal = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n @property({ attribute: false }) overlayContainer?: OverlayContainer\n @property({ type: String, reflect: true }) name = ''\n\n // value 使用内部状态 + 访问器模式,在变更时同步 ElementInternals;\n // @property + reflect 让它与 input/textarea/slider/input-number 的 value 反射语义保持一致。\n @state() private _value = ''\n @property({ type: String, reflect: true })\n get value(): string {\n return this._value\n }\n set value(v: string) {\n const old = this._value\n this._value = v\n this._formAssociation.sync()\n this.toggleAttribute('data-has-value', !!v)\n this.requestUpdate('value', old)\n }\n\n private readonly _formAssociation = defineFormAssociation<string>({\n host: this,\n initialize: () => {\n // 同步 HTML 属性中预设的 value,补全访问器模式不处理 attribute 反射。\n const attrValue = this.getAttribute('value')\n if (attrValue !== null) {\n this._value = attrValue\n this.toggleAttribute('data-has-value', !!attrValue)\n }\n },\n getState: () => this._value,\n setState: value => {\n this.value = value\n },\n getFormValue: () => this._value,\n getFormState: () => this._value,\n restoreState: state => {\n if (typeof state === 'string') this.value = state\n },\n syncValidity: () => this._syncValidity()\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formAssociation.isFormDisabled()\n }\n\n @state() private _isOpen = false\n @state() private _activeIndex = -1\n @state() private _selectedLabel = ''\n @state() private _hasTriggerSlot = false\n\n private _options: WebUiOption[] = []\n private _portal?: OverlayPortal\n private _portalContent?: HTMLElement\n private readonly _scrollLock = defineScrollLockLease().make()\n\n private static _nextInstanceId = 0\n\n // option 注册表 / portal 同步 / 微任务调度收敛到 shared 模块(autocomplete 同款)\n private readonly _optionPortal = defineOptionPortal().make({\n element: this,\n // 实例级前缀保证多实例同时展开时 option id 不冲突(aria 引用按 id 定位)\n idPrefix: `web-ui-select-${++WebUiSelect._nextInstanceId}`,\n getPortal: () => this._portal,\n getPortalContent: () => this._portalContent,\n isOpen: () => this.portal && this._isOpen,\n getMigratableNodes: () => [...this.querySelectorAll<WebUiOption>('web-ui-option')],\n hasUpdated: () => this.hasUpdated,\n requestUpdate: () => this.requestUpdate(),\n bindOption: option => this._bindOption(option),\n unbindOption: option => this._unbindOption(option),\n onImmediateSync: () => {\n this._refreshOptions()\n this._syncSelected()\n this._syncActiveOption()\n }\n })\n private readonly _panel = defineAnchoredPanel().make({\n getAnchor: () => this.shadowRoot?.querySelector<HTMLElement>('.select-trigger') ?? null,\n getLocalPanel: () => this.shadowRoot?.querySelector<HTMLElement>('.select-overlay') ?? null,\n getPositioning: () => ({\n placement: 'bottom-start',\n offset: 4,\n // 面板宽度统一为 max(内容, trigger, --wui-overlay-min-width),内容自适应展开\n minAnchorWidth: true,\n strategy: this.portal ? 'fixed' : 'absolute'\n }),\n isPortal: () => this.portal,\n createPortal: () => this._createPortal()\n })\n\n get isOpen(): boolean {\n return this._isOpen\n }\n\n get open(): boolean {\n return this._isOpen\n }\n\n private _onClickOutside = (e: MouseEvent) => {\n const panel = this._panel.getPanel()\n const isInside = e.composedPath().includes(this) || (panel && overlayComposition.containsEvent(panel, e))\n if (this._isOpen && !isInside) {\n this._close()\n }\n }\n\n private _onFocusOut = () => {\n handleComboboxFocusOut(\n this,\n () => this._panel.getPanel(),\n () => this._isOpen,\n () => this._close()\n )\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._optionPortal.bindHost()\n this.addEventListener('keydown', this._onKeydown)\n this.addEventListener('focusout', this._onFocusOut)\n document.addEventListener('click', this._onClickOutside)\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._optionPortal.dispose()\n this.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('focusout', this._onFocusOut)\n document.removeEventListener('click', this._onClickOutside)\n this._options.forEach(this._unbindOption)\n this._options = []\n this._portal = undefined\n this._portalContent = undefined\n this._close()\n this._panel.dispose()\n this._scrollLock.release()\n }\n\n override firstUpdated() {\n requestAnimationFrame(() => {\n if (this.isConnected) this._optionPortal.scheduleRefresh()\n })\n }\n\n override willUpdate() {\n this._refreshOptions()\n this._syncSelected()\n }\n\n override updated(changed: PropertyValues) {\n if (changed.has('portal') || changed.has('overlayContainer'))\n requestAnimationFrame(() => this._reconfigureOverlay())\n if (changed.has('noScrollLock')) this._syncScrollLock()\n this._syncOpenAttribute()\n this._syncValidity()\n }\n\n private _syncValidity() {\n const internals = this._formAssociation.getInternals()\n if (!internals || typeof internals.setValidity !== 'function') return\n if (this._isDisabled || !this.required || this.value) internals.setValidity({})\n else internals.setValidity({ valueMissing: true }, '请选择一项')\n }\n\n private _syncOpenAttribute() {\n this.toggleAttribute('open', this._isOpen)\n }\n\n private _onTriggerSlotChange = (e: Event) => {\n const slot = e.target as HTMLSlotElement\n const hasContent = slot.assignedElements().length > 0\n if (this._hasTriggerSlot === hasContent) return\n this._hasTriggerSlot = hasContent\n this._reconfigureOverlay()\n }\n\n private _syncSelected() {\n this._options.forEach(o => {\n o.selected = o.value === this.value\n })\n if (!this.value) {\n this._selectedLabel = this.placeholder\n return\n }\n const option = this._options.find(o => o.value === this.value)\n this._selectedLabel = option?.label || this.placeholder\n }\n\n private readonly _optionListeners = createOptionListenerBinding({\n // 惰性解引用:handler 字段声明在后者仍可在调用期取到\n onClick: event => this._handleOptionClick(event),\n onPointerOver: event => this._handleOptionPointerOver(event),\n onPointerDown: event => this._handleOptionPointerDown(event),\n onUpdate: () => this._onOptionUpdate()\n })\n private _bindOption = (option: WebUiOption) => this._optionListeners.bind(option)\n private _unbindOption = (option: WebUiOption) => this._optionListeners.unbind(option)\n\n private _refreshOptions() {\n const activeOption = this._options[this._activeIndex]\n // diff 绑定/解绑与激活索引按 option 身份保持在 shared 内完成,\n // 避免移除中间项后激活静默偏移到相邻项\n const next = this._optionPortal.refresh(this._options, activeOption)\n this._options = next.options\n this._activeIndex = next.activeIndex\n // 非 portal 模式 aria-activedescendant 引用真实 option id,需保证已分配\n this._optionPortal.ensureOptionIds(this._options)\n }\n\n private _handleOptionClick = (e: Event) => {\n if (!(e.currentTarget instanceof HTMLElement)) return\n const option = e.currentTarget as WebUiOption\n if (option.disabled || !this._isLive(option)) return\n this.value = option.value\n this._close()\n this._notifyValueChange()\n }\n\n private _onOptionUpdate = () => {\n this._syncSelected()\n this._syncActiveOption()\n }\n\n private _handleOptionPointerOver = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (!this._isOpen || this._activeIndex < 0 || !(e.currentTarget instanceof HTMLElement)) return\n\n // 指针接管后只保留 :hover,避免键盘激活项与悬停项同时高亮。\n this._activeIndex = -1\n this._syncActiveOption()\n }\n\n private _handleOptionPointerDown = (e: PointerEvent) => {\n // 保持 trigger 焦点,避免 focusout 在 click 前关闭浮层。\n e.preventDefault()\n }\n\n // slotchange 不冒泡,只能由模板内 slot 自行监听;稳定引用避免 Lit 重挂载\n private _onSlotChange = () => {\n this._optionPortal.scheduleRefresh()\n }\n\n // slotchange/unregister 的刷新依赖 Lit 渲染调度;键盘或 click 事件可能先于其触发,\n // 已从 DOM 移除或被移出 Select/portal 面板的选项不得再被激活或选中。\n private _isLive(option: WebUiOption): boolean {\n const panel = this.portal ? this._panel.getPanel() : null\n return option.isConnected && (this.contains(option) || (!!panel && panel.contains(option)))\n }\n\n private _onKeydown = (e: KeyboardEvent) => {\n if (this._isDisabled) return\n\n switch (e.key) {\n case 'Escape':\n if (this._isOpen) {\n this._close()\n e.preventDefault()\n }\n break\n case 'ArrowDown':\n e.preventDefault()\n if (!this._isOpen) {\n this._open(true)\n } else {\n this._navigateActive(1)\n }\n break\n case 'ArrowUp':\n e.preventDefault()\n if (!this._isOpen) this._open(true)\n else this._navigateActive(-1)\n break\n case 'Enter': {\n if (this._isOpen && this._activeIndex >= 0) {\n const option = this._options[this._activeIndex]\n if (option && this._isLive(option) && !option.disabled) {\n this.value = option.value\n this._notifyValueChange()\n }\n this._close()\n e.preventDefault()\n }\n break\n }\n }\n }\n\n private _navigateActive(delta: number) {\n const enabled = this._options.filter(o => !o.disabled && this._isLive(o))\n if (!enabled.length) return\n\n const selectedOption = this._options.find(\n option => option.value === this.value && !option.disabled && this._isLive(option)\n )\n const currentIdx =\n this._activeIndex >= 0 && this._isLive(this._options[this._activeIndex])\n ? enabled.indexOf(this._options[this._activeIndex])\n : selectedOption\n ? enabled.indexOf(selectedOption)\n : delta > 0\n ? -1\n : 0\n const nextOption = enabled[nextWrappingIndex(enabled.length, currentIdx, delta)]\n this._activeIndex = this._options.indexOf(nextOption)\n\n this._syncActiveOption()\n }\n\n // 开合生命周期不变量(guard / 派发顺序 / scroll-lock 配对 / portal rAF dance)\n // 收敛在 shared combobox-shell;select 只注入差异点\n private readonly _openController = createComboboxOpenController({\n canOpen: () => !this._isDisabled,\n getIsOpen: () => this._isOpen,\n setIsOpen: open => {\n this._isOpen = open\n },\n dispatchOpenChange: () => this._dispatchOpenChange(),\n syncScrollLock: open => this._syncScrollLock(open),\n isPortal: () => this.portal,\n openOverlay: isKeyboardNavigation => this._openOverlay(isKeyboardNavigation),\n closeOverlay: () => void this._closeOverlay(),\n onOpen: isKeyboardNavigation => {\n this._syncSelected()\n if (isKeyboardNavigation) this._setInitialActiveOption()\n else this._syncActiveOption()\n },\n onAfterClose: () => {\n this._activeIndex = -1\n this._options.forEach(o => o.removeAttribute('active'))\n }\n })\n\n private _open(isKeyboardNavigation = false) {\n this._openController.open(isKeyboardNavigation)\n }\n\n private _close() {\n this._openController.close()\n }\n\n private _dispatchOpenChange() {\n dispatchOpenChangeEvent(this, this._isOpen)\n }\n\n private _setInitialActiveOption() {\n const selectedIndex = this._options.findIndex(\n option => option.value === this.value && !option.disabled && this._isLive(option)\n )\n const firstEnabledIndex = this._options.findIndex(option => !option.disabled && this._isLive(option))\n this._activeIndex = selectedIndex >= 0 ? selectedIndex : firstEnabledIndex\n this._syncActiveOption()\n }\n\n private _syncActiveOption() {\n this._options.forEach((option, index) =>\n option.toggleAttribute('active', index === this._activeIndex && this._isLive(option))\n )\n }\n\n private _notifyValueChange() {\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private _syncScrollLock(isOpen = this._isOpen) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n private _togglePopup() {\n if (this._isDisabled) return\n if (this._isOpen) this._close()\n else this._open()\n }\n\n private _openOverlay(isKeyboardNavigation = false) {\n this._panel.open(isKeyboardNavigation)\n }\n\n private _createPortal(): OverlayPortal {\n const portal = defineOverlayPortal().make({\n container: this.overlayContainer,\n target: this,\n style: `${glass}\\n${overlayMotion}\\n${style}`,\n className: 'wui-glass select-overlay portal wui-floating-panel',\n onContentChange: () => this._optionPortal.scheduleRefresh()\n })\n this._portal = portal\n applyOverlayVariables(portal.panel, this, [\n '--wui-overlay-min-width',\n '--wui-select-max-width',\n '--wui-select-max-height'\n ])\n portal.panel.setAttribute('role', 'listbox')\n const scroll = document.createElement('div')\n scroll.className = 'select-scroll'\n const content = document.createElement('div')\n content.className = 'select-content'\n this._portalContent = content\n scroll.append(content)\n portal.panel.append(scroll)\n // 自定义 trigger 必须留在宿主内,不能随 options 迁入 portal 面板\n portal.moveContent(\n Array.from(this.children).filter(child => child.slot !== 'trigger'),\n content\n )\n return portal\n }\n\n private _reconfigureOverlay() {\n // reconfigure 会 dispose 并按需重建 portal,旧引用必须同步失效\n this._portal = undefined\n this._portalContent = undefined\n this._panel.reconfigure(this._isOpen)\n }\n\n private async _closeOverlay() {\n const closed = await this._panel.close(() => this._isOpen)\n // portal 已随关闭 dispose,与 autocomplete 对齐同步失效引用\n if (closed) {\n this._portal = undefined\n this._portalContent = undefined\n }\n }\n\n override render() {\n // portal 模式下 options 被 moveContent 移入浮层 shadow root,id 引用无法跨树作用域\n // 解析,因此 activedescendant 仅在非 portal 模式输出;aria-controls 同理指向同根内 listbox\n const listboxId = `${this.localName}-listbox`\n const activeDescendant =\n !this.portal && this._isOpen && this._activeIndex >= 0\n ? (this._options[this._activeIndex]?.id ?? nothing)\n : nothing\n\n return html`\n <div class=\"wui-select-inner\">\n <div\n class=\"wui-glass select-trigger\"\n ?data-custom-trigger=${this._hasTriggerSlot}\n @click=${this._togglePopup}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"combobox\"\n aria-expanded=${this._isOpen}\n aria-haspopup=\"listbox\"\n aria-controls=${this.portal ? nothing : listboxId}\n aria-disabled=${String(this._isDisabled)}\n aria-activedescendant=${activeDescendant}\n >\n <slot name=\"trigger\" @slotchange=${this._onTriggerSlotChange}></slot>\n ${!this._hasTriggerSlot ? html`<span class=\"label\">${this._selectedLabel}</span>` : nothing}\n <web-ui-icon class=\"arrow\" .icon=${lucideChevronDown}></web-ui-icon>\n </div>\n <div class=\"select-overlay wui-floating-panel wui-glass\" hidden role=\"listbox\" id=${listboxId}>\n <div class=\"select-scroll\">\n <div class=\"select-content\">\n <slot @slotchange=${this._onSlotChange}></slot>\n </div>\n </div>\n </div>\n </div>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-select': WebUiSelect\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/select/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{--wui-select-bg-hover:var(--wui-color-surface-glass-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, var(--wui-color-surface-glass,#fafafa57)));--wui-select-bg-active:var(--wui-color-surface-glass-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, var(--wui-color-surface-glass,#fafafa57)));-webkit-user-select:none;user-select:none;display:inline-block}:host([disabled]){cursor:not-allowed;opacity:.4}.wui-select-inner{flex-direction:column;display:flex;position:relative}.select-trigger{cursor:default;box-sizing:border-box;width:var(--wui-input-width,200px);min-width:var(--wui-control-size,36px);height:var(--wui-control-size,36px);border:
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{--wui-select-bg-hover:var(--wui-color-surface-glass-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, var(--wui-color-surface-glass,#fafafa57)));--wui-select-bg-active:var(--wui-color-surface-glass-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, var(--wui-color-surface-glass,#fafafa57)));-webkit-user-select:none;user-select:none;display:inline-block}:host([disabled]){cursor:not-allowed;opacity:.4}.wui-select-inner{flex-direction:column;display:flex;position:relative}.select-trigger{--wui-glass-corner-radius:calc(var(--wui-control-size,36px) / 2);cursor:default;box-sizing:border-box;width:var(--wui-input-width,200px);min-width:var(--wui-control-size,36px);height:var(--wui-control-size,36px);border-radius:var(--wui-radius-control,calc(infinity * 1px));border:none;align-items:center;gap:8px;padding:0 12px;display:flex;overflow:clip}.select-trigger:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,#08f6);outline-offset:2px}:host([disabled]) .select-trigger{cursor:not-allowed}@media (hover:hover) and (pointer:fine){:host(:not([disabled])) .select-trigger:hover{background-color:var(--wui-select-bg-hover)}}:host(:not([disabled])) .select-trigger:active,:host([open]:not([disabled])) .select-trigger{background-color:var(--wui-select-bg-active)}.select-trigger[data-custom-trigger]{width:auto}.label{font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}:host(:not([data-has-value])) .label{color:var(--wui-color-text-secondary,#6a6a6a)}::slotted([slot=trigger]){font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.arrow{color:var(--wui-color-text-secondary,#6a6a6a);flex-shrink:0}:host([open]) .arrow{transform:rotate(180deg)}.select-overlay{--wui-internal-glass-shadow:var(--wui-shadow-panel,0 3px 9px #00000045);--wui-internal-duration-float-enter:var(--wui-duration-float-enter,.16s);--wui-internal-duration-float-exit:var(--wui-duration-float-exit,.12s);--wui-glass-corner-radius:var(--wui-radius-menu,18px);z-index:var(--wui-layer-inline-overlay,1);box-sizing:border-box;min-width:var(--wui-overlay-min-width,200px);max-width:var(--wui-select-max-width,500px);border-radius:var(--wui-radius-menu,18px);background-color:var(--wui-color-surface-menu,#f6f6f6d1);position:absolute;overflow:hidden}.select-overlay.portal{z-index:var(--wui-layer-menu,100);position:fixed}.select-overlay.hidden{display:none}.select-scroll{max-height:var(--wui-select-max-height,200px);overflow-y:auto}.select-content{padding:4px}:host([portal]) .select-overlay{display:none}:host([data-wui-pointer-focus]) .select-trigger:focus-visible{outline-color:#0000}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/select/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n --wui-select-bg-hover: var(\n --wui-color-surface-glass-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n --wui-select-bg-active: var(\n --wui-color-surface-glass-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n user-select: none;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wui-select-inner {\n position: relative;\n display: flex;\n flex-direction: column;\n}\n\n.select-trigger {\n cursor: default;\n\n overflow: clip;\n display: flex;\n gap: 8px;\n align-items: center;\n\n box-sizing: border-box;\n width: var(--wui-input-width, 200px);\n min-width: var(--wui-control-size, 36px);\n height: var(--wui-control-size, 36px);\n padding: 0 12px;\n border: none;\n border-radius: calc(infinity * 1px);\n\n &:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid var(--wui-color-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n}\n\n:host([disabled]) .select-trigger {\n cursor: not-allowed;\n}\n\n@media (hover: hover) and (pointer: fine) {\n :host(:not([disabled])) .select-trigger:hover {\n background-color: var(--wui-select-bg-hover);\n }\n}\n\n:host(:not([disabled])) .select-trigger:active,\n:host([open]:not([disabled])) .select-trigger {\n background-color: var(--wui-select-bg-active);\n}\n\n.select-trigger[data-custom-trigger] {\n width: auto;\n}\n\n.label {\n overflow: hidden;\n flex: 1;\n\n font-size: var(--wui-font-size, 14px);\n color: var(--wui-color-text, #1b1b1b);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n:host(:not([data-has-value])) .label {\n color: var(--wui-color-text-secondary, #6a6a6a);\n}\n\n::slotted([slot='trigger']) {\n overflow: hidden;\n flex: 1;\n\n font-size: var(--wui-font-size, 14px);\n color: var(--wui-color-text, #1b1b1b);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.arrow {\n flex-shrink: 0;\n color: var(--wui-color-text-secondary, #6a6a6a);\n}\n\n:host([open]) .arrow {\n transform: rotate(180deg);\n}\n\n/* ===== 浮层(glass 样式参考 dialog) ===== */\n\n.select-overlay {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-internal-duration-
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/select/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n --wui-select-bg-hover: var(\n --wui-color-surface-glass-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n --wui-select-bg-active: var(\n --wui-color-surface-glass-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n user-select: none;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wui-select-inner {\n position: relative;\n display: flex;\n flex-direction: column;\n}\n\n.select-trigger {\n --wui-glass-corner-radius: calc(var(--wui-control-size, 36px) / 2);\n\n cursor: default;\n\n overflow: clip;\n display: flex;\n gap: 8px;\n align-items: center;\n\n box-sizing: border-box;\n width: var(--wui-input-width, 200px);\n min-width: var(--wui-control-size, 36px);\n height: var(--wui-control-size, 36px);\n padding: 0 12px;\n border: none;\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n &:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid var(--wui-color-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n}\n\n:host([disabled]) .select-trigger {\n cursor: not-allowed;\n}\n\n@media (hover: hover) and (pointer: fine) {\n :host(:not([disabled])) .select-trigger:hover {\n background-color: var(--wui-select-bg-hover);\n }\n}\n\n:host(:not([disabled])) .select-trigger:active,\n:host([open]:not([disabled])) .select-trigger {\n background-color: var(--wui-select-bg-active);\n}\n\n.select-trigger[data-custom-trigger] {\n width: auto;\n}\n\n.label {\n overflow: hidden;\n flex: 1;\n\n font-size: var(--wui-font-size, 14px);\n color: var(--wui-color-text, #1b1b1b);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n:host(:not([data-has-value])) .label {\n color: var(--wui-color-text-secondary, #6a6a6a);\n}\n\n::slotted([slot='trigger']) {\n overflow: hidden;\n flex: 1;\n\n font-size: var(--wui-font-size, 14px);\n color: var(--wui-color-text, #1b1b1b);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.arrow {\n flex-shrink: 0;\n color: var(--wui-color-text-secondary, #6a6a6a);\n}\n\n:host([open]) .arrow {\n transform: rotate(180deg);\n}\n\n/* ===== 浮层(glass 样式参考 dialog) ===== */\n\n.select-overlay {\n --wui-internal-glass-shadow: var(--wui-shadow-panel, 0 3px 9px rgb(0 0 0 / 0.27));\n --wui-internal-duration-float-enter: var(--wui-duration-float-enter, 160ms);\n --wui-internal-duration-float-exit: var(--wui-duration-float-exit, 120ms);\n --wui-glass-corner-radius: var(--wui-radius-menu, 18px);\n position: absolute;\n z-index: var(--wui-layer-inline-overlay, 1);\n\n overflow: hidden;\n\n box-sizing: border-box;\n min-width: var(--wui-overlay-min-width, 200px);\n max-width: var(--wui-select-max-width, 500px);\n border-radius: var(--wui-radius-menu, 18px);\n\n /* 玻璃背景:wui-glass 在面板自身,这里覆盖其默认玻璃底为菜单表面色 */\n background-color: var(--wui-color-surface-menu, rgb(246 246 246 / 0.82));\n\n &.portal {\n position: fixed;\n z-index: var(--wui-layer-menu, 100);\n }\n\n &.hidden {\n display: none;\n }\n}\n\n.select-scroll {\n overflow-y: auto;\n max-height: var(--wui-select-max-height, 200px);\n}\n\n.select-content {\n padding: 4px;\n}\n\n:host([portal]) .select-overlay {\n display: none;\n}\n\n:host([data-wui-pointer-focus]) .select-trigger:focus-visible {\n outline-color: transparent;\n}\n"],"mappings":""}
|