@greypan/web-ui 2.1.7 → 2.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.CN.md +51 -35
  2. package/README.md +54 -35
  3. package/dist/assets/glass.js.map +1 -1
  4. package/dist/components/avatar/index.js +1 -1
  5. package/dist/components/avatar/index.js.map +1 -1
  6. package/dist/components/back-top/index.js +1 -1
  7. package/dist/components/back-top/index.js.map +1 -1
  8. package/dist/components/button/index.d.ts +6 -1
  9. package/dist/components/button/index.js +35 -14
  10. package/dist/components/button/index.js.map +1 -1
  11. package/dist/components/button/style.js +1 -1
  12. package/dist/components/button/style.js.map +1 -1
  13. package/dist/components/checkbox/index.d.ts +0 -3
  14. package/dist/components/checkbox/index.js.map +1 -1
  15. package/dist/components/context-menu/index.d.ts +4 -3
  16. package/dist/components/context-menu/index.js +47 -50
  17. package/dist/components/context-menu/index.js.map +1 -1
  18. package/dist/components/dialog/index.d.ts +1 -1
  19. package/dist/components/dialog/index.js +20 -19
  20. package/dist/components/dialog/index.js.map +1 -1
  21. package/dist/components/drawer/index.d.ts +2 -3
  22. package/dist/components/drawer/index.js +41 -31
  23. package/dist/components/drawer/index.js.map +1 -1
  24. package/dist/components/drawer/style.js +1 -1
  25. package/dist/components/drawer/style.js.map +1 -1
  26. package/dist/components/dropdown/index.d.ts +2 -9
  27. package/dist/components/dropdown/index.js +55 -51
  28. package/dist/components/dropdown/index.js.map +1 -1
  29. package/dist/components/dropdown-item/index.d.ts +0 -1
  30. package/dist/components/dropdown-item/index.js.map +1 -1
  31. package/dist/components/empty/index.js.map +1 -1
  32. package/dist/components/input/index.d.ts +1 -0
  33. package/dist/components/input/index.js +27 -14
  34. package/dist/components/input/index.js.map +1 -1
  35. package/dist/components/input/style.js +1 -1
  36. package/dist/components/input/style.js.map +1 -1
  37. package/dist/components/input-number/index.js.map +1 -1
  38. package/dist/components/option/index.js +1 -1
  39. package/dist/components/option/index.js.map +1 -1
  40. package/dist/components/popover/index.d.ts +1 -5
  41. package/dist/components/popover/index.js +41 -36
  42. package/dist/components/popover/index.js.map +1 -1
  43. package/dist/components/radio/index.d.ts +0 -3
  44. package/dist/components/radio/index.js.map +1 -1
  45. package/dist/components/segmented/index.js +6 -2
  46. package/dist/components/segmented/index.js.map +1 -1
  47. package/dist/components/segmented-trigger/index.js +1 -1
  48. package/dist/components/segmented-trigger/index.js.map +1 -1
  49. package/dist/components/segmented-trigger/style.js +1 -1
  50. package/dist/components/segmented-trigger/style.js.map +1 -1
  51. package/dist/components/select/index.js +5 -3
  52. package/dist/components/select/index.js.map +1 -1
  53. package/dist/components/slider/index.d.ts +0 -2
  54. package/dist/components/slider/index.js +1 -1
  55. package/dist/components/slider/index.js.map +1 -1
  56. package/dist/components/spinner/index.d.ts +0 -2
  57. package/dist/components/spinner/index.js.map +1 -1
  58. package/dist/components/svg-draw-lines/index.d.ts +0 -2
  59. package/dist/components/svg-draw-lines/index.js.map +1 -1
  60. package/dist/components/switch/index.d.ts +0 -1
  61. package/dist/components/switch/index.js.map +1 -1
  62. package/dist/components/switch/style.js +1 -1
  63. package/dist/components/switch/style.js.map +1 -1
  64. package/dist/components/textarea/index.d.ts +1 -0
  65. package/dist/components/textarea/index.js +47 -33
  66. package/dist/components/textarea/index.js.map +1 -1
  67. package/dist/components/textarea/style.js +1 -1
  68. package/dist/components/textarea/style.js.map +1 -1
  69. package/dist/components/theme/index.d.ts +0 -2
  70. package/dist/components/theme/index.js.map +1 -1
  71. package/dist/components/toast/manager.js.map +1 -1
  72. package/dist/components/toast/style.js +1 -1
  73. package/dist/components/toast/style.js.map +1 -1
  74. package/dist/components/toast/toast.d.ts +0 -4
  75. package/dist/components/toast/toast.js +14 -6
  76. package/dist/components/toast/toast.js.map +1 -1
  77. package/dist/components/toast/types.d.ts +0 -3
  78. package/dist/components/tooltip/index.d.ts +1 -0
  79. package/dist/components/tooltip/index.js +31 -30
  80. package/dist/components/tooltip/index.js.map +1 -1
  81. package/dist/shared/events/user-change.js +17 -0
  82. package/dist/shared/events/user-change.js.map +1 -0
  83. package/dist/shared/normalize/index.js.map +1 -1
  84. package/dist/shared/overlay/native-dialog-presence.js +8 -3
  85. package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
  86. package/dist/shared/overlay/overlay.js.map +1 -1
  87. package/dist/shared/overlay/portal.js +3 -1
  88. package/dist/shared/overlay/portal.js.map +1 -1
  89. package/dist/shared/overlay/presence.js.map +1 -1
  90. package/package.json +9 -4
@@ -1,14 +1,15 @@
1
1
  import e from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
2
2
  import t from "../../assets/glass.js";
3
3
  import { normalizeLiteral as n, normalizeNumber as r } from "../../shared/normalize/index.js";
4
- import i from "../../assets/overlay-motion.js";
5
- import { defineAnchoredPanel as a } from "../../shared/overlay/anchored-panel.js";
6
- import { createOverlayPortal as o } from "../../shared/overlay/portal.js";
7
- import s from "./style.js";
8
- import { LitElement as c, html as l, unsafeCSS as u } from "lit";
9
- import { customElement as d, property as f } from "lit/decorators.js";
4
+ import { UserChangeController as i } from "../../shared/events/user-change.js";
5
+ import a from "../../assets/overlay-motion.js";
6
+ import { defineAnchoredPanel as o } from "../../shared/overlay/anchored-panel.js";
7
+ import { createOverlayPortal as s } from "../../shared/overlay/portal.js";
8
+ import c from "./style.js";
9
+ import { LitElement as l, html as u, unsafeCSS as d } from "lit";
10
+ import { customElement as f, property as p } from "lit/decorators.js";
10
11
  //#region src/components/popover/index.ts
11
- var p = [
12
+ var m = [
12
13
  "top",
13
14
  "top-start",
14
15
  "top-end",
@@ -21,13 +22,13 @@ var p = [
21
22
  "right",
22
23
  "right-start",
23
24
  "right-end"
24
- ], m = [
25
+ ], h = [
25
26
  "click",
26
27
  "hover",
27
28
  "manual"
28
- ], h = 0, g = class extends c {
29
+ ], g = 0, _ = class extends l {
29
30
  constructor(...e) {
30
- super(...e), this.open = !1, this.disabled = !1, this._placement = "bottom", this._offset = 8, this._trigger = "click", this.portal = !1, this._suppressEvent = !1, this._shouldOpenInstantly = !0, this._panelId = `wui-popover-panel-${++h}`, this._panel = a().make({
31
+ super(...e), this.open = !1, this.disabled = !1, this._placement = "bottom", this._offset = 8, this._trigger = "click", this.portal = !1, this._userOpenChange = new i(), this._shouldOpenInstantly = !0, this._panelId = `wui-popover-panel-${++g}`, this._panel = o().make({
31
32
  getAnchor: () => this.shadowRoot?.querySelector(".popover-trigger") ?? null,
32
33
  getLocalPanel: () => this.shadowRoot?.querySelector(".popover-panel") ?? null,
33
34
  getPositioning: () => ({
@@ -38,32 +39,36 @@ var p = [
38
39
  isPortal: () => this.portal,
39
40
  createPortal: () => this._createPortal()
40
41
  }), this._onTriggerClick = (e) => {
41
- this.disabled || (clearTimeout(this._showTimer), clearTimeout(this._hideTimer), this.trigger !== "hover" && (this.open || (this._shouldOpenInstantly = e.detail === 0), this.toggle()));
42
+ this.disabled || (clearTimeout(this._showTimer), clearTimeout(this._hideTimer), this.trigger !== "hover" && (this.open || (this._shouldOpenInstantly = e.detail === 0), this._userOpenChange.mark(), this.toggle()));
42
43
  }, this._onClickOutside = (e) => {
43
- this.open && this.trigger !== "manual" && this.trigger !== "hover" && (e.target instanceof Node && this.portal && this._panel.getPanel()?.contains(e.target) || this._isInsideShadowRoot(e) || (this.open = !1));
44
+ this.open && this.trigger !== "manual" && this.trigger !== "hover" && (e.target instanceof Node && this.portal && this._panel.getPanel()?.contains(e.target) || this._isInsideShadowRoot(e) || (this._userOpenChange.mark(), this.open = !1));
44
45
  }, this._onFocusOut = () => {
45
46
  this.trigger !== "manual" && this.trigger !== "hover" && requestAnimationFrame(() => {
46
- this.open && !this.matches(":focus-within") && !this._panel.getPanel()?.matches(":focus-within") && (this.open = !1);
47
+ this.open && !this.matches(":focus-within") && !this._panel.getPanel()?.matches(":focus-within") && (this._userOpenChange.mark(), this.open = !1);
47
48
  });
48
49
  }, this._onKeydown = (e) => {
49
- this.open && this.trigger !== "manual" && e.key === "Escape" && (this.open = !1, e.preventDefault());
50
+ this.open && this.trigger !== "manual" && e.key === "Escape" && (this._userOpenChange.mark(), this.open = !1, e.preventDefault());
50
51
  }, this._onPointerEnter = (e) => {
51
52
  e.pointerType !== "touch" && (this.disabled || this.trigger !== "hover" || (clearTimeout(this._hideTimer), this._showTimer = setTimeout(() => {
52
- this._shouldOpenInstantly = !1, this.show();
53
+ this._shouldOpenInstantly = !1, !this.open && (this._userOpenChange.mark(), this.show());
53
54
  }, 100)));
54
55
  }, this._onPointerLeave = (e) => {
55
- e.pointerType !== "touch" && (this.disabled || this.trigger !== "hover" || (clearTimeout(this._showTimer), this._hideTimer = setTimeout(() => this.close(), 100)));
56
+ e.pointerType !== "touch" && (this.disabled || this.trigger !== "hover" || (clearTimeout(this._showTimer), this._hideTimer = setTimeout(() => {
57
+ this.open && (this._userOpenChange.mark(), this.close());
58
+ }, 100)));
56
59
  }, this._onPanelPointerEnter = (e) => {
57
60
  e.pointerType !== "touch" && this.trigger === "hover" && clearTimeout(this._hideTimer);
58
61
  }, this._onPanelPointerLeave = (e) => {
59
- e.pointerType !== "touch" && this.trigger === "hover" && (this._hideTimer = setTimeout(() => this.close(), 100));
62
+ e.pointerType !== "touch" && this.trigger === "hover" && (this._hideTimer = setTimeout(() => {
63
+ this.open && (this._userOpenChange.mark(), this.close());
64
+ }, 100));
60
65
  };
61
66
  }
62
67
  static {
63
68
  this.styles = [
64
- u(t),
65
- u(i),
66
- u(s)
69
+ d(t),
70
+ d(a),
71
+ d(c)
67
72
  ];
68
73
  }
69
74
  get placement() {
@@ -71,7 +76,7 @@ var p = [
71
76
  }
72
77
  set placement(e) {
73
78
  let t = this._placement;
74
- this._placement = n(e, p, "bottom"), this.requestUpdate("placement", t);
79
+ this._placement = n(e, m, "bottom"), this.requestUpdate("placement", t);
75
80
  }
76
81
  get offset() {
77
82
  return this._offset;
@@ -85,7 +90,7 @@ var p = [
85
90
  }
86
91
  set trigger(e) {
87
92
  let t = this._trigger;
88
- this._trigger = n(e, m, "click"), this.requestUpdate("trigger", t);
93
+ this._trigger = n(e, h, "click"), this.requestUpdate("trigger", t);
89
94
  }
90
95
  get isOpen() {
91
96
  return this.open;
@@ -102,15 +107,15 @@ var p = [
102
107
  updated(e) {
103
108
  if (e.has("portal") || e.has("overlayContainer") ? requestAnimationFrame(() => this._reconfigureOverlay()) : (e.has("placement") || e.has("offset")) && requestAnimationFrame(() => this._panel.updatePosition()), e.has("open")) if (this.open) {
104
109
  let e = this._shouldOpenInstantly;
105
- this._shouldOpenInstantly = !0, requestAnimationFrame(() => this._openOverlay(e)), this._dispatchChange(!0), this._focusPanel();
106
- } else this._returnFocus(), this._closeOverlay(), this._suppressEvent || this._dispatchChange(!1);
110
+ this._shouldOpenInstantly = !0, requestAnimationFrame(() => this._openOverlay(e)), this._userOpenChange.consume() && this._dispatchChange(!0), this._focusPanel();
111
+ } else this._returnFocus(), this._closeOverlay(), this._userOpenChange.consume() && this._dispatchChange(!1);
107
112
  e.has("trigger") && (this.removeEventListener("pointerenter", this._onPointerEnter), this.removeEventListener("pointerleave", this._onPointerLeave), clearTimeout(this._showTimer), clearTimeout(this._hideTimer), this._syncTriggerListeners());
108
113
  }
109
114
  show() {
110
- this.disabled || this.open || (this._suppressEvent = !0, this.open = !0, this._suppressEvent = !1);
115
+ this.disabled || this.open || (this.open = !0);
111
116
  }
112
117
  close() {
113
- this.open && (this._suppressEvent = !0, this.open = !1, this._suppressEvent = !1);
118
+ this.open &&= !1;
114
119
  }
115
120
  toggle() {
116
121
  this.open ? this.close() : this.show();
@@ -126,10 +131,10 @@ var p = [
126
131
  this._panel.open(e);
127
132
  }
128
133
  _createPortal() {
129
- let e = o({
134
+ let e = s({
130
135
  container: this.overlayContainer,
131
136
  target: this,
132
- style: `${t}\n${i}\n${s}`,
137
+ style: `${t}\n${a}\n${c}`,
133
138
  className: "popover-panel portal wui-glass wui-floating-panel"
134
139
  });
135
140
  return e.panel.id = this._panelId, e.panel.setAttribute("role", "dialog"), e.panel.tabIndex = -1, e.panel.addEventListener("pointerenter", this._onPanelPointerEnter), e.panel.addEventListener("pointerleave", this._onPanelPointerLeave), e.moveContent(Array.from(this.childNodes).filter((e) => !(e instanceof HTMLElement && e.slot === "trigger"))), e;
@@ -161,7 +166,7 @@ var p = [
161
166
  return e instanceof HTMLElement ? e : null;
162
167
  }
163
168
  render() {
164
- return l`
169
+ return u`
165
170
  <div class="popover-anchor">
166
171
  <div
167
172
  class="popover-trigger"
@@ -186,23 +191,23 @@ var p = [
186
191
  `;
187
192
  }
188
193
  };
189
- e([f({
194
+ e([p({
190
195
  type: Boolean,
191
196
  reflect: !0
192
- })], g.prototype, "open", void 0), e([f({
197
+ })], _.prototype, "open", void 0), e([p({
193
198
  type: Boolean,
194
199
  reflect: !0
195
- })], g.prototype, "disabled", void 0), e([f({
200
+ })], _.prototype, "disabled", void 0), e([p({
196
201
  type: String,
197
202
  reflect: !0
198
- })], g.prototype, "placement", null), e([f({ type: Number })], g.prototype, "offset", null), e([f({
203
+ })], _.prototype, "placement", null), e([p({ type: Number })], _.prototype, "offset", null), e([p({
199
204
  type: String,
200
205
  reflect: !0
201
- })], g.prototype, "trigger", null), e([f({
206
+ })], _.prototype, "trigger", null), e([p({
202
207
  type: Boolean,
203
208
  reflect: !0
204
- })], g.prototype, "portal", void 0), e([f({ attribute: !1 })], g.prototype, "overlayContainer", void 0), g = e([d("web-ui-popover")], g);
209
+ })], _.prototype, "portal", void 0), e([p({ attribute: !1 })], _.prototype, "overlayContainer", void 0), _ = e([f("web-ui-popover")], _);
205
210
  //#endregion
206
- export { g as WebUiPopover };
211
+ export { _ as WebUiPopover };
207
212
 
208
213
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/popover/index.ts"],"sourcesContent":["import type { Placement } from '@floating-ui/dom'\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport glass from '@/assets/glass.css?inline'\nimport overlayMotion from '@/assets/overlay-motion.css?inline'\nimport { normalizeLiteral, normalizeNumber } from '@/shared/normalize'\nimport { defineAnchoredPanel } from '@/shared/overlay/anchored-panel'\nimport { createOverlayPortal } from '@/shared/overlay/portal'\nimport type { OverlayContainer, OverlayPortal } from '@/shared/overlay/portal'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_PLACEMENTS = [\n 'top',\n 'top-start',\n 'top-end',\n 'bottom',\n 'bottom-start',\n 'bottom-end',\n 'left',\n 'left-start',\n 'left-end',\n 'right',\n 'right-start',\n 'right-end'\n] as const\n\nconst ALLOWED_TRIGGERS = ['click', 'hover', 'manual'] as const\n\nlet popoverIdCounter = 0\n\n@customElement('web-ui-popover')\nexport class WebUiPopover extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(overlayMotion), unsafeCSS(style)]\n\n @property({ type: Boolean, reflect: true }) open = false\n @property({ type: Boolean, reflect: true }) disabled = false\n\n @property({ type: String, reflect: true })\n get placement(): Placement {\n return this._placement\n }\n set placement(v: string) {\n const old = this._placement\n this._placement = normalizeLiteral(v, ALLOWED_PLACEMENTS, 'bottom')\n this.requestUpdate('placement', old)\n }\n private _placement: Placement = 'bottom'\n\n @property({ type: Number })\n get offset(): number {\n return this._offset\n }\n set offset(v: number) {\n const old = this._offset\n this._offset = normalizeNumber(v, 0, 100, 8)\n this.requestUpdate('offset', old)\n }\n private _offset = 8\n\n @property({ type: String, reflect: true })\n get trigger(): 'click' | 'hover' | 'manual' {\n return this._trigger\n }\n set trigger(v: string) {\n const old = this._trigger\n this._trigger = normalizeLiteral(v, ALLOWED_TRIGGERS, 'click')\n this.requestUpdate('trigger', old)\n }\n private _trigger: 'click' | 'hover' | 'manual' = 'click'\n\n @property({ type: Boolean, reflect: true }) portal = false\n @property({ attribute: false }) overlayContainer?: OverlayContainer\n\n private _showTimer?: ReturnType<typeof setTimeout>\n private _hideTimer?: ReturnType<typeof setTimeout>\n private _suppressEvent = false\n private _shouldOpenInstantly = true\n\n private _panelId = `wui-popover-panel-${++popoverIdCounter}`\n private readonly _panel = defineAnchoredPanel().make({\n getAnchor: () => this.shadowRoot?.querySelector<HTMLElement>('.popover-trigger') ?? null,\n getLocalPanel: () => this.shadowRoot?.querySelector<HTMLElement>('.popover-panel') ?? null,\n getPositioning: () => ({\n placement: this.placement,\n offset: this.offset,\n strategy: this.portal ? 'fixed' : 'absolute'\n }),\n isPortal: () => this.portal,\n createPortal: () => this._createPortal()\n })\n\n /** 当前是否打开 */\n get isOpen(): boolean {\n return this.open\n }\n\n override connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._onClickOutside)\n document.addEventListener('keydown', this._onKeydown)\n this.addEventListener('focusout', this._onFocusOut)\n this._syncTriggerListeners()\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._onClickOutside)\n document.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('focusout', this._onFocusOut)\n this.removeEventListener('pointerenter', this._onPointerEnter)\n this.removeEventListener('pointerleave', this._onPointerLeave)\n clearTimeout(this._showTimer)\n clearTimeout(this._hideTimer)\n this._panel.dispose()\n }\n\n override firstUpdated() {\n if (this.open) {\n requestAnimationFrame(() => this._openOverlay(this._shouldOpenInstantly))\n this._shouldOpenInstantly = true\n }\n }\n\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has('portal') || changed.has('overlayContainer'))\n requestAnimationFrame(() => this._reconfigureOverlay())\n else if (changed.has('placement') || changed.has('offset'))\n requestAnimationFrame(() => this._panel.updatePosition())\n\n if (changed.has('open')) {\n if (this.open) {\n const isInstant = this._shouldOpenInstantly\n this._shouldOpenInstantly = true\n requestAnimationFrame(() => this._openOverlay(isInstant))\n this._dispatchChange(true)\n this._focusPanel()\n } else {\n this._returnFocus()\n void this._closeOverlay()\n if (!this._suppressEvent) this._dispatchChange(false)\n }\n }\n\n if (changed.has('trigger')) {\n this.removeEventListener('pointerenter', this._onPointerEnter)\n this.removeEventListener('pointerleave', this._onPointerLeave)\n clearTimeout(this._showTimer)\n clearTimeout(this._hideTimer)\n this._syncTriggerListeners()\n }\n }\n\n /** 打开 popover */\n show() {\n if (this.disabled || this.open) return\n this._suppressEvent = true\n this.open = true\n this._suppressEvent = false\n }\n\n /** 关闭 popover */\n close() {\n if (!this.open) return\n this._suppressEvent = true\n this.open = false\n this._suppressEvent = false\n }\n\n /** 切换 popover */\n toggle() {\n if (this.open) this.close()\n else this.show()\n }\n\n private _isInsideShadowRoot(e: MouseEvent): boolean {\n for (const node of e.composedPath()) {\n if (node instanceof Node && node.getRootNode() === this.shadowRoot) return true\n }\n return false\n }\n\n private _syncTriggerListeners() {\n if (this.trigger === 'hover') {\n this.addEventListener('pointerenter', this._onPointerEnter)\n this.addEventListener('pointerleave', this._onPointerLeave)\n }\n }\n\n private _openOverlay(isInstant = false) {\n this._panel.open(isInstant)\n }\n\n private _createPortal(): OverlayPortal {\n const portal = createOverlayPortal({\n container: this.overlayContainer,\n target: this,\n style: `${glass}\\n${overlayMotion}\\n${style}`,\n className: 'popover-panel portal wui-glass wui-floating-panel'\n })\n portal.panel.id = this._panelId\n portal.panel.setAttribute('role', 'dialog')\n portal.panel.tabIndex = -1\n portal.panel.addEventListener('pointerenter', this._onPanelPointerEnter)\n portal.panel.addEventListener('pointerleave', this._onPanelPointerLeave)\n portal.moveContent(\n Array.from(this.childNodes).filter(node => !(node instanceof HTMLElement && node.slot === 'trigger'))\n )\n return portal\n }\n\n private async _closeOverlay() {\n await this._panel.close(() => this.open)\n }\n\n private _reconfigureOverlay() {\n this._panel.reconfigure(this.open)\n }\n\n private _dispatchChange(open: boolean) {\n this.dispatchEvent(\n new CustomEvent('open-change', {\n detail: { open },\n bubbles: true,\n composed: true\n })\n )\n }\n\n private _focusPanel() {\n requestAnimationFrame(() => {\n const panel = this._panel.getPanel()\n const autofocus = panel?.querySelector<HTMLElement>('[autofocus]')\n if (autofocus && !autofocus.matches(':disabled, [disabled]')) autofocus.focus()\n })\n }\n\n private _returnFocus() {\n const panel = this._panel.getPanel()\n if (!panel?.matches(':focus-within')) return\n const trigger = this._queryTrigger()\n trigger?.focus()\n }\n\n private _queryTrigger(): HTMLElement | null {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"trigger\"]')\n const el = slot?.assignedElements()[0]\n return el instanceof HTMLElement ? el : null\n }\n\n private _onTriggerClick = (event: MouseEvent) => {\n if (this.disabled) return\n clearTimeout(this._showTimer)\n clearTimeout(this._hideTimer)\n if (this.trigger === 'hover') return\n if (!this.open) this._shouldOpenInstantly = event.detail === 0\n this.toggle()\n }\n\n private _onClickOutside = (e: MouseEvent) => {\n if (!this.open) return\n if (this.trigger === 'manual' || this.trigger === 'hover') return\n if (e.target instanceof Node && this.portal && this._panel.getPanel()?.contains(e.target)) return\n if (this._isInsideShadowRoot(e)) return\n this.open = false\n }\n\n private _onFocusOut = () => {\n if (this.trigger === 'manual' || this.trigger === 'hover') return\n\n requestAnimationFrame(() => {\n if (this.open && !this.matches(':focus-within') && !this._panel.getPanel()?.matches(':focus-within')) {\n this.open = false\n }\n })\n }\n\n private _onKeydown = (e: KeyboardEvent) => {\n if (!this.open) return\n if (this.trigger === 'manual') return\n if (e.key === 'Escape') {\n this.open = false\n e.preventDefault()\n }\n }\n\n private _onPointerEnter = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.disabled || this.trigger !== 'hover') return\n clearTimeout(this._hideTimer)\n this._showTimer = setTimeout(() => {\n this._shouldOpenInstantly = false\n this.show()\n }, 100)\n }\n\n private _onPointerLeave = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.disabled || this.trigger !== 'hover') return\n clearTimeout(this._showTimer)\n this._hideTimer = setTimeout(() => this.close(), 100)\n }\n\n private _onPanelPointerEnter = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.trigger !== 'hover') return\n clearTimeout(this._hideTimer)\n }\n\n private _onPanelPointerLeave = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.trigger !== 'hover') return\n this._hideTimer = setTimeout(() => this.close(), 100)\n }\n\n override render() {\n return html`\n <div class=\"popover-anchor\">\n <div\n class=\"popover-trigger\"\n aria-expanded=${String(this.open)}\n aria-controls=${this._panelId}\n @click=${this._onTriggerClick}\n >\n <slot name=\"trigger\"></slot>\n </div>\n <div\n id=${this._panelId}\n class=\"popover-panel wui-glass wui-floating-panel\"\n hidden\n role=\"dialog\"\n tabindex=\"-1\"\n @pointerenter=${this._onPanelPointerEnter}\n @pointerleave=${this._onPanelPointerLeave}\n >\n <slot></slot>\n </div>\n </div>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-popover': WebUiPopover\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/popover/index.ts"],"sourcesContent":["import type { Placement } from '@floating-ui/dom'\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport glass from '@/assets/glass.css?inline'\nimport overlayMotion from '@/assets/overlay-motion.css?inline'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport { normalizeLiteral, normalizeNumber } from '@/shared/normalize'\nimport { defineAnchoredPanel } from '@/shared/overlay/anchored-panel'\nimport { createOverlayPortal } from '@/shared/overlay/portal'\nimport type { OverlayContainer, OverlayPortal } from '@/shared/overlay/portal'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_PLACEMENTS = [\n 'top',\n 'top-start',\n 'top-end',\n 'bottom',\n 'bottom-start',\n 'bottom-end',\n 'left',\n 'left-start',\n 'left-end',\n 'right',\n 'right-start',\n 'right-end'\n] as const\n\nconst ALLOWED_TRIGGERS = ['click', 'hover', 'manual'] as const\n\nlet popoverIdCounter = 0\n\n@customElement('web-ui-popover')\nexport class WebUiPopover extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(overlayMotion), unsafeCSS(style)]\n\n @property({ type: Boolean, reflect: true }) open = false\n @property({ type: Boolean, reflect: true }) disabled = false\n\n @property({ type: String, reflect: true })\n get placement(): Placement {\n return this._placement\n }\n set placement(v: string) {\n const old = this._placement\n this._placement = normalizeLiteral(v, ALLOWED_PLACEMENTS, 'bottom')\n this.requestUpdate('placement', old)\n }\n private _placement: Placement = 'bottom'\n\n @property({ type: Number })\n get offset(): number {\n return this._offset\n }\n set offset(v: number) {\n const old = this._offset\n this._offset = normalizeNumber(v, 0, 100, 8)\n this.requestUpdate('offset', old)\n }\n private _offset = 8\n\n @property({ type: String, reflect: true })\n get trigger(): 'click' | 'hover' | 'manual' {\n return this._trigger\n }\n set trigger(v: string) {\n const old = this._trigger\n this._trigger = normalizeLiteral(v, ALLOWED_TRIGGERS, 'click')\n this.requestUpdate('trigger', old)\n }\n private _trigger: 'click' | 'hover' | 'manual' = 'click'\n\n @property({ type: Boolean, reflect: true }) portal = false\n @property({ attribute: false }) overlayContainer?: OverlayContainer\n\n private _showTimer?: ReturnType<typeof setTimeout>\n private _hideTimer?: ReturnType<typeof setTimeout>\n private readonly _userOpenChange = new UserChangeController()\n private _shouldOpenInstantly = true\n\n private _panelId = `wui-popover-panel-${++popoverIdCounter}`\n private readonly _panel = defineAnchoredPanel().make({\n getAnchor: () => this.shadowRoot?.querySelector<HTMLElement>('.popover-trigger') ?? null,\n getLocalPanel: () => this.shadowRoot?.querySelector<HTMLElement>('.popover-panel') ?? null,\n getPositioning: () => ({\n placement: this.placement,\n offset: this.offset,\n strategy: this.portal ? 'fixed' : 'absolute'\n }),\n isPortal: () => this.portal,\n createPortal: () => this._createPortal()\n })\n\n // 当前是否打开\n get isOpen(): boolean {\n return this.open\n }\n\n override connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._onClickOutside)\n document.addEventListener('keydown', this._onKeydown)\n this.addEventListener('focusout', this._onFocusOut)\n this._syncTriggerListeners()\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._onClickOutside)\n document.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('focusout', this._onFocusOut)\n this.removeEventListener('pointerenter', this._onPointerEnter)\n this.removeEventListener('pointerleave', this._onPointerLeave)\n clearTimeout(this._showTimer)\n clearTimeout(this._hideTimer)\n this._panel.dispose()\n }\n\n override firstUpdated() {\n if (this.open) {\n requestAnimationFrame(() => this._openOverlay(this._shouldOpenInstantly))\n this._shouldOpenInstantly = true\n }\n }\n\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has('portal') || changed.has('overlayContainer'))\n requestAnimationFrame(() => this._reconfigureOverlay())\n else if (changed.has('placement') || changed.has('offset'))\n requestAnimationFrame(() => this._panel.updatePosition())\n\n if (changed.has('open')) {\n if (this.open) {\n const isInstant = this._shouldOpenInstantly\n this._shouldOpenInstantly = true\n requestAnimationFrame(() => this._openOverlay(isInstant))\n if (this._userOpenChange.consume()) this._dispatchChange(true)\n this._focusPanel()\n } else {\n this._returnFocus()\n void this._closeOverlay()\n if (this._userOpenChange.consume()) this._dispatchChange(false)\n }\n }\n\n if (changed.has('trigger')) {\n this.removeEventListener('pointerenter', this._onPointerEnter)\n this.removeEventListener('pointerleave', this._onPointerLeave)\n clearTimeout(this._showTimer)\n clearTimeout(this._hideTimer)\n this._syncTriggerListeners()\n }\n }\n\n // 打开 popover\n show() {\n if (this.disabled || this.open) return\n this.open = true\n }\n\n // 关闭 popover\n close() {\n if (!this.open) return\n this.open = false\n }\n\n // 切换 popover\n toggle() {\n if (this.open) this.close()\n else this.show()\n }\n\n private _isInsideShadowRoot(e: MouseEvent): boolean {\n for (const node of e.composedPath()) {\n if (node instanceof Node && node.getRootNode() === this.shadowRoot) return true\n }\n return false\n }\n\n private _syncTriggerListeners() {\n if (this.trigger === 'hover') {\n this.addEventListener('pointerenter', this._onPointerEnter)\n this.addEventListener('pointerleave', this._onPointerLeave)\n }\n }\n\n private _openOverlay(isInstant = false) {\n this._panel.open(isInstant)\n }\n\n private _createPortal(): OverlayPortal {\n const portal = createOverlayPortal({\n container: this.overlayContainer,\n target: this,\n style: `${glass}\\n${overlayMotion}\\n${style}`,\n className: 'popover-panel portal wui-glass wui-floating-panel'\n })\n portal.panel.id = this._panelId\n portal.panel.setAttribute('role', 'dialog')\n portal.panel.tabIndex = -1\n portal.panel.addEventListener('pointerenter', this._onPanelPointerEnter)\n portal.panel.addEventListener('pointerleave', this._onPanelPointerLeave)\n portal.moveContent(\n Array.from(this.childNodes).filter(node => !(node instanceof HTMLElement && node.slot === 'trigger'))\n )\n return portal\n }\n\n private async _closeOverlay() {\n await this._panel.close(() => this.open)\n }\n\n private _reconfigureOverlay() {\n this._panel.reconfigure(this.open)\n }\n\n private _dispatchChange(open: boolean) {\n this.dispatchEvent(\n new CustomEvent('open-change', {\n detail: { open },\n bubbles: true,\n composed: true\n })\n )\n }\n\n private _focusPanel() {\n requestAnimationFrame(() => {\n const panel = this._panel.getPanel()\n const autofocus = panel?.querySelector<HTMLElement>('[autofocus]')\n if (autofocus && !autofocus.matches(':disabled, [disabled]')) autofocus.focus()\n })\n }\n\n private _returnFocus() {\n const panel = this._panel.getPanel()\n if (!panel?.matches(':focus-within')) return\n const trigger = this._queryTrigger()\n trigger?.focus()\n }\n\n private _queryTrigger(): HTMLElement | null {\n const slot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"trigger\"]')\n const el = slot?.assignedElements()[0]\n return el instanceof HTMLElement ? el : null\n }\n\n private _onTriggerClick = (event: MouseEvent) => {\n if (this.disabled) return\n clearTimeout(this._showTimer)\n clearTimeout(this._hideTimer)\n if (this.trigger === 'hover') return\n if (!this.open) this._shouldOpenInstantly = event.detail === 0\n this._userOpenChange.mark()\n this.toggle()\n }\n\n private _onClickOutside = (e: MouseEvent) => {\n if (!this.open) return\n if (this.trigger === 'manual' || this.trigger === 'hover') return\n if (e.target instanceof Node && this.portal && this._panel.getPanel()?.contains(e.target)) return\n if (this._isInsideShadowRoot(e)) return\n this._userOpenChange.mark()\n this.open = false\n }\n\n private _onFocusOut = () => {\n if (this.trigger === 'manual' || this.trigger === 'hover') return\n\n requestAnimationFrame(() => {\n if (this.open && !this.matches(':focus-within') && !this._panel.getPanel()?.matches(':focus-within')) {\n this._userOpenChange.mark()\n this.open = false\n }\n })\n }\n\n private _onKeydown = (e: KeyboardEvent) => {\n if (!this.open) return\n if (this.trigger === 'manual') return\n if (e.key === 'Escape') {\n this._userOpenChange.mark()\n this.open = false\n e.preventDefault()\n }\n }\n\n private _onPointerEnter = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.disabled || this.trigger !== 'hover') return\n clearTimeout(this._hideTimer)\n this._showTimer = setTimeout(() => {\n this._shouldOpenInstantly = false\n if (this.open) return\n this._userOpenChange.mark()\n this.show()\n }, 100)\n }\n\n private _onPointerLeave = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.disabled || this.trigger !== 'hover') return\n clearTimeout(this._showTimer)\n this._hideTimer = setTimeout(() => {\n if (!this.open) return\n this._userOpenChange.mark()\n this.close()\n }, 100)\n }\n\n private _onPanelPointerEnter = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.trigger !== 'hover') return\n clearTimeout(this._hideTimer)\n }\n\n private _onPanelPointerLeave = (e: PointerEvent) => {\n if (e.pointerType === 'touch') return\n if (this.trigger !== 'hover') return\n this._hideTimer = setTimeout(() => {\n if (!this.open) return\n this._userOpenChange.mark()\n this.close()\n }, 100)\n }\n\n override render() {\n return html`\n <div class=\"popover-anchor\">\n <div\n class=\"popover-trigger\"\n aria-expanded=${String(this.open)}\n aria-controls=${this._panelId}\n @click=${this._onTriggerClick}\n >\n <slot name=\"trigger\"></slot>\n </div>\n <div\n id=${this._panelId}\n class=\"popover-panel wui-glass wui-floating-panel\"\n hidden\n role=\"dialog\"\n tabindex=\"-1\"\n @pointerenter=${this._onPanelPointerEnter}\n @pointerleave=${this._onPanelPointerLeave}\n >\n <slot></slot>\n </div>\n </div>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-popover': WebUiPopover\n }\n}\n"],"mappings":";;;;;;;;;;;AAcA,IAAM,IAAqB;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GAEM,IAAmB;CAAC;CAAS;CAAS;AAAQ,GAEhD,IAAmB,GAGV,IAAN,cAA2B,EAAW;;EA2RX,aAxRmB,KAAA,OAAA,IACI,KAAA,WAAA,IAWvB,KAAA,aAAA,UAWd,KAAA,UAAA,GAW+B,KAAA,WAAA,SAEI,KAAA,SAAA,IAKlB,KAAA,kBAAA,IAAI,EAAqB,GAC7B,KAAA,uBAAA,IAEZ,KAAA,WAAA,qBAAqB,EAAE,KAChB,KAAA,SAAA,EAAoB,CAAC,CAAC,KAAK;GACnD,iBAAiB,KAAK,YAAY,cAA2B,kBAAkB,KAAK;GACpF,qBAAqB,KAAK,YAAY,cAA2B,gBAAgB,KAAK;GACtF,uBAAuB;IACrB,WAAW,KAAK;IAChB,QAAQ,KAAK;IACb,UAAU,KAAK,SAAS,UAAU;GACpC;GACA,gBAAgB,KAAK;GACrB,oBAAoB,KAAK,cAAc;EACzC,CAAC,GA4J0B,KAAA,mBAAA,MAAsB;GAC3C,KAAK,aACT,aAAa,KAAK,UAAU,GAC5B,aAAa,KAAK,UAAU,GACxB,KAAK,YAAY,YAChB,KAAK,SAAM,KAAK,uBAAuB,EAAM,WAAW,IAC7D,KAAK,gBAAgB,KAAK,GAC1B,KAAK,OAAO;EACd,GAE2B,KAAA,mBAAA,MAAkB;GACtC,KAAK,QACN,KAAK,YAAY,YAAY,KAAK,YAAY,YAC9C,EAAE,kBAAkB,QAAQ,KAAK,UAAU,KAAK,OAAO,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,KACpF,KAAK,oBAAoB,CAAC,MAC9B,KAAK,gBAAgB,KAAK,GAC1B,KAAK,OAAO;EACd,GAE4B,KAAA,oBAAA;GACtB,KAAK,YAAY,YAAY,KAAK,YAAY,WAElD,4BAA4B;IAC1B,AAAI,KAAK,QAAQ,CAAC,KAAK,QAAQ,eAAe,KAAK,CAAC,KAAK,OAAO,SAAS,CAAC,EAAE,QAAQ,eAAe,MACjG,KAAK,gBAAgB,KAAK,GAC1B,KAAK,OAAO;GAEhB,CAAC;EACH,GAEsB,KAAA,cAAA,MAAqB;GACpC,KAAK,QACN,KAAK,YAAY,YACjB,EAAE,QAAQ,aACZ,KAAK,gBAAgB,KAAK,GAC1B,KAAK,OAAO,IACZ,EAAE,eAAe;EAErB,GAE2B,KAAA,mBAAA,MAAoB;GACzC,EAAE,gBAAgB,YAClB,KAAK,YAAY,KAAK,YAAY,YACtC,aAAa,KAAK,UAAU,GAC5B,KAAK,aAAa,iBAAiB;IACjC,KAAK,uBAAuB,IACxB,MAAK,SACT,KAAK,gBAAgB,KAAK,GAC1B,KAAK,KAAK;GACZ,GAAG,GAAG;EACR,GAE2B,KAAA,mBAAA,MAAoB;GACzC,EAAE,gBAAgB,YAClB,KAAK,YAAY,KAAK,YAAY,YACtC,aAAa,KAAK,UAAU,GAC5B,KAAK,aAAa,iBAAiB;IAC5B,KAAK,SACV,KAAK,gBAAgB,KAAK,GAC1B,KAAK,MAAM;GACb,GAAG,GAAG;EACR,GAEgC,KAAA,wBAAA,MAAoB;GAC9C,EAAE,gBAAgB,WAClB,KAAK,YAAY,WACrB,aAAa,KAAK,UAAU;EAC9B,GAEgC,KAAA,wBAAA,MAAoB;GAC9C,EAAE,gBAAgB,WAClB,KAAK,YAAY,YACrB,KAAK,aAAa,iBAAiB;IAC5B,KAAK,SACV,KAAK,gBAAgB,KAAK,GAC1B,KAAK,MAAM;GACb,GAAG,GAAG;EACR;;;EAlSyB,KAAA,SAAA;GAAC,EAAU,CAAK;GAAG,EAAU,CAAa;GAAG,EAAU,CAAK;EAAC;;CAKtF,IACI,YAAuB;EACzB,OAAO,KAAK;CACd;CACA,IAAI,UAAU,GAAW;EACvB,IAAM,IAAM,KAAK;EAEjB,AADA,KAAK,aAAa,EAAiB,GAAG,GAAoB,QAAQ,GAClE,KAAK,cAAc,aAAa,CAAG;CACrC;CAGA,IACI,SAAiB;EACnB,OAAO,KAAK;CACd;CACA,IAAI,OAAO,GAAW;EACpB,IAAM,IAAM,KAAK;EAEjB,AADA,KAAK,UAAU,EAAgB,GAAG,GAAG,KAAK,CAAC,GAC3C,KAAK,cAAc,UAAU,CAAG;CAClC;CAGA,IACI,UAAwC;EAC1C,OAAO,KAAK;CACd;CACA,IAAI,QAAQ,GAAW;EACrB,IAAM,IAAM,KAAK;EAEjB,AADA,KAAK,WAAW,EAAiB,GAAG,GAAkB,OAAO,GAC7D,KAAK,cAAc,WAAW,CAAG;CACnC;CAyBA,IAAI,SAAkB;EACpB,OAAO,KAAK;CACd;CAEA,oBAA6B;EAK3B,AAJA,MAAM,kBAAkB,GACxB,SAAS,iBAAiB,SAAS,KAAK,eAAe,GACvD,SAAS,iBAAiB,WAAW,KAAK,UAAU,GACpD,KAAK,iBAAiB,YAAY,KAAK,WAAW,GAClD,KAAK,sBAAsB;CAC7B;CAEA,uBAAgC;EAS9B,AARA,MAAM,qBAAqB,GAC3B,SAAS,oBAAoB,SAAS,KAAK,eAAe,GAC1D,SAAS,oBAAoB,WAAW,KAAK,UAAU,GACvD,KAAK,oBAAoB,YAAY,KAAK,WAAW,GACrD,KAAK,oBAAoB,gBAAgB,KAAK,eAAe,GAC7D,KAAK,oBAAoB,gBAAgB,KAAK,eAAe,GAC7D,aAAa,KAAK,UAAU,GAC5B,aAAa,KAAK,UAAU,GAC5B,KAAK,OAAO,QAAQ;CACtB;CAEA,eAAwB;EACtB,AAAI,KAAK,SACP,4BAA4B,KAAK,aAAa,KAAK,oBAAoB,CAAC,GACxE,KAAK,uBAAuB;CAEhC;CAEA,QAA2B,GAA+B;EAMxD,IALI,EAAQ,IAAI,QAAQ,KAAK,EAAQ,IAAI,kBAAkB,IACzD,4BAA4B,KAAK,oBAAoB,CAAC,KAC/C,EAAQ,IAAI,WAAW,KAAK,EAAQ,IAAI,QAAQ,MACvD,4BAA4B,KAAK,OAAO,eAAe,CAAC,GAEtD,EAAQ,IAAI,MAAM,GACpB,IAAI,KAAK,MAAM;GACb,IAAM,IAAY,KAAK;GAIvB,AAHA,KAAK,uBAAuB,IAC5B,4BAA4B,KAAK,aAAa,CAAS,CAAC,GACpD,KAAK,gBAAgB,QAAQ,KAAG,KAAK,gBAAgB,EAAI,GAC7D,KAAK,YAAY;EACnB,OAGE,AAFA,KAAK,aAAa,GAClB,KAAU,cAAc,GACpB,KAAK,gBAAgB,QAAQ,KAAG,KAAK,gBAAgB,EAAK;EAIlE,AAAI,EAAQ,IAAI,SAAS,MACvB,KAAK,oBAAoB,gBAAgB,KAAK,eAAe,GAC7D,KAAK,oBAAoB,gBAAgB,KAAK,eAAe,GAC7D,aAAa,KAAK,UAAU,GAC5B,aAAa,KAAK,UAAU,GAC5B,KAAK,sBAAsB;CAE/B;CAGA,OAAO;EACD,KAAK,YAAY,KAAK,SAC1B,KAAK,OAAO;CACd;CAGA,QAAQ;EACD,AACL,KAAK,SAAO;CACd;CAGA,SAAS;EACP,AAAI,KAAK,OAAM,KAAK,MAAM,IACrB,KAAK,KAAK;CACjB;CAEA,oBAA4B,GAAwB;EAClD,KAAK,IAAM,KAAQ,EAAE,aAAa,GAChC,IAAI,aAAgB,QAAQ,EAAK,YAAY,MAAM,KAAK,YAAY,OAAO;EAE7E,OAAO;CACT;CAEA,wBAAgC;EAC9B,AAAI,KAAK,YAAY,YACnB,KAAK,iBAAiB,gBAAgB,KAAK,eAAe,GAC1D,KAAK,iBAAiB,gBAAgB,KAAK,eAAe;CAE9D;CAEA,aAAqB,IAAY,IAAO;EACtC,KAAK,OAAO,KAAK,CAAS;CAC5B;CAEA,gBAAuC;EACrC,IAAM,IAAS,EAAoB;GACjC,WAAW,KAAK;GAChB,QAAQ;GACR,OAAO,GAAG,EAAM,IAAI,EAAc,IAAI;GACtC,WAAW;EACb,CAAC;EASD,OARA,EAAO,MAAM,KAAK,KAAK,UACvB,EAAO,MAAM,aAAa,QAAQ,QAAQ,GAC1C,EAAO,MAAM,WAAW,IACxB,EAAO,MAAM,iBAAiB,gBAAgB,KAAK,oBAAoB,GACvE,EAAO,MAAM,iBAAiB,gBAAgB,KAAK,oBAAoB,GACvE,EAAO,YACL,MAAM,KAAK,KAAK,UAAU,CAAC,CAAC,QAAO,MAAQ,EAAE,aAAgB,eAAe,EAAK,SAAS,UAAU,CACtG,GACO;CACT;CAEA,MAAc,gBAAgB;EAC5B,MAAM,KAAK,OAAO,YAAY,KAAK,IAAI;CACzC;CAEA,sBAA8B;EAC5B,KAAK,OAAO,YAAY,KAAK,IAAI;CACnC;CAEA,gBAAwB,GAAe;EACrC,KAAK,cACH,IAAI,YAAY,eAAe;GAC7B,QAAQ,EAAE,QAAK;GACf,SAAS;GACT,UAAU;EACZ,CAAC,CACH;CACF;CAEA,cAAsB;EACpB,4BAA4B;GAE1B,IAAM,IADQ,KAAK,OAAO,SACR,CAAA,EAAO,cAA2B,aAAa;GACjE,AAAI,KAAa,CAAC,EAAU,QAAQ,uBAAuB,KAAG,EAAU,MAAM;EAChF,CAAC;CACH;CAEA,eAAuB;EACP,KAAK,OAAO,SACrB,CAAA,EAAO,QAAQ,eAAe,KAEnC,KADqB,cACrB,CAAA,EAAS,MAAM;CACjB;CAEA,gBAA4C;EAE1C,IAAM,KADO,KAAK,YAAY,cAA+B,wBAAsB,EAAA,EAClE,iBAAiB,CAAC,CAAC;EACpC,OAAO,aAAc,cAAc,IAAK;CAC1C;CAiFA,SAAkB;EAChB,OAAO,CAAI;;;;0BAIW,OAAO,KAAK,IAAI,EAAE;0BAClB,KAAK,SAAS;mBACrB,KAAK,gBAAgB;;;;;eAKzB,KAAK,SAAS;;;;;0BAKH,KAAK,qBAAqB;0BAC1B,KAAK,qBAAqB;;;;;;CAMlD;AAKF;AA/TG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,QAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GAEzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,aAAA,IAAA,GAWxC,EAAA,CAAA,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,UAAA,IAAA,GAWzB,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,IAAA,GAWxC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,UAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS,EAAE,WAAW,GAAM,CAAC,CAAA,GAAA,EAAA,WAAA,oBAAA,KAAA,CAAA,GAzC/B,IAAA,EAAA,CAAA,EAAc,gBAAgB,CAAA,GAAA,CAAA"}
@@ -2,11 +2,9 @@ import { LitElement } from 'lit';
2
2
  export declare class WebUiRadio extends LitElement {
3
3
  static styles: import('lit').CSSResult;
4
4
  static formAssociated: boolean;
5
- /** 内部表单关联实例(connectedCallback 中初始化) */
6
5
  private _internals?;
7
6
  private _formDisabled;
8
7
  private _groupDisabled;
9
- /** 内部 checked 状态,通过 getter/setter 暴露为公共 API */
10
8
  private _checked;
11
9
  get checked(): boolean;
12
10
  set checked(v: boolean);
@@ -23,7 +21,6 @@ export declare class WebUiRadio extends LitElement {
23
21
  updated(): void;
24
22
  private _syncFormValue;
25
23
  private _syncValidity;
26
- /** 用户点击选中(已选中时不重复触发) */
27
24
  private handleClick;
28
25
  private handleKeyDown;
29
26
  render(): import('lit').TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/radio/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-radio')\nexport class WebUiRadio extends LitElement {\n static override styles = unsafeCSS(style)\n static formAssociated = true\n\n /** 内部表单关联实例(connectedCallback 中初始化) */\n private _internals?: ElementInternals\n @state() private _formDisabled = false\n @state() private _groupDisabled = false\n\n /** 内部 checked 状态,通过 getter/setter 暴露为公共 API */\n @state() private _checked = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._syncFormValue()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled || this._groupDisabled\n }\n\n private get _isManagedByGroup(): boolean {\n return this.closest('web-ui-radio-group') !== null\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n override connectedCallback() {\n super.connectedCallback()\n if (this._internals) return\n this._internals = this.attachInternals()\n if (this.hasAttribute('checked')) {\n this._checked = true\n }\n this._syncFormValue()\n }\n\n formResetCallback() {\n this.checked = this.hasAttribute('checked')\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override updated() {\n this._syncFormValue()\n this._syncValidity()\n }\n\n private _syncFormValue() {\n this._internals?.setFormValue?.(!this._isManagedByGroup && this._checked ? this.value || 'on' : null)\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n this._internals.setValidity({})\n return\n }\n this._internals.setValidity({ valueMissing: true }, '请选择一项')\n }\n\n /** 用户点击选中(已选中时不重复触发) */\n private handleClick() {\n if (this._isDisabled || this._checked) return\n this._checked = true\n this._syncFormValue()\n this.requestUpdate('checked', false)\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-radio': true,\n 'is-checked': this._checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"radio\"\n aria-checked=${String(this._checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"wui-radio-circle\">\n <span class=\"wui-radio-dot\"></span>\n </span>\n <span class=\"wui-radio-label\"><slot></slot></span>\n </label>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-radio': WebUiRadio\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/radio/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-radio')\nexport class WebUiRadio extends LitElement {\n static override styles = unsafeCSS(style)\n static formAssociated = true\n\n // 内部表单关联实例(connectedCallback 中初始化)\n private _internals?: ElementInternals\n @state() private _formDisabled = false\n @state() private _groupDisabled = false\n\n // 内部 checked 状态,通过 getter/setter 暴露为公共 API\n @state() private _checked = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._syncFormValue()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled || this._groupDisabled\n }\n\n private get _isManagedByGroup(): boolean {\n return this.closest('web-ui-radio-group') !== null\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n override connectedCallback() {\n super.connectedCallback()\n if (this._internals) return\n this._internals = this.attachInternals()\n if (this.hasAttribute('checked')) {\n this._checked = true\n }\n this._syncFormValue()\n }\n\n formResetCallback() {\n this.checked = this.hasAttribute('checked')\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override updated() {\n this._syncFormValue()\n this._syncValidity()\n }\n\n private _syncFormValue() {\n this._internals?.setFormValue?.(!this._isManagedByGroup && this._checked ? this.value || 'on' : null)\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n this._internals.setValidity({})\n return\n }\n this._internals.setValidity({ valueMissing: true }, '请选择一项')\n }\n\n // 用户点击选中(已选中时不重复触发)\n private handleClick() {\n if (this._isDisabled || this._checked) return\n this._checked = true\n this._syncFormValue()\n this.requestUpdate('checked', false)\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-radio': true,\n 'is-checked': this._checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"radio\"\n aria-checked=${String(this._checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"wui-radio-circle\">\n <span class=\"wui-radio-dot\"></span>\n </span>\n <span class=\"wui-radio-label\"><slot></slot></span>\n </label>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-radio': WebUiRadio\n }\n}\n"],"mappings":"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"}
@@ -76,10 +76,14 @@ var u = class extends r {
76
76
  }
77
77
  render() {
78
78
  return i`
79
- <div class=${l({
79
+ <div
80
+ class=${l({
80
81
  "wui-segmented": !0,
81
82
  "is-disabled": this._isDisabled
82
- })}>
83
+ })}
84
+ role="listbox"
85
+ aria-orientation="horizontal"
86
+ >
83
87
  <span class="wui-segmented-indicator wui-glass"></span>
84
88
  <slot></slot>
85
89
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented/index.ts"],"sourcesContent":["import { html, LitElement, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport glass from '@/assets/glass.css?inline'\n\nimport type { WebUiSegmentedTrigger } from '../segmented-trigger'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented')\nexport class WebUiSegmented extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n static formAssociated = true\n\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private _internals?: ElementInternals\n @state() private _value = ''\n @state() private _formDisabled = false\n private _initialValue = ''\n\n get value(): string {\n return this._value\n }\n\n set value(v: string) {\n const old = this._value\n this._value = v\n this._internals?.setFormValue?.(v)\n this.requestUpdate('value', old)\n }\n\n private readonly childObserver = new MutationObserver(() => {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n })\n\n private _syncPropsToChildren() {\n this.querySelectorAll<WebUiSegmentedTrigger>('web-ui-segmented-trigger').forEach(trigger => {\n trigger.checked = trigger.value === this._value\n trigger.setGroupDisabled(this._isDisabled)\n })\n }\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled\n }\n\n private _updateIndicator() {\n const triggers = this.querySelectorAll<WebUiSegmentedTrigger>('web-ui-segmented-trigger')\n let left = 0\n let width = 0\n\n triggers.forEach(trigger => {\n if (trigger.value === this._value) {\n const triggerRect = trigger.getBoundingClientRect()\n const groupRect = this.getBoundingClientRect()\n left = triggerRect.left - groupRect.left\n width = triggerRect.width\n }\n })\n\n this.style.setProperty('--indicator-left', `${left}px`)\n this.style.setProperty('--indicator-width', `${width}px`)\n }\n\n override updated(props: PropertyValues) {\n if (props.has('value') || props.has('disabled') || props.has('_formDisabled')) {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n }\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._internals = this.attachInternals()\n\n // 仅当属性在连接前未被 property setter 设值时,才从 attribute 读取初始值\n const attrValue = this.getAttribute('value')\n if (attrValue !== null && this._value === '') {\n this._value = attrValue\n }\n this._initialValue = attrValue ?? ''\n this._internals?.setFormValue?.(this._value)\n\n this.childObserver.observe(this, { childList: true })\n this.addEventListener('change', this._handleChildChange)\n }\n\n override firstUpdated() {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this.childObserver.disconnect()\n this.removeEventListener('change', this._handleChildChange)\n }\n\n private _handleChildChange(e: Event) {\n if (this._isDisabled) return\n const target = e.target as HTMLElement\n if (!target.matches?.('web-ui-segmented-trigger')) return\n const trigger = target as WebUiSegmentedTrigger\n if (trigger.value === this._value) return\n\n this.value = trigger.value\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n formResetCallback() {\n this.value = this._initialValue\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override render() {\n return html`\n <div class=${classMap({ 'wui-segmented': true, 'is-disabled': this._isDisabled })}>\n <span class=\"wui-segmented-indicator wui-glass\"></span>\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented': WebUiSegmented\n }\n}\n"],"mappings":";;;;;;;AAWO,IAAM,IAAN,cAA6B,EAAW;;EAwBZ,aApBiB,KAAA,OAAA,IACK,KAAA,WAAA,IACA,KAAA,WAAA,IAG7B,KAAA,SAAA,IACO,KAAA,gBAAA,IACT,KAAA,gBAAA,IAaS,KAAA,gBAAA,IAAI,uBAAuB;GAE1D,AADA,KAAK,qBAAqB,GAC1B,4BAA4B,KAAK,iBAAiB,CAAC;EACrD,CAAC;;;EA1BwB,KAAA,SAAA,CAAC,EAAU,CAAK,GAAG,EAAU,CAAK,CAAC;;;EACpC,KAAA,iBAAA;;CAWxB,IAAI,QAAgB;EAClB,OAAO,KAAK;CACd;CAEA,IAAI,MAAM,GAAW;EACnB,IAAM,IAAM,KAAK;EAGjB,AAFA,KAAK,SAAS,GACd,KAAK,YAAY,eAAe,CAAC,GACjC,KAAK,cAAc,SAAS,CAAG;CACjC;CAOA,uBAA+B;EAC7B,KAAK,iBAAwC,0BAA0B,CAAC,CAAC,SAAQ,MAAW;GAE1F,AADA,EAAQ,UAAU,EAAQ,UAAU,KAAK,QACzC,EAAQ,iBAAiB,KAAK,WAAW;EAC3C,CAAC;CACH;CAEA,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK;CAC/B;CAEA,mBAA2B;EACzB,IAAM,IAAW,KAAK,iBAAwC,0BAA0B,GACpF,IAAO,GACP,IAAQ;EAYZ,AAVA,EAAS,SAAQ,MAAW;GAC1B,IAAI,EAAQ,UAAU,KAAK,QAAQ;IACjC,IAAM,IAAc,EAAQ,sBAAsB,GAC5C,IAAY,KAAK,sBAAsB;IAE7C,AADA,IAAO,EAAY,OAAO,EAAU,MACpC,IAAQ,EAAY;GACtB;EACF,CAAC,GAED,KAAK,MAAM,YAAY,oBAAoB,GAAG,EAAK,GAAG,GACtD,KAAK,MAAM,YAAY,qBAAqB,GAAG,EAAM,GAAG;CAC1D;CAEA,QAAiB,GAAuB;EACtC,CAAI,EAAM,IAAI,OAAO,KAAK,EAAM,IAAI,UAAU,KAAK,EAAM,IAAI,eAAe,OAC1E,KAAK,qBAAqB,GAC1B,4BAA4B,KAAK,iBAAiB,CAAC;CAEvD;CAEA,oBAA6B;EAE3B,AADA,MAAM,kBAAkB,GACxB,KAAK,aAAa,KAAK,gBAAgB;EAGvC,IAAM,IAAY,KAAK,aAAa,OAAO;EAQ3C,AAPI,MAAc,QAAQ,KAAK,WAAW,OACxC,KAAK,SAAS,IAEhB,KAAK,gBAAgB,KAAa,IAClC,KAAK,YAAY,eAAe,KAAK,MAAM,GAE3C,KAAK,cAAc,QAAQ,MAAM,EAAE,WAAW,GAAK,CAAC,GACpD,KAAK,iBAAiB,UAAU,KAAK,kBAAkB;CACzD;CAEA,eAAwB;EAEtB,AADA,KAAK,qBAAqB,GAC1B,4BAA4B,KAAK,iBAAiB,CAAC;CACrD;CAEA,uBAAgC;EAG9B,AAFA,MAAM,qBAAqB,GAC3B,KAAK,cAAc,WAAW,GAC9B,KAAK,oBAAoB,UAAU,KAAK,kBAAkB;CAC5D;CAEA,mBAA2B,GAAU;EACnC,IAAI,KAAK,aAAa;EACtB,IAAM,IAAS,EAAE;EACjB,IAAI,CAAC,EAAO,UAAU,0BAA0B,GAAG;EACnD,IAAM,IAAU;EACZ,EAAQ,UAAU,KAAK,WAE3B,KAAK,QAAQ,EAAQ,OACrB,KAAK,cAAc,IAAI,MAAM,SAAS;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC,GACxE,KAAK,cAAc,IAAI,MAAM,UAAU;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC3E;CAEA,oBAAoB;EAClB,KAAK,QAAQ,KAAK;CACpB;CAEA,qBAAqB,GAAmB;EACtC,KAAK,gBAAgB;CACvB;CAEA,SAAkB;EAChB,OAAO,CAAI;mBACI,EAAS;GAAE,iBAAiB;GAAM,eAAe,KAAK;EAAY,CAAC,EAAE;;;;;CAKtF;AAMF;AAzHG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,QAAA,KAAA,CAAA,GACxC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GAGzC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,UAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,iBAAA,KAAA,CAAA,GAXR,IAAA,EAAA,CAAA,EAAc,kBAAkB,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented/index.ts"],"sourcesContent":["import { html, LitElement, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport glass from '@/assets/glass.css?inline'\n\nimport type { WebUiSegmentedTrigger } from '../segmented-trigger'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented')\nexport class WebUiSegmented extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n static formAssociated = true\n\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private _internals?: ElementInternals\n @state() private _value = ''\n @state() private _formDisabled = false\n private _initialValue = ''\n\n get value(): string {\n return this._value\n }\n\n set value(v: string) {\n const old = this._value\n this._value = v\n this._internals?.setFormValue?.(v)\n this.requestUpdate('value', old)\n }\n\n private readonly childObserver = new MutationObserver(() => {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n })\n\n private _syncPropsToChildren() {\n this.querySelectorAll<WebUiSegmentedTrigger>('web-ui-segmented-trigger').forEach(trigger => {\n trigger.checked = trigger.value === this._value\n trigger.setGroupDisabled(this._isDisabled)\n })\n }\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled\n }\n\n private _updateIndicator() {\n const triggers = this.querySelectorAll<WebUiSegmentedTrigger>('web-ui-segmented-trigger')\n let left = 0\n let width = 0\n\n triggers.forEach(trigger => {\n if (trigger.value === this._value) {\n const triggerRect = trigger.getBoundingClientRect()\n const groupRect = this.getBoundingClientRect()\n left = triggerRect.left - groupRect.left\n width = triggerRect.width\n }\n })\n\n this.style.setProperty('--indicator-left', `${left}px`)\n this.style.setProperty('--indicator-width', `${width}px`)\n }\n\n override updated(props: PropertyValues) {\n if (props.has('value') || props.has('disabled') || props.has('_formDisabled')) {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n }\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._internals = this.attachInternals()\n\n // 仅当属性在连接前未被 property setter 设值时,才从 attribute 读取初始值\n const attrValue = this.getAttribute('value')\n if (attrValue !== null && this._value === '') {\n this._value = attrValue\n }\n this._initialValue = attrValue ?? ''\n this._internals?.setFormValue?.(this._value)\n\n this.childObserver.observe(this, { childList: true })\n this.addEventListener('change', this._handleChildChange)\n }\n\n override firstUpdated() {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this.childObserver.disconnect()\n this.removeEventListener('change', this._handleChildChange)\n }\n\n private _handleChildChange(e: Event) {\n if (this._isDisabled) return\n const target = e.target as HTMLElement\n if (!target.matches?.('web-ui-segmented-trigger')) return\n const trigger = target as WebUiSegmentedTrigger\n if (trigger.value === this._value) return\n\n this.value = trigger.value\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n formResetCallback() {\n this.value = this._initialValue\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override render() {\n return html`\n <div\n class=${classMap({ 'wui-segmented': true, 'is-disabled': this._isDisabled })}\n role=\"listbox\"\n aria-orientation=\"horizontal\"\n >\n <span class=\"wui-segmented-indicator wui-glass\"></span>\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented': WebUiSegmented\n }\n}\n"],"mappings":";;;;;;;AAWO,IAAM,IAAN,cAA6B,EAAW;;EAwBZ,aApBiB,KAAA,OAAA,IACK,KAAA,WAAA,IACA,KAAA,WAAA,IAG7B,KAAA,SAAA,IACO,KAAA,gBAAA,IACT,KAAA,gBAAA,IAaS,KAAA,gBAAA,IAAI,uBAAuB;GAE1D,AADA,KAAK,qBAAqB,GAC1B,4BAA4B,KAAK,iBAAiB,CAAC;EACrD,CAAC;;;EA1BwB,KAAA,SAAA,CAAC,EAAU,CAAK,GAAG,EAAU,CAAK,CAAC;;;EACpC,KAAA,iBAAA;;CAWxB,IAAI,QAAgB;EAClB,OAAO,KAAK;CACd;CAEA,IAAI,MAAM,GAAW;EACnB,IAAM,IAAM,KAAK;EAGjB,AAFA,KAAK,SAAS,GACd,KAAK,YAAY,eAAe,CAAC,GACjC,KAAK,cAAc,SAAS,CAAG;CACjC;CAOA,uBAA+B;EAC7B,KAAK,iBAAwC,0BAA0B,CAAC,CAAC,SAAQ,MAAW;GAE1F,AADA,EAAQ,UAAU,EAAQ,UAAU,KAAK,QACzC,EAAQ,iBAAiB,KAAK,WAAW;EAC3C,CAAC;CACH;CAEA,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK;CAC/B;CAEA,mBAA2B;EACzB,IAAM,IAAW,KAAK,iBAAwC,0BAA0B,GACpF,IAAO,GACP,IAAQ;EAYZ,AAVA,EAAS,SAAQ,MAAW;GAC1B,IAAI,EAAQ,UAAU,KAAK,QAAQ;IACjC,IAAM,IAAc,EAAQ,sBAAsB,GAC5C,IAAY,KAAK,sBAAsB;IAE7C,AADA,IAAO,EAAY,OAAO,EAAU,MACpC,IAAQ,EAAY;GACtB;EACF,CAAC,GAED,KAAK,MAAM,YAAY,oBAAoB,GAAG,EAAK,GAAG,GACtD,KAAK,MAAM,YAAY,qBAAqB,GAAG,EAAM,GAAG;CAC1D;CAEA,QAAiB,GAAuB;EACtC,CAAI,EAAM,IAAI,OAAO,KAAK,EAAM,IAAI,UAAU,KAAK,EAAM,IAAI,eAAe,OAC1E,KAAK,qBAAqB,GAC1B,4BAA4B,KAAK,iBAAiB,CAAC;CAEvD;CAEA,oBAA6B;EAE3B,AADA,MAAM,kBAAkB,GACxB,KAAK,aAAa,KAAK,gBAAgB;EAGvC,IAAM,IAAY,KAAK,aAAa,OAAO;EAQ3C,AAPI,MAAc,QAAQ,KAAK,WAAW,OACxC,KAAK,SAAS,IAEhB,KAAK,gBAAgB,KAAa,IAClC,KAAK,YAAY,eAAe,KAAK,MAAM,GAE3C,KAAK,cAAc,QAAQ,MAAM,EAAE,WAAW,GAAK,CAAC,GACpD,KAAK,iBAAiB,UAAU,KAAK,kBAAkB;CACzD;CAEA,eAAwB;EAEtB,AADA,KAAK,qBAAqB,GAC1B,4BAA4B,KAAK,iBAAiB,CAAC;CACrD;CAEA,uBAAgC;EAG9B,AAFA,MAAM,qBAAqB,GAC3B,KAAK,cAAc,WAAW,GAC9B,KAAK,oBAAoB,UAAU,KAAK,kBAAkB;CAC5D;CAEA,mBAA2B,GAAU;EACnC,IAAI,KAAK,aAAa;EACtB,IAAM,IAAS,EAAE;EACjB,IAAI,CAAC,EAAO,UAAU,0BAA0B,GAAG;EACnD,IAAM,IAAU;EACZ,EAAQ,UAAU,KAAK,WAE3B,KAAK,QAAQ,EAAQ,OACrB,KAAK,cAAc,IAAI,MAAM,SAAS;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC,GACxE,KAAK,cAAc,IAAI,MAAM,UAAU;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC3E;CAEA,oBAAoB;EAClB,KAAK,QAAQ,KAAK;CACpB;CAEA,qBAAqB,GAAmB;EACtC,KAAK,gBAAgB;CACvB;CAEA,SAAkB;EAChB,OAAO,CAAI;;gBAEC,EAAS;GAAE,iBAAiB;GAAM,eAAe,KAAK;EAAY,CAAC,EAAE;;;;;;;;CAQnF;AAMF;AA7HG,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,QAAA,KAAA,CAAA,GACxC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GAGzC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,UAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,iBAAA,KAAA,CAAA,GAXR,IAAA,EAAA,CAAA,EAAc,kBAAkB,CAAA,GAAA,CAAA"}
@@ -36,7 +36,7 @@ var l = class extends n {
36
36
  })}
37
37
  tabindex=${this._isDisabled ? "-1" : "0"}
38
38
  role="option"
39
- .ariaSelected=${String(this.checked)}
39
+ aria-selected=${String(this.checked)}
40
40
  aria-disabled=${String(this._isDisabled)}
41
41
  @click=${this.handleClick}
42
42
  @keydown=${this.handleKeyDown}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented-trigger/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented-trigger')\nexport class WebUiSegmentedTrigger extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: String }) value = ''\n @property({ type: Boolean, reflect: true }) checked = false\n @property({ type: Boolean, reflect: true }) disabled = false\n @state() private _groupDisabled = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._groupDisabled\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n private handleClick() {\n if (this._isDisabled || this.checked) return\n this.checked = true\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-segmented-trigger': true,\n 'is-checked': this.checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <div\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"option\"\n .ariaSelected=${String(this.checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented-trigger': WebUiSegmentedTrigger\n }\n}\n"],"mappings":";;;;;;AAOO,IAAM,IAAN,cAAoC,EAAW;;EAMlB,aAHE,KAAA,QAAA,IACkB,KAAA,UAAA,IACC,KAAA,WAAA,IACrB,KAAA,iBAAA;;;EALT,KAAA,SAAA,EAAU,CAAK;;CAOxC,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK;CAC/B;CAEA,iBAAiB,GAAmB;EAClC,KAAK,iBAAiB;CACxB;CAEA,cAAsB;EAChB,KAAK,eAAe,KAAK,YAC7B,KAAK,UAAU,IACf,KAAK,cAAc,IAAI,MAAM,UAAU;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC3E;CAEA,cAAsB,GAAkB;EACtC,CAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAe,GACjB,KAAK,YAAY;CAErB;CAEA,SAAkB;EAOhB,OAAO,CAAI;;gBAEC,EAAS;GAPnB,yBAAyB;GACzB,cAAc,KAAK;GACnB,eAAe,KAAK;EAKD,CAAG,EAAE;mBACX,KAAK,cAAc,OAAO,IAAI;;wBAEzB,OAAO,KAAK,OAAO,EAAE;wBACrB,OAAO,KAAK,WAAW,EAAE;iBAChC,KAAK,YAAY;mBACf,KAAK,cAAc;;;;;CAKpC;AAKF;AAnDG,EAAA,CAAA,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,GACzB,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GAPR,IAAA,EAAA,CAAA,EAAc,0BAA0B,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented-trigger/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented-trigger')\nexport class WebUiSegmentedTrigger extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: String }) value = ''\n @property({ type: Boolean, reflect: true }) checked = false\n @property({ type: Boolean, reflect: true }) disabled = false\n @state() private _groupDisabled = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._groupDisabled\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n private handleClick() {\n if (this._isDisabled || this.checked) return\n this.checked = true\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-segmented-trigger': true,\n 'is-checked': this.checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <div\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"option\"\n aria-selected=${String(this.checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented-trigger': WebUiSegmentedTrigger\n }\n}\n"],"mappings":";;;;;;AAOO,IAAM,IAAN,cAAoC,EAAW;;EAMlB,aAHE,KAAA,QAAA,IACkB,KAAA,UAAA,IACC,KAAA,WAAA,IACrB,KAAA,iBAAA;;;EALT,KAAA,SAAA,EAAU,CAAK;;CAOxC,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK;CAC/B;CAEA,iBAAiB,GAAmB;EAClC,KAAK,iBAAiB;CACxB;CAEA,cAAsB;EAChB,KAAK,eAAe,KAAK,YAC7B,KAAK,UAAU,IACf,KAAK,cAAc,IAAI,MAAM,UAAU;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC3E;CAEA,cAAsB,GAAkB;EACtC,CAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAe,GACjB,KAAK,YAAY;CAErB;CAEA,SAAkB;EAOhB,OAAO,CAAI;;gBAEC,EAAS;GAPnB,yBAAyB;GACzB,cAAc,KAAK;GACnB,eAAe,KAAK;EAKD,CAAG,EAAE;mBACX,KAAK,cAAc,OAAO,IAAI;;wBAEzB,OAAO,KAAK,OAAO,EAAE;wBACrB,OAAO,KAAK,WAAW,EAAE;iBAChC,KAAK,YAAY;mBACf,KAAK,cAAc;;;;;CAKpC;AAKF;AAnDG,EAAA,CAAA,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,GACzB,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GAPR,IAAA,EAAA,CAAA,EAAc,0BAA0B,CAAA,GAAA,CAAA"}
@@ -1,5 +1,5 @@
1
1
  //#region src/components/segmented-trigger/style.css?inline
2
- var e = "*,:before,:after{box-sizing:border-box}:host{display:inline-block}:host([disabled]){cursor:not-allowed}.wui-segmented-trigger{cursor:pointer;-webkit-user-select:none;user-select:none;z-index:1;height:34px;font-size:var(--wui-font-size,14px);color:var(--wui-color-text-muted,#6a6a6a);white-space:nowrap;transition:color var(--wui-duration-focus,.2s) ease;border-radius:2147483647px;justify-content:center;align-items:center;padding:0 16px;line-height:1;display:inline-flex;position:relative}.wui-segmented-trigger:focus-visible{outline:3px solid var(--wui-focus-ring,#08f6);outline-offset:2px}.wui-segmented-trigger.is-checked{color:var(--wui-color-text,#1a1a1a)}.wui-segmented-trigger.is-disabled{cursor:not-allowed;opacity:.4}";
2
+ var e = "*,:before,:after{box-sizing:border-box}:host{display:inline-block}:host([disabled]){cursor:not-allowed}.wui-segmented-trigger{--wui-segmented-trigger-bg-hover:color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent);--wui-segmented-trigger-bg-active:color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, transparent);cursor:pointer;-webkit-user-select:none;user-select:none;z-index:1;height:34px;font-size:var(--wui-font-size,14px);color:var(--wui-color-text-muted,#6a6a6a);white-space:nowrap;transition:background-color var(--wui-duration-trigger,.16s) ease, color var(--wui-duration-focus,.2s) ease;background-color:#0000;border-radius:2147483647px;justify-content:center;align-items:center;padding:0 16px;line-height:1;display:inline-flex;position:relative}.wui-segmented-trigger:focus-visible{outline:3px solid var(--wui-focus-ring,#08f6);outline-offset:2px}.wui-segmented-trigger.is-checked{color:var(--wui-color-text,#1a1a1a)}@media (hover:hover) and (pointer:fine){.wui-segmented-trigger:hover:not(.is-disabled){background-color:var(--wui-segmented-trigger-bg-hover)}}.wui-segmented-trigger:active:not(.is-disabled){background-color:var(--wui-segmented-trigger-bg-active)}.wui-segmented-trigger.is-disabled{cursor:not-allowed;opacity:.4}";
3
3
  //#endregion
4
4
  export { e as default };
5
5
 
@@ -1 +1 @@
1
- {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/segmented-trigger/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.wui-segmented-trigger {\n cursor: pointer;\n user-select: none;\n\n position: relative;\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n height: 34px;\n padding: 0 16px;\n border-radius: calc(infinity * 1px);\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text-muted, #6a6a6a);\n white-space: nowrap;\n\n transition: color var(--wui-duration-focus, 200ms) ease;\n\n &:focus-visible {\n outline: 3px solid var(--wui-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n\n &.is-checked {\n color: var(--wui-color-text, #1a1a1a);\n }\n}\n\n.wui-segmented-trigger.is-disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"style.js","names":[],"sources":["../../../src/components/segmented-trigger/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.wui-segmented-trigger {\n --wui-segmented-trigger-bg-hover: color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent);\n --wui-segmented-trigger-bg-active: color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, transparent);\n\n cursor: pointer;\n user-select: none;\n\n position: relative;\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n height: 34px;\n padding: 0 16px;\n border-radius: calc(infinity * 1px);\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text-muted, #6a6a6a);\n white-space: nowrap;\n\n background-color: transparent;\n\n transition:\n background-color var(--wui-duration-trigger, 160ms) ease,\n color var(--wui-duration-focus, 200ms) ease;\n\n &:focus-visible {\n outline: 3px solid var(--wui-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n\n &.is-checked {\n color: var(--wui-color-text, #1a1a1a);\n }\n}\n\n@media (hover: hover) and (pointer: fine) {\n .wui-segmented-trigger:hover:not(.is-disabled) {\n background-color: var(--wui-segmented-trigger-bg-hover);\n }\n}\n\n.wui-segmented-trigger:active:not(.is-disabled) {\n background-color: var(--wui-segmented-trigger-bg-active);\n}\n\n.wui-segmented-trigger.is-disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n"],"mappings":""}
@@ -230,24 +230,26 @@ var h = class extends c {
230
230
  this._panel.reconfigure(this._isOpen);
231
231
  }
232
232
  render() {
233
+ let e = `${this.localName}-listbox`, t = !this.portal && this._isOpen && this._activeIndex >= 0 ? this._options[this._activeIndex]?.id ?? u : u;
233
234
  return l`
234
235
  <div class="wui-select-inner">
235
236
  <div
236
237
  class="wui-glass select-trigger"
237
238
  ?data-custom-trigger=${this._hasTriggerSlot}
238
239
  @click=${this._togglePopup}
239
- tabindex=${this._isDisabled ? -1 : 0}
240
+ tabindex=${this._isDisabled ? "-1" : "0"}
240
241
  role="combobox"
241
242
  aria-expanded=${this._isOpen}
242
243
  aria-haspopup="listbox"
244
+ aria-controls=${this.portal ? u : e}
243
245
  aria-disabled=${String(this._isDisabled)}
244
- aria-activedescendant=${this._isOpen && this._activeIndex >= 0 ? this._options[this._activeIndex]?.id : u}
246
+ aria-activedescendant=${t}
245
247
  >
246
248
  <slot name="trigger" @slotchange=${this._onTriggerSlotChange}></slot>
247
249
  ${this._hasTriggerSlot ? u : l`<span class="label">${this._selectedLabel}</span>`}
248
250
  <web-ui-icon class="arrow" .icon=${n}></web-ui-icon>
249
251
  </div>
250
- <div class="wui-glass select-overlay wui-floating-panel" hidden role="listbox">
252
+ <div class="wui-glass select-overlay wui-floating-panel" hidden role="listbox" id=${e}>
251
253
  <div class="select-scroll">
252
254
  <div class="select-content">
253
255
  <slot @slotchange=${this._onSlotChange}></slot>
@@ -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 { defineAnchoredPanel } from '@/shared/overlay/anchored-panel'\nimport { createOverlayPortal } from '@/shared/overlay/portal'\nimport type { OverlayContainer, OverlayPortal } from '@/shared/overlay/portal'\nimport { createScrollLockLease } 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 // ElementInternals 实例,在 connectedCallback 中初始化\n private _internals?: ElementInternals\n @state() private _formDisabled = false\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 @state() private _value = ''\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._internals?.setFormValue?.(v)\n this.toggleAttribute('data-has-value', !!v)\n this.requestUpdate('value', old)\n }\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled\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 readonly _scrollLock = createScrollLockLease()\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: () => ({ placement: 'bottom-start', offset: 4, strategy: this.portal ? 'fixed' : 'absolute' }),\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._internals = this.attachInternals()\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 this._internals?.setFormValue?.(this._value)\n this.addEventListener('option-register', this._onOptionRegister)\n this.addEventListener('option-unregister', this._onOptionUnregister)\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.removeEventListener('option-register', this._onOptionRegister)\n this.removeEventListener('option-unregister', this._onOptionUnregister)\n this.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('focusout', this._onFocusOut)\n document.removeEventListener('click', this._onClickOutside)\n this._options.forEach(o => {\n o.removeEventListener('click', this._handleOptionClick)\n o.removeEventListener('pointerover', this._handleOptionPointerOver)\n o.removeEventListener('pointerdown', this._handleOptionPointerDown)\n o.removeEventListener('option-update', this._onOptionUpdate)\n })\n this._close()\n this._panel.dispose()\n this._scrollLock.release()\n }\n\n override firstUpdated() {\n requestAnimationFrame(() => {\n if (this.isConnected) this._onSlotChange()\n })\n }\n\n private _queryOptions(): WebUiOption[] {\n const panel = this.portal ? this._panel.getPanel() : null\n const panelOptions = panel ? [...panel.querySelectorAll<WebUiOption>('web-ui-option')] : []\n // 面板内容仅在浮层打开、moveContent 之后存在;关闭时回退 light DOM,\n // 否则 portal select 首次加载时 _options 为空,trigger 显示不出已选值。\n return panelOptions.length > 0 ? panelOptions : [...this.querySelectorAll<WebUiOption>('web-ui-option')]\n }\n\n override willUpdate() {\n this._options = this._queryOptions()\n this._ensureOptionIds()\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.value = this.getAttribute('value') || ''\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || !this.required || this.value) this._internals.setValidity({})\n else this._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 _ensureOptionIds() {\n this._options.forEach((option, index) => {\n if (!option.id) option.id = `${this.localName}-option-${index}`\n })\n }\n\n private _onOptionRegister = (e: Event) => {\n if (!(e.target instanceof HTMLElement)) return\n const target = e.target as WebUiOption\n target.addEventListener('click', this._handleOptionClick)\n target.addEventListener('pointerover', this._handleOptionPointerOver)\n target.addEventListener('pointerdown', this._handleOptionPointerDown)\n target.addEventListener('option-update', this._onOptionUpdate)\n this._options.push(target)\n this._ensureOptionIds()\n this._syncSelected()\n }\n\n private _onOptionUnregister = (e: Event) => {\n if (!(e.target instanceof HTMLElement)) return\n const target = e.target as WebUiOption\n target.removeEventListener('click', this._handleOptionClick)\n target.removeEventListener('pointerover', this._handleOptionPointerOver)\n target.removeEventListener('pointerdown', this._handleOptionPointerDown)\n target.removeEventListener('option-update', this._onOptionUpdate)\n this._options = this._options.filter(o => o !== target)\n }\n\n private _onSlotChange = () => {\n this._options = this._queryOptions()\n this._ensureOptionIds()\n this._syncSelected()\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) 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 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 && !option.disabled) {\n this.value = option.value\n this._notifyValueChange()\n }\n this._close()\n e.preventDefault()\n }\n break\n }\n }\n\n private _navigateActive(delta: number) {\n const enabled = this._options.filter(o => !o.disabled)\n if (!enabled.length) return\n\n const selectedOption = this._options.find(option => option.value === this.value && !option.disabled)\n const currentIdx =\n this._activeIndex >= 0\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(option => option.value === this.value && !option.disabled)\n const firstEnabledIndex = this._options.findIndex(option => !option.disabled)\n this._activeIndex = selectedIndex >= 0 ? selectedIndex : firstEnabledIndex\n this._syncActiveOption()\n }\n\n private _syncActiveOption() {\n this._options.forEach((option, index) => option.toggleAttribute('active', index === this._activeIndex))\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 const panel = !this.portal ? this._panel.getPanel() : null\n if (panel) panel.style.width = `${this._getDesiredWidth()}px`\n this._panel.open(isKeyboardNavigation)\n }\n\n private _getDesiredWidth(): number {\n const trigger = this.shadowRoot?.querySelector<HTMLElement>('.select-trigger')\n const triggerWidth = trigger?.offsetWidth || 0\n\n const options = [...this.querySelectorAll<WebUiOption>('web-ui-option')]\n let maxOptionWidth = 0\n options.forEach(opt => {\n const label = opt.shadowRoot?.querySelector<HTMLElement>('.option-label')\n const w = label?.scrollWidth || opt.scrollWidth || 0\n if (w > maxOptionWidth) maxOptionWidth = w\n })\n\n return Math.max(120, triggerWidth, maxOptionWidth)\n }\n\n private _createPortal(): OverlayPortal {\n const desiredWidth = this._getDesiredWidth()\n\n const portal = createOverlayPortal({\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 })\n portal.panel.style.width = `${desiredWidth}px`\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 scroll.append(content)\n portal.panel.append(scroll)\n portal.moveContent(Array.from(this.children), content)\n return portal\n }\n\n private async _closeOverlay() {\n await this._panel.close(() => this._isOpen)\n }\n\n private _reconfigureOverlay() {\n if (!this.portal) {\n const panel = this._panel.getPanel()\n if (panel) panel.style.width = `${this._getDesiredWidth()}px`\n }\n this._panel.reconfigure(this._isOpen)\n }\n\n override render() {\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-disabled=${String(this._isDisabled)}\n aria-activedescendant=${this._isOpen && this._activeIndex >= 0\n ? this._options[this._activeIndex]?.id\n : nothing}\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\">\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 { defineAnchoredPanel } from '@/shared/overlay/anchored-panel'\nimport { createOverlayPortal } from '@/shared/overlay/portal'\nimport type { OverlayContainer, OverlayPortal } from '@/shared/overlay/portal'\nimport { createScrollLockLease } 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 // ElementInternals 实例,在 connectedCallback 中初始化\n private _internals?: ElementInternals\n @state() private _formDisabled = false\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 @state() private _value = ''\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._internals?.setFormValue?.(v)\n this.toggleAttribute('data-has-value', !!v)\n this.requestUpdate('value', old)\n }\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled\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 readonly _scrollLock = createScrollLockLease()\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: () => ({ placement: 'bottom-start', offset: 4, strategy: this.portal ? 'fixed' : 'absolute' }),\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._internals = this.attachInternals()\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 this._internals?.setFormValue?.(this._value)\n this.addEventListener('option-register', this._onOptionRegister)\n this.addEventListener('option-unregister', this._onOptionUnregister)\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.removeEventListener('option-register', this._onOptionRegister)\n this.removeEventListener('option-unregister', this._onOptionUnregister)\n this.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('focusout', this._onFocusOut)\n document.removeEventListener('click', this._onClickOutside)\n this._options.forEach(o => {\n o.removeEventListener('click', this._handleOptionClick)\n o.removeEventListener('pointerover', this._handleOptionPointerOver)\n o.removeEventListener('pointerdown', this._handleOptionPointerDown)\n o.removeEventListener('option-update', this._onOptionUpdate)\n })\n this._close()\n this._panel.dispose()\n this._scrollLock.release()\n }\n\n override firstUpdated() {\n requestAnimationFrame(() => {\n if (this.isConnected) this._onSlotChange()\n })\n }\n\n private _queryOptions(): WebUiOption[] {\n const panel = this.portal ? this._panel.getPanel() : null\n const panelOptions = panel ? [...panel.querySelectorAll<WebUiOption>('web-ui-option')] : []\n // 面板内容仅在浮层打开、moveContent 之后存在;关闭时回退 light DOM,\n // 否则 portal select 首次加载时 _options 为空,trigger 显示不出已选值。\n return panelOptions.length > 0 ? panelOptions : [...this.querySelectorAll<WebUiOption>('web-ui-option')]\n }\n\n override willUpdate() {\n this._options = this._queryOptions()\n this._ensureOptionIds()\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.value = this.getAttribute('value') || ''\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || !this.required || this.value) this._internals.setValidity({})\n else this._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 _ensureOptionIds() {\n this._options.forEach((option, index) => {\n if (!option.id) option.id = `${this.localName}-option-${index}`\n })\n }\n\n private _onOptionRegister = (e: Event) => {\n if (!(e.target instanceof HTMLElement)) return\n const target = e.target as WebUiOption\n target.addEventListener('click', this._handleOptionClick)\n target.addEventListener('pointerover', this._handleOptionPointerOver)\n target.addEventListener('pointerdown', this._handleOptionPointerDown)\n target.addEventListener('option-update', this._onOptionUpdate)\n this._options.push(target)\n this._ensureOptionIds()\n this._syncSelected()\n }\n\n private _onOptionUnregister = (e: Event) => {\n if (!(e.target instanceof HTMLElement)) return\n const target = e.target as WebUiOption\n target.removeEventListener('click', this._handleOptionClick)\n target.removeEventListener('pointerover', this._handleOptionPointerOver)\n target.removeEventListener('pointerdown', this._handleOptionPointerDown)\n target.removeEventListener('option-update', this._onOptionUpdate)\n this._options = this._options.filter(o => o !== target)\n }\n\n private _onSlotChange = () => {\n this._options = this._queryOptions()\n this._ensureOptionIds()\n this._syncSelected()\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) 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 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 && !option.disabled) {\n this.value = option.value\n this._notifyValueChange()\n }\n this._close()\n e.preventDefault()\n }\n break\n }\n }\n\n private _navigateActive(delta: number) {\n const enabled = this._options.filter(o => !o.disabled)\n if (!enabled.length) return\n\n const selectedOption = this._options.find(option => option.value === this.value && !option.disabled)\n const currentIdx =\n this._activeIndex >= 0\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(option => option.value === this.value && !option.disabled)\n const firstEnabledIndex = this._options.findIndex(option => !option.disabled)\n this._activeIndex = selectedIndex >= 0 ? selectedIndex : firstEnabledIndex\n this._syncActiveOption()\n }\n\n private _syncActiveOption() {\n this._options.forEach((option, index) => option.toggleAttribute('active', index === this._activeIndex))\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 const panel = !this.portal ? this._panel.getPanel() : null\n if (panel) panel.style.width = `${this._getDesiredWidth()}px`\n this._panel.open(isKeyboardNavigation)\n }\n\n private _getDesiredWidth(): number {\n const trigger = this.shadowRoot?.querySelector<HTMLElement>('.select-trigger')\n const triggerWidth = trigger?.offsetWidth || 0\n\n const options = [...this.querySelectorAll<WebUiOption>('web-ui-option')]\n let maxOptionWidth = 0\n options.forEach(opt => {\n const label = opt.shadowRoot?.querySelector<HTMLElement>('.option-label')\n const w = label?.scrollWidth || opt.scrollWidth || 0\n if (w > maxOptionWidth) maxOptionWidth = w\n })\n\n return Math.max(120, triggerWidth, maxOptionWidth)\n }\n\n private _createPortal(): OverlayPortal {\n const desiredWidth = this._getDesiredWidth()\n\n const portal = createOverlayPortal({\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 })\n portal.panel.style.width = `${desiredWidth}px`\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 scroll.append(content)\n portal.panel.append(scroll)\n portal.moveContent(Array.from(this.children), content)\n return portal\n }\n\n private async _closeOverlay() {\n await this._panel.close(() => this._isOpen)\n }\n\n private _reconfigureOverlay() {\n if (!this.portal) {\n const panel = this._panel.getPanel()\n if (panel) panel.style.width = `${this._getDesiredWidth()}px`\n }\n this._panel.reconfigure(this._isOpen)\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":";;;;;;;;;;;;;AAiBO,IAAM,IAAN,cAA0B,EAAW;;EA+OpB,aAxOW,KAAA,gBAAA,IAEwB,KAAA,cAAA,IACF,KAAA,WAAA,IACA,KAAA,WAAA,IACF,KAAA,SAAA,IACmC,KAAA,eAAA,IAEtC,KAAA,OAAA,IAGxB,KAAA,SAAA,IAgBC,KAAA,UAAA,IACK,KAAA,eAAA,IACE,KAAA,iBAAA,IACC,KAAA,kBAAA,IAED,KAAA,WAAA,CAAC,GACJ,KAAA,cAAA,EAAsB,GAC3B,KAAA,SAAA,EAAoB,CAAC,CAAC,KAAK;GACnD,iBAAiB,KAAK,YAAY,cAA2B,iBAAiB,KAAK;GACnF,qBAAqB,KAAK,YAAY,cAA2B,iBAAiB,KAAK;GACvF,uBAAuB;IAAE,WAAW;IAAgB,QAAQ;IAAG,UAAU,KAAK,SAAS,UAAU;GAAW;GAC5G,gBAAgB,KAAK;GACrB,oBAAoB,KAAK,cAAc;EACzC,CAAC,GAU0B,KAAA,mBAAA,MAAkB;GAC3C,AACE,KAAK,WACL,EAAE,kBAAkB,QACpB,CAAC,KAAK,SAAS,EAAE,MAAM,KACvB,CAAC,KAAK,OAAO,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,KAE1C,KAAK,OAAO;EAEhB,GAE4B,KAAA,oBAAA;GAC1B,4BAA4B;IAC1B,AAAI,KAAK,WAAW,CAAC,KAAK,QAAQ,eAAe,KAAK,CAAC,KAAK,OAAO,SAAS,CAAC,EAAE,QAAQ,eAAe,KACpG,KAAK,OAAO;GAEhB,CAAC;EACH,GAmFgC,KAAA,wBAAA,MAAa;GAE3C,IAAM,IADO,EAAE,OACS,iBAAiB,CAAC,CAAC,SAAS;GAChD,KAAK,oBAAoB,MAC7B,KAAK,kBAAkB,GACvB,KAAK,oBAAoB;EAC3B,GAoB6B,KAAA,qBAAA,MAAa;GACxC,IAAI,EAAE,EAAE,kBAAkB,cAAc;GACxC,IAAM,IAAS,EAAE;GAOjB,AANA,EAAO,iBAAiB,SAAS,KAAK,kBAAkB,GACxD,EAAO,iBAAiB,eAAe,KAAK,wBAAwB,GACpE,EAAO,iBAAiB,eAAe,KAAK,wBAAwB,GACpE,EAAO,iBAAiB,iBAAiB,KAAK,eAAe,GAC7D,KAAK,SAAS,KAAK,CAAM,GACzB,KAAK,iBAAiB,GACtB,KAAK,cAAc;EACrB,GAE+B,KAAA,uBAAA,MAAa;GAC1C,IAAI,EAAE,EAAE,kBAAkB,cAAc;GACxC,IAAM,IAAS,EAAE;GAKjB,AAJA,EAAO,oBAAoB,SAAS,KAAK,kBAAkB,GAC3D,EAAO,oBAAoB,eAAe,KAAK,wBAAwB,GACvE,EAAO,oBAAoB,eAAe,KAAK,wBAAwB,GACvE,EAAO,oBAAoB,iBAAiB,KAAK,eAAe,GAChE,KAAK,WAAW,KAAK,SAAS,QAAO,MAAK,MAAM,CAAM;EACxD,GAE8B,KAAA,sBAAA;GAG5B,AAFA,KAAK,WAAW,KAAK,cAAc,GACnC,KAAK,iBAAiB,GACtB,KAAK,cAAc;EACrB,GAE8B,KAAA,sBAAA,MAAa;GACzC,IAAI,EAAE,EAAE,yBAAyB,cAAc;GAC/C,IAAM,IAAS,EAAE;GACb,EAAO,aACX,KAAK,QAAQ,EAAO,OACpB,KAAK,OAAO,GACZ,KAAK,mBAAmB;EAC1B,GAEgC,KAAA,wBAAA;GAE9B,AADA,KAAK,cAAc,GACnB,KAAK,kBAAkB;EACzB,GAEoC,KAAA,4BAAA,MAAoB;GAClD,EAAE,gBAAgB,YAClB,CAAC,KAAK,WAAW,KAAK,eAAe,KAAK,EAAE,EAAE,yBAAyB,iBAG3E,KAAK,eAAe,IACpB,KAAK,kBAAkB;EACzB,GAEoC,KAAA,4BAAA,MAAoB;GAEtD,EAAE,eAAe;EACnB,GAEsB,KAAA,cAAA,MAAqB;GACrC,UAAK,aAET,QAAQ,EAAE,KAAV;IACE,KAAK;KACH,AAAI,KAAK,YACP,KAAK,OAAO,GACZ,EAAE,eAAe;KAEnB;IACF,KAAK;KAEH,AADA,EAAE,eAAe,GACZ,KAAK,UAGR,KAAK,gBAAgB,CAAC,IAFtB,KAAK,MAAM,EAAI;KAIjB;IACF,KAAK;KAEH,AADA,EAAE,eAAe,GACZ,KAAK,UACL,KAAK,gBAAgB,EAAE,IADT,KAAK,MAAM,EAAI;KAElC;IACF,KAAK;KACH,IAAI,KAAK,WAAW,KAAK,gBAAgB,GAAG;MAC1C,IAAM,IAAS,KAAK,SAAS,KAAK;MAMlC,AALI,KAAU,CAAC,EAAO,aACpB,KAAK,QAAQ,EAAO,OACpB,KAAK,mBAAmB,IAE1B,KAAK,OAAO,GACZ,EAAE,eAAe;KACnB;KACA;GACJ;EACF;;;EAjRyB,KAAA,SAAA;GAAC,EAAU,CAAK;GAAG,EAAU,CAAa;GAAG,EAAU,CAAK;EAAC;;;EAE9D,KAAA,iBAAA;;CAgBxB,IAAI,QAAgB;EAClB,OAAO,KAAK;CACd;CACA,IAAI,MAAM,GAAW;EACnB,IAAM,IAAM,KAAK;EAIjB,AAHA,KAAK,SAAS,GACd,KAAK,YAAY,eAAe,CAAC,GACjC,KAAK,gBAAgB,kBAAkB,CAAC,CAAC,CAAC,GAC1C,KAAK,cAAc,SAAS,CAAG;CACjC;CAEA,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK;CAC/B;CAiBA,IAAI,SAAkB;EACpB,OAAO,KAAK;CACd;CAEA,IAAI,OAAgB;EAClB,OAAO,KAAK;CACd;CAqBA,oBAA6B;EAE3B,AADA,MAAM,kBAAkB,GACxB,KAAK,aAAa,KAAK,gBAAgB;EAEvC,IAAM,IAAY,KAAK,aAAa,OAAO;EAU3C,AATI,MAAc,SAChB,KAAK,SAAS,GACd,KAAK,gBAAgB,kBAAkB,CAAC,CAAC,CAAS,IAEpD,KAAK,YAAY,eAAe,KAAK,MAAM,GAC3C,KAAK,iBAAiB,mBAAmB,KAAK,iBAAiB,GAC/D,KAAK,iBAAiB,qBAAqB,KAAK,mBAAmB,GACnE,KAAK,iBAAiB,WAAW,KAAK,UAAU,GAChD,KAAK,iBAAiB,YAAY,KAAK,WAAW,GAClD,SAAS,iBAAiB,SAAS,KAAK,eAAe;CACzD;CAEA,uBAAgC;EAe9B,AAdA,MAAM,qBAAqB,GAC3B,KAAK,oBAAoB,mBAAmB,KAAK,iBAAiB,GAClE,KAAK,oBAAoB,qBAAqB,KAAK,mBAAmB,GACtE,KAAK,oBAAoB,WAAW,KAAK,UAAU,GACnD,KAAK,oBAAoB,YAAY,KAAK,WAAW,GACrD,SAAS,oBAAoB,SAAS,KAAK,eAAe,GAC1D,KAAK,SAAS,SAAQ,MAAK;GAIzB,AAHA,EAAE,oBAAoB,SAAS,KAAK,kBAAkB,GACtD,EAAE,oBAAoB,eAAe,KAAK,wBAAwB,GAClE,EAAE,oBAAoB,eAAe,KAAK,wBAAwB,GAClE,EAAE,oBAAoB,iBAAiB,KAAK,eAAe;EAC7D,CAAC,GACD,KAAK,OAAO,GACZ,KAAK,OAAO,QAAQ,GACpB,KAAK,YAAY,QAAQ;CAC3B;CAEA,eAAwB;EACtB,4BAA4B;GAC1B,AAAI,KAAK,eAAa,KAAK,cAAc;EAC3C,CAAC;CACH;CAEA,gBAAuC;EACrC,IAAM,IAAQ,KAAK,SAAS,KAAK,OAAO,SAAS,IAAI,MAC/C,IAAe,IAAQ,CAAC,GAAG,EAAM,iBAA8B,eAAe,CAAC,IAAI,CAAC;EAG1F,OAAO,EAAa,SAAS,IAAI,IAAe,CAAC,GAAG,KAAK,iBAA8B,eAAe,CAAC;CACzG;CAEA,aAAsB;EAGpB,AAFA,KAAK,WAAW,KAAK,cAAc,GACnC,KAAK,iBAAiB,GACtB,KAAK,cAAc;CACrB;CAEA,QAAiB,GAAyB;EAKxC,CAJI,EAAQ,IAAI,QAAQ,KAAK,EAAQ,IAAI,kBAAkB,MACzD,4BAA4B,KAAK,oBAAoB,CAAC,GACpD,EAAQ,IAAI,cAAc,KAAG,KAAK,gBAAgB,GACtD,KAAK,mBAAmB,GACxB,KAAK,cAAc;CACrB;CAEA,oBAAoB;EAClB,KAAK,QAAQ,KAAK,aAAa,OAAO,KAAK;CAC7C;CAEA,qBAAqB,GAAmB;EACtC,KAAK,gBAAgB;CACvB;CAEA,gBAAwB;EAClB,CAAC,KAAK,cAAc,OAAO,KAAK,WAAW,eAAgB,eAC3D,KAAK,eAAe,CAAC,KAAK,YAAY,KAAK,QAAO,KAAK,WAAW,YAAY,CAAC,CAAC,IAC/E,KAAK,WAAW,YAAY,EAAE,cAAc,GAAK,GAAG,OAAO;CAClE;CAEA,qBAA6B;EAC3B,KAAK,gBAAgB,QAAQ,KAAK,OAAO;CAC3C;CAUA,gBAAwB;EAItB,IAHA,KAAK,SAAS,SAAQ,MAAK;GACzB,EAAE,WAAW,EAAE,UAAU,KAAK;EAChC,CAAC,GACG,CAAC,KAAK,OAAO;GACf,KAAK,iBAAiB,KAAK;GAC3B;EACF;EACA,IAAM,IAAS,KAAK,SAAS,MAAK,MAAK,EAAE,UAAU,KAAK,KAAK;EAC7D,KAAK,iBAAiB,GAAQ,SAAS,KAAK;CAC9C;CAEA,mBAA2B;EACzB,KAAK,SAAS,SAAS,GAAQ,MAAU;GACvC,AAAgB,EAAO,OAAK,GAAG,KAAK,UAAU,UAAU;EAC1D,CAAC;CACH;CA+FA,gBAAwB,GAAe;EACrC,IAAM,IAAU,KAAK,SAAS,QAAO,MAAK,CAAC,EAAE,QAAQ;EACrD,IAAI,CAAC,EAAQ,QAAQ;EAErB,IAAM,IAAiB,KAAK,SAAS,MAAK,MAAU,EAAO,UAAU,KAAK,SAAS,CAAC,EAAO,QAAQ,GAS/F,KAPF,KAAK,gBAAgB,IACjB,EAAQ,QAAQ,KAAK,SAAS,KAAK,aAAa,IAChD,IACE,EAAQ,QAAQ,CAAc,IAC9B,IAAQ,IACN,KACA,KACiB;EAE3B,AADI,IAAU,MAAG,IAAU,EAAQ,SAAS,IACxC,KAAW,EAAQ,WAAQ,IAAU;EAEzC,IAAM,IAAa,EAAQ;EAG3B,AAFA,KAAK,eAAe,KAAK,SAAS,QAAQ,CAAU,GAEpD,KAAK,kBAAkB;CACzB;CAEA,MAAc,IAAuB,IAAO;EACtC,KAAK,eAAe,KAAK,YAC7B,KAAK,UAAU,IACf,KAAK,oBAAoB,GACzB,KAAK,cAAc,GACf,IAAsB,KAAK,wBAAwB,IAClD,KAAK,kBAAkB,GAC5B,KAAK,gBAAgB,GACjB,KAAK,SACP,4BAA4B;GAC1B,AAAI,KAAK,WAAS,KAAK,aAAa,CAAoB;EAC1D,CAAC,IAED,KAAK,aAAa,CAAoB;CAE1C;CAEA,SAAiB;EACV,KAAK,YACV,KAAK,UAAU,IACf,KAAK,oBAAoB,GACzB,KAAK,eAAe,IACpB,KAAK,SAAS,SAAQ,MAAK,EAAE,gBAAgB,QAAQ,CAAC,GACtD,KAAK,gBAAgB,EAAK,GAC1B,KAAU,cAAc;CAC1B;CAEA,sBAA8B;EAC5B,KAAK,cACH,IAAI,YAAY,eAAe;GAC7B,QAAQ,EAAE,MAAM,KAAK,QAAQ;GAC7B,SAAS;GACT,UAAU;EACZ,CAAC,CACH;CACF;CAEA,0BAAkC;EAChC,IAAM,IAAgB,KAAK,SAAS,WAAU,MAAU,EAAO,UAAU,KAAK,SAAS,CAAC,EAAO,QAAQ,GACjG,IAAoB,KAAK,SAAS,WAAU,MAAU,CAAC,EAAO,QAAQ;EAE5E,AADA,KAAK,eAAe,KAAiB,IAAI,IAAgB,GACzD,KAAK,kBAAkB;CACzB;CAEA,oBAA4B;EAC1B,KAAK,SAAS,SAAS,GAAQ,MAAU,EAAO,gBAAgB,UAAU,MAAU,KAAK,YAAY,CAAC;CACxG;CAEA,qBAA6B;EAE3B,AADA,KAAK,cAAc,IAAI,MAAM,SAAS;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC,GACxE,KAAK,cAAc,IAAI,MAAM,UAAU;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC3E;CAEA,gBAAwB,IAAS,KAAK,SAAS;EAC7C,KAAK,YAAY,KAAK,KAAU,CAAC,KAAK,YAAY;CACpD;CAEA,eAAuB;EACjB,KAAK,gBACL,KAAK,UAAS,KAAK,OAAO,IACzB,KAAK,MAAM;CAClB;CAEA,aAAqB,IAAuB,IAAO;EACjD,IAAM,IAAS,KAAK,SAAkC,OAAzB,KAAK,OAAO,SAAS;EAElD,AADI,MAAO,EAAM,MAAM,QAAQ,GAAG,KAAK,iBAAiB,EAAE,MAC1D,KAAK,OAAO,KAAK,CAAoB;CACvC;CAEA,mBAAmC;EAEjC,IAAM,IADU,KAAK,YAAY,cAA2B,iBAAiB,CAAA,EAC/C,eAAe,GAEvC,IAAU,CAAC,GAAG,KAAK,iBAA8B,eAAe,CAAC,GACnE,IAAiB;EAOrB,OANA,EAAQ,SAAQ,MAAO;GAErB,IAAM,IADQ,EAAI,YAAY,cAA2B,eAAe,CAAA,EACvD,eAAe,EAAI,eAAe;GACnD,AAAI,IAAI,MAAgB,IAAiB;EAC3C,CAAC,GAEM,KAAK,IAAI,KAAK,GAAc,CAAc;CACnD;CAEA,gBAAuC;EACrC,IAAM,IAAe,KAAK,iBAAiB,GAErC,IAAS,EAAoB;GACjC,WAAW,KAAK;GAChB,QAAQ;GACR,OAAO,GAAG,EAAM,IAAI,EAAc,IAAI;GACtC,WAAW;EACb,CAAC;EAED,AADA,EAAO,MAAM,MAAM,QAAQ,GAAG,EAAa,KAC3C,EAAO,MAAM,aAAa,QAAQ,SAAS;EAC3C,IAAM,IAAS,SAAS,cAAc,KAAK;EAC3C,EAAO,YAAY;EACnB,IAAM,IAAU,SAAS,cAAc,KAAK;EAK5C,OAJA,EAAQ,YAAY,kBACpB,EAAO,OAAO,CAAO,GACrB,EAAO,MAAM,OAAO,CAAM,GAC1B,EAAO,YAAY,MAAM,KAAK,KAAK,QAAQ,GAAG,CAAO,GAC9C;CACT;CAEA,MAAc,gBAAgB;EAC5B,MAAM,KAAK,OAAO,YAAY,KAAK,OAAO;CAC5C;CAEA,sBAA8B;EAC5B,IAAI,CAAC,KAAK,QAAQ;GAChB,IAAM,IAAQ,KAAK,OAAO,SAAS;GACnC,AAAI,MAAO,EAAM,MAAM,QAAQ,GAAG,KAAK,iBAAiB,EAAE;EAC5D;EACA,KAAK,OAAO,YAAY,KAAK,OAAO;CACtC;CAEA,SAAkB;EAGhB,IAAM,IAAY,GAAG,KAAK,UAAU,WAC9B,IACJ,CAAC,KAAK,UAAU,KAAK,WAAW,KAAK,gBAAgB,IAChD,KAAK,SAAS,KAAK,aAAa,EAAE,MAAM,IACzC;EAEN,OAAO,CAAI;;;;iCAIkB,KAAK,gBAAgB;mBACnC,KAAK,aAAa;qBAChB,KAAK,cAAc,OAAO,IAAI;;0BAEzB,KAAK,QAAQ;;0BAEb,KAAK,SAAS,IAAU,EAAU;0BAClC,OAAO,KAAK,WAAW,EAAE;kCACjB,EAAiB;;6CAEN,KAAK,qBAAqB;YAC1D,KAAK,kBAA4E,IAA1D,CAAI,uBAAuB,KAAK,eAAe,SAAmB;6CACzD,EAAkB;;4FAE6B,EAAU;;;kCAGpE,KAAK,cAAc;;;;;;CAMnD;AAOF;AApcG,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,iBAAA,KAAA,CAAA,GAEN,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,eAAA,KAAA,CAAA,GACxC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,UAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;CAAM,WAAW;AAAiB,CAAC,CAAA,GAAA,EAAA,WAAA,gBAAA,KAAA,CAAA,GACtE,EAAA,CAAA,EAAS,EAAE,WAAW,GAAM,CAAC,CAAA,GAAA,EAAA,WAAA,oBAAA,KAAA,CAAA,GAC7B,EAAA,CAAA,EAAS;CAAE,MAAM;CAAQ,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,QAAA,KAAA,CAAA,GAGxC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,UAAA,KAAA,CAAA,GAgBN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,gBAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GACN,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,mBAAA,KAAA,CAAA,GAtCR,IAAA,EAAA,CAAA,EAAc,eAAe,CAAA,GAAA,CAAA"}
@@ -30,9 +30,7 @@ export declare class WebUiSlider extends LitElement {
30
30
  formResetCallback(): void;
31
31
  formDisabledCallback(disabled: boolean): void;
32
32
  updated(): void;
33
- /** 将焦点移至滑块,供表单或外部控制使用 */
34
33
  focus(options?: FocusOptions): void;
35
- /** 移除滑块焦点 */
36
34
  blur(): void;
37
35
  private get _slider();
38
36
  private get _range();
@@ -160,7 +160,7 @@ var f = class extends i {
160
160
  class=${e}
161
161
  style=${d({ "--percent": `${this._percent}%` })}
162
162
  role="slider"
163
- tabindex=${this._isDisabled ? -1 : 0}
163
+ tabindex=${this._isDisabled ? "-1" : "0"}
164
164
  aria-label="滑块"
165
165
  aria-orientation=${this.vertical ? "vertical" : "horizontal"}
166
166
  aria-valuemin=${this.min}