@greypan/web-ui 11.0.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.CN.md +105 -41
  2. package/README.md +69 -0
  3. package/dist/assets/overlay-motion.js +1 -1
  4. package/dist/assets/overlay-motion.js.map +1 -1
  5. package/dist/assets/selection-control.js +1 -1
  6. package/dist/assets/selection-control.js.map +1 -1
  7. package/dist/classes/glass.js +6 -0
  8. package/dist/classes/glass.js.map +1 -0
  9. package/dist/classes/glow.js +6 -0
  10. package/dist/classes/glow.js.map +1 -0
  11. package/dist/classes/style.css +1 -0
  12. package/dist/components/autocomplete/index.d.ts +7 -0
  13. package/dist/components/autocomplete/index.js +33 -13
  14. package/dist/components/autocomplete/index.js.map +1 -1
  15. package/dist/components/autocomplete/style.js +1 -1
  16. package/dist/components/autocomplete/style.js.map +1 -1
  17. package/dist/components/avatar/index.js +2 -2
  18. package/dist/components/avatar/index.js.map +1 -1
  19. package/dist/components/avatar/style.js +1 -1
  20. package/dist/components/avatar/style.js.map +1 -1
  21. package/dist/components/back-top/index.d.ts +4 -0
  22. package/dist/components/back-top/index.js +60 -22
  23. package/dist/components/back-top/index.js.map +1 -1
  24. package/dist/components/back-top/style.js +1 -1
  25. package/dist/components/back-top/style.js.map +1 -1
  26. package/dist/components/badge/index.d.ts +3 -0
  27. package/dist/components/badge/index.js +29 -14
  28. package/dist/components/badge/index.js.map +1 -1
  29. package/dist/components/badge/style.js +1 -1
  30. package/dist/components/badge/style.js.map +1 -1
  31. package/dist/components/button/index.d.ts +3 -0
  32. package/dist/components/button/index.js +27 -18
  33. package/dist/components/button/index.js.map +1 -1
  34. package/dist/components/button/style.js +1 -1
  35. package/dist/components/button/style.js.map +1 -1
  36. package/dist/components/button-group/index.d.ts +3 -0
  37. package/dist/components/button-group/index.js +15 -2
  38. package/dist/components/button-group/index.js.map +1 -1
  39. package/dist/components/button-group/style.js +1 -1
  40. package/dist/components/button-group/style.js.map +1 -1
  41. package/dist/components/checkbox/index.js +6 -6
  42. package/dist/components/checkbox/index.js.map +1 -1
  43. package/dist/components/checkbox/style.js +1 -1
  44. package/dist/components/checkbox/style.js.map +1 -1
  45. package/dist/components/collapse/index.d.ts +15 -7
  46. package/dist/components/collapse/index.js +44 -26
  47. package/dist/components/collapse/index.js.map +1 -1
  48. package/dist/components/collapse/style.js +1 -1
  49. package/dist/components/collapse/style.js.map +1 -1
  50. package/dist/components/dialog/index.d.ts +1 -0
  51. package/dist/components/dialog/index.js +5 -2
  52. package/dist/components/dialog/index.js.map +1 -1
  53. package/dist/components/dialog/style.js +1 -1
  54. package/dist/components/dialog/style.js.map +1 -1
  55. package/dist/components/drawer/index.js +1 -1
  56. package/dist/components/drawer/index.js.map +1 -1
  57. package/dist/components/dropdown/index.d.ts +16 -0
  58. package/dist/components/dropdown/index.js +147 -18
  59. package/dist/components/dropdown/index.js.map +1 -1
  60. package/dist/components/dropdown-item/style.js +1 -1
  61. package/dist/components/dropdown-item/style.js.map +1 -1
  62. package/dist/components/editable-text/index.js +7 -3
  63. package/dist/components/editable-text/index.js.map +1 -1
  64. package/dist/components/editable-text/style.js +1 -1
  65. package/dist/components/editable-text/style.js.map +1 -1
  66. package/dist/components/empty/index.d.ts +10 -22
  67. package/dist/components/empty/index.js +19 -35
  68. package/dist/components/empty/index.js.map +1 -1
  69. package/dist/components/empty/style.js +1 -1
  70. package/dist/components/empty/style.js.map +1 -1
  71. package/dist/components/image-preview/index.js +2 -2
  72. package/dist/components/image-preview/index.js.map +1 -1
  73. package/dist/components/input/index.d.ts +1 -0
  74. package/dist/components/input/index.js +5 -2
  75. package/dist/components/input/index.js.map +1 -1
  76. package/dist/components/input/style.js +1 -1
  77. package/dist/components/input/style.js.map +1 -1
  78. package/dist/components/input-number/index.d.ts +31 -1
  79. package/dist/components/input-number/index.js +281 -22
  80. package/dist/components/input-number/index.js.map +1 -1
  81. package/dist/components/input-number/style.js +1 -1
  82. package/dist/components/input-number/style.js.map +1 -1
  83. package/dist/components/layout/index.js +44 -39
  84. package/dist/components/layout/index.js.map +1 -1
  85. package/dist/components/layout/style.js +1 -1
  86. package/dist/components/layout/style.js.map +1 -1
  87. package/dist/components/middle-ellipsis/index.d.ts +8 -1
  88. package/dist/components/middle-ellipsis/index.js +68 -10
  89. package/dist/components/middle-ellipsis/index.js.map +1 -1
  90. package/dist/components/option/style.js +1 -1
  91. package/dist/components/option/style.js.map +1 -1
  92. package/dist/components/popover/index.js +1 -1
  93. package/dist/components/popover/index.js.map +1 -1
  94. package/dist/components/popover/style.js +1 -1
  95. package/dist/components/popover/style.js.map +1 -1
  96. package/dist/components/radio/index.d.ts +5 -0
  97. package/dist/components/radio/index.js +33 -23
  98. package/dist/components/radio/index.js.map +1 -1
  99. package/dist/components/radio/interaction.d.ts +4 -0
  100. package/dist/components/radio/interaction.js +17 -0
  101. package/dist/components/radio/interaction.js.map +1 -0
  102. package/dist/components/radio/style.js +1 -1
  103. package/dist/components/radio/style.js.map +1 -1
  104. package/dist/components/radio-group/index.d.ts +22 -0
  105. package/dist/components/radio-group/index.js +219 -28
  106. package/dist/components/radio-group/index.js.map +1 -1
  107. package/dist/components/segmented/index.d.ts +2 -0
  108. package/dist/components/segmented/index.js +74 -18
  109. package/dist/components/segmented/index.js.map +1 -1
  110. package/dist/components/segmented/style.js +1 -1
  111. package/dist/components/segmented/style.js.map +1 -1
  112. package/dist/components/segmented-trigger/index.js +3 -2
  113. package/dist/components/segmented-trigger/index.js.map +1 -1
  114. package/dist/components/segmented-trigger/style.js +1 -1
  115. package/dist/components/segmented-trigger/style.js.map +1 -1
  116. package/dist/components/select/index.d.ts +8 -0
  117. package/dist/components/select/index.js +76 -25
  118. package/dist/components/select/index.js.map +1 -1
  119. package/dist/components/select/style.js +1 -1
  120. package/dist/components/select/style.js.map +1 -1
  121. package/dist/components/slider/index.d.ts +15 -0
  122. package/dist/components/slider/index.js +175 -39
  123. package/dist/components/slider/index.js.map +1 -1
  124. package/dist/components/slider/style.js +1 -1
  125. package/dist/components/slider/style.js.map +1 -1
  126. package/dist/components/spinner/index.d.ts +15 -0
  127. package/dist/components/spinner/index.js +79 -22
  128. package/dist/components/spinner/index.js.map +1 -1
  129. package/dist/components/spinner/style.js +1 -1
  130. package/dist/components/spinner/style.js.map +1 -1
  131. package/dist/components/svg-draw-lines/index.js +48 -12
  132. package/dist/components/svg-draw-lines/index.js.map +1 -1
  133. package/dist/components/switch/index.d.ts +11 -3
  134. package/dist/components/switch/index.js +57 -53
  135. package/dist/components/switch/index.js.map +1 -1
  136. package/dist/components/switch/style.js +1 -1
  137. package/dist/components/switch/style.js.map +1 -1
  138. package/dist/components/textarea/index.js +2 -2
  139. package/dist/components/textarea/index.js.map +1 -1
  140. package/dist/components/textarea/style.js +1 -1
  141. package/dist/components/textarea/style.js.map +1 -1
  142. package/dist/components/theme/index.d.ts +1 -0
  143. package/dist/components/theme/index.js +26 -15
  144. package/dist/components/theme/index.js.map +1 -1
  145. package/dist/components/theme/style.js +1 -1
  146. package/dist/components/theme/style.js.map +1 -1
  147. package/dist/components/toast/style.js +1 -1
  148. package/dist/components/toast/style.js.map +1 -1
  149. package/dist/components/toast/toast.js +1 -1
  150. package/dist/components/toast/toast.js.map +1 -1
  151. package/dist/components/tooltip/index.d.ts +1 -0
  152. package/dist/components/tooltip/index.js +10 -5
  153. package/dist/components/tooltip/index.js.map +1 -1
  154. package/dist/icons/generated/andrsrxn-inbox.d.ts +6 -0
  155. package/dist/icons/generated/andrsrxn-inbox.js +10 -0
  156. package/dist/icons/generated/andrsrxn-inbox.js.map +1 -0
  157. package/dist/icons/index.d.ts +1 -0
  158. package/dist/icons/index.js +75 -74
  159. package/dist/shared/focus/pointer-focus.js +12 -10
  160. package/dist/shared/focus/pointer-focus.js.map +1 -1
  161. package/dist/shared/gesture/drag-gesture.js +4 -4
  162. package/dist/shared/gesture/drag-gesture.js.map +1 -1
  163. package/dist/shared/group-management/index.js +43 -18
  164. package/dist/shared/group-management/index.js.map +1 -1
  165. package/dist/shared/menu-portal/menu-portal.js +1 -1
  166. package/dist/shared/menu-portal/menu-portal.js.map +1 -1
  167. package/dist/shared/overlay/overlay-root.js +1 -1
  168. package/dist/shared/overlay/overlay-root.js.map +1 -1
  169. package/dist/shared/overlay/overlay.js +7 -1
  170. package/dist/shared/overlay/overlay.js.map +1 -1
  171. package/package.json +5 -1
  172. package/dist/assets/glass.js +0 -6
  173. package/dist/assets/glass.js.map +0 -1
@@ -2,38 +2,113 @@ import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate
2
2
  import { FormAssociated as t, FormAssociationController as n, defineFormAssociation as r } from "../../shared/form-association/index.js";
3
3
  import { GroupController as i, defineGroupCoordinator as a } from "../../shared/group-management/index.js";
4
4
  import { normalizeLiteral as o } from "../../shared/normalize/index.js";
5
- import s from "./style.js";
6
- import { LitElement as c, html as l, unsafeCSS as u } from "lit";
7
- import { customElement as d, property as f, state as p } from "lit/decorators.js";
5
+ import { activateRadio as s, focusRadio as c, isRadioDisabled as l } from "../radio/interaction.js";
6
+ import u from "./style.js";
7
+ import { LitElement as d, html as f, unsafeCSS as p } from "lit";
8
+ import { customElement as m, property as h, state as g } from "lit/decorators.js";
8
9
  //#region src/components/radio-group/index.ts
9
- var m = ["horizontal", "vertical"], h = class extends t(c) {
10
+ var _ = ["horizontal", "vertical"], v = {
11
+ next: ["ArrowRight", "ArrowDown"],
12
+ previous: ["ArrowLeft", "ArrowUp"]
13
+ }, y = [
14
+ "hidden",
15
+ "inert",
16
+ "aria-hidden",
17
+ "style",
18
+ "class",
19
+ "open",
20
+ "popover",
21
+ "slot"
22
+ ], b = /* @__PURE__ */ new WeakMap();
23
+ function x(e, t) {
24
+ let n = e.defaultView;
25
+ if (!n) return () => {};
26
+ let r = b.get(e);
27
+ if (!r) {
28
+ let t = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map(), a = () => t.forEach((e) => e()), o = (e) => {
29
+ let t = e.trim();
30
+ if (t && t !== "all" && !i.has(t)) try {
31
+ let e = n.matchMedia(t);
32
+ e.addEventListener("change", a), i.set(t, e);
33
+ } catch {}
34
+ }, s = (e, t = /* @__PURE__ */ new Set()) => {
35
+ for (let n of Array.from(e)) {
36
+ if (n instanceof CSSMediaRule && o(n.conditionText), n instanceof CSSImportRule && n.styleSheet && !t.has(n.styleSheet)) {
37
+ t.add(n.styleSheet), o(n.media.mediaText);
38
+ try {
39
+ s(n.styleSheet.cssRules, t);
40
+ } catch {}
41
+ }
42
+ if ("cssRules" in n) try {
43
+ s(n.cssRules, t);
44
+ } catch {}
45
+ }
46
+ }, c = () => {
47
+ for (let e of i.values()) e.removeEventListener("change", a);
48
+ i.clear();
49
+ for (let t of Array.from(e.styleSheets)) {
50
+ o(t.media.mediaText);
51
+ try {
52
+ s(t.cssRules, /* @__PURE__ */ new Set([t]));
53
+ } catch {}
54
+ }
55
+ }, l = (e) => {
56
+ let t = e.target;
57
+ t instanceof HTMLLinkElement && t.relList.contains("stylesheet") && (c(), a());
58
+ }, u = (e) => {
59
+ e.key === "Tab" && (c(), a());
60
+ }, d = new MutationObserver(() => {
61
+ c(), a();
62
+ }), f = e.head ?? e.documentElement;
63
+ d.observe(f, {
64
+ attributes: !0,
65
+ childList: !0,
66
+ characterData: !0,
67
+ subtree: !0
68
+ }), n.addEventListener("resize", a), e.addEventListener("load", l, !0), e.addEventListener("keydown", u, !0), r = {
69
+ subscribers: t,
70
+ mediaQueries: i,
71
+ observer: d,
72
+ view: n,
73
+ notify: a,
74
+ refreshMediaQueries: c,
75
+ handleStylesheetLoad: l,
76
+ handleTabKeydown: u
77
+ }, b.set(e, r), c();
78
+ }
79
+ return r.subscribers.add(t), () => {
80
+ let n = b.get(e);
81
+ if (n && (n.subscribers.delete(t), !(n.subscribers.size > 0))) {
82
+ n.observer.disconnect(), n.view.removeEventListener("resize", n.notify), e.removeEventListener("load", n.handleStylesheetLoad, !0), e.removeEventListener("keydown", n.handleTabKeydown, !0);
83
+ for (let e of n.mediaQueries.values()) e.removeEventListener("change", n.notify);
84
+ n.mediaQueries.clear(), b.delete(e);
85
+ }
86
+ };
87
+ }
88
+ var S = class extends t(d) {
10
89
  constructor(...e) {
11
- super(...e), this.name = "", this.disabled = !1, this.required = !1, this._direction = "vertical", this._value = "", this._groupController = new i(this, a({
90
+ super(...e), this.name = "", this.disabled = !1, this.required = !1, this.ariaLabel = null, this._direction = "vertical", this._value = "", this._groupController = new i(this, a({
12
91
  host: this,
13
- getItems: () => [...this.querySelectorAll("web-ui-radio")],
92
+ getItems: () => this._getRadios(),
14
93
  getValue: () => this._value,
15
94
  setValue: (e) => {
16
95
  this.value = e;
17
96
  },
18
97
  getDisabled: () => this._isDisabled,
19
- isItem: (e) => e instanceof HTMLElement && e.matches("web-ui-radio"),
20
- isItemSelected: (e, t) => {
21
- if (!t) return !1;
22
- let n;
23
- for (let e of this.querySelectorAll("web-ui-radio")) if (e.value === t && (n ||= e, e.checked)) {
24
- n = e;
25
- break;
26
- }
27
- return e === n;
28
- },
98
+ isItem: (e) => e instanceof HTMLElement && e.matches("web-ui-radio") && e.closest("web-ui-radio-group") === this,
99
+ isItemSelected: (e, t) => e === this._findSelectedRadio(this._getRadios(), t),
100
+ getItemSelected: (e) => e.checked,
29
101
  getNextValue: (e, t) => e.checked ? e.value : t,
30
102
  valuesEqual: (e, t) => e === t,
31
103
  copyValue: (e) => e,
32
104
  setItemSelected: (e, t) => {
33
105
  e.checked = t;
34
106
  },
107
+ getRovingTabStop: (e, t, n, r) => this._getRovingTabStop(e, n, r),
108
+ handleKeyDown: (e) => this._handleKeyDown(e),
35
109
  resyncOnUnchangedValue: (e) => {
36
- for (let t of this.querySelectorAll("web-ui-radio")) t.checked = t === e;
110
+ for (let t of this._getRadios()) t.checked = t === e;
111
+ this._groupController.sync();
37
112
  },
38
113
  dispatchValueChange: () => {
39
114
  this.dispatchEvent(new Event("input", {
@@ -44,7 +119,12 @@ var m = ["horizontal", "vertical"], h = class extends t(c) {
44
119
  composed: !0
45
120
  }));
46
121
  }
47
- }).make(), { afterSync: () => this._pruneRemovedMembers() }), this._knownMemberValues = /* @__PURE__ */ new Set(), this._formAssociation = r({
122
+ }).make(), {
123
+ observeAttributes: ["disabled", ...y],
124
+ afterSync: () => this._pruneRemovedMembers()
125
+ }), this._knownMemberValues = /* @__PURE__ */ new Set(), this._availabilityObserver = null, this._availabilityResizeObserver = null, this._availabilityToggleTargets = /* @__PURE__ */ new Set(), this._availabilitySlotTargets = /* @__PURE__ */ new Set(), this._unsubscribeDocumentAvailability = null, this._handleAvailabilityToggle = () => this._groupController.sync(), this._handleAvailabilitySlotChange = () => {
126
+ this._observeAvailabilityAncestors(), this._groupController.sync();
127
+ }, this._formAssociation = r({
48
128
  host: this,
49
129
  initialize: () => {
50
130
  let e = this.getAttribute("value");
@@ -63,18 +143,65 @@ var m = ["horizontal", "vertical"], h = class extends t(c) {
63
143
  }).make(), this._formAssociationController = new n(this, this._formAssociation);
64
144
  }
65
145
  static {
66
- this.styles = u(s);
146
+ this.styles = p(u);
67
147
  }
68
148
  get direction() {
69
149
  return this._direction;
70
150
  }
71
151
  set direction(e) {
72
152
  let t = this._direction;
73
- this._direction = o(e, m, "vertical"), this.requestUpdate("direction", t);
153
+ this._direction = o(e, _, "vertical"), this.requestUpdate("direction", t);
154
+ }
155
+ _getRadios() {
156
+ return [...this.querySelectorAll("web-ui-radio")].filter((e) => e.closest("web-ui-radio-group") === this);
157
+ }
158
+ _findSelectedRadio(e, t) {
159
+ if (!t) return;
160
+ let n = e.filter((e) => e.value === t);
161
+ return n.find((e) => e.checked) ?? n[0];
162
+ }
163
+ _getRovingTabStop(e, t, n) {
164
+ if (this._isDisabled || this._isRadioUnavailable(e)) return !1;
165
+ let r = t.filter((e) => !this._isRadioUnavailable(e));
166
+ return e === (r.find((e) => e.checked) ?? this._findSelectedRadio(r, n) ?? r[0]);
167
+ }
168
+ _handleKeyDown(e) {
169
+ if (this._isDisabled || e.defaultPrevented || e.altKey || e.ctrlKey || e.metaKey) return;
170
+ let t = e.composedPath().find((e) => e instanceof HTMLElement && e.matches("web-ui-radio"));
171
+ if (!t || t.closest("web-ui-radio-group") !== this) return;
172
+ let n = this._getRadios(), r = n.indexOf(t);
173
+ if (r < 0) return;
174
+ let i = n.filter((e) => !this._isRadioUnavailable(e));
175
+ if (i.length === 0) return;
176
+ let a = i.indexOf(t), o = v.next.some((t) => e.key === t) ? 1 : v.previous.some((t) => e.key === t) ? -1 : 0;
177
+ o && this.direction === "horizontal" && (e.key === "ArrowLeft" || e.key === "ArrowRight") && getComputedStyle(this).direction === "rtl" && (o *= -1);
178
+ let l;
179
+ if (o) {
180
+ if (a >= 0) l = i[(a + o + i.length) % i.length];
181
+ else for (let e = 1; e <= n.length; e++) {
182
+ let t = n[((r + o * e) % n.length + n.length) % n.length];
183
+ if (t && !this._isRadioUnavailable(t)) {
184
+ l = t;
185
+ break;
186
+ }
187
+ }
188
+ } else if (e.key === "Home") l = i[0];
189
+ else if (e.key === "End") l = i[i.length - 1];
190
+ else return;
191
+ l && (e.preventDefault(), c(l), l.checked || s(l));
192
+ }
193
+ _getComposedAncestors(e) {
194
+ let t = [], n = /* @__PURE__ */ new Set(), r = e;
195
+ for (; r && !n.has(r);) {
196
+ n.add(r), t.push(r);
197
+ let e = r.getRootNode();
198
+ r = r.assignedSlot ?? r.parentElement ?? (e instanceof ShadowRoot ? e.host : null);
199
+ }
200
+ return t;
74
201
  }
75
202
  _pruneRemovedMembers() {
76
203
  if (!this._value) return;
77
- let e = [...this.querySelectorAll("web-ui-radio")];
204
+ let e = this._getRadios();
78
205
  if (e.length === 0) return;
79
206
  let t = new Set(e.map((e) => e.value));
80
207
  !t.has(this._value) && this._knownMemberValues.has(this._value) && (this.value = ""), this._knownMemberValues = t;
@@ -89,6 +216,62 @@ var m = ["horizontal", "vertical"], h = class extends t(c) {
89
216
  get _isDisabled() {
90
217
  return this.disabled || this._formAssociation.isFormDisabled();
91
218
  }
219
+ connectedCallback() {
220
+ this._syncHostSemantics(), this._observeAvailabilityAncestors(), this._unsubscribeDocumentAvailability?.(), this._unsubscribeDocumentAvailability = x(this.ownerDocument, () => this._groupController.sync()), super.connectedCallback();
221
+ }
222
+ disconnectedCallback() {
223
+ this._availabilityObserver?.disconnect(), this._availabilityObserver = null, this._availabilityResizeObserver?.disconnect(), this._availabilityResizeObserver = null, this._syncAvailabilityToggleTargets([]), this._syncAvailabilitySlotTargets([]), this._unsubscribeDocumentAvailability?.(), this._unsubscribeDocumentAvailability = null, super.disconnectedCallback();
224
+ }
225
+ updated() {
226
+ this._syncHostSemantics();
227
+ }
228
+ _syncHostSemantics() {
229
+ this.setAttribute("role", "radiogroup"), this.setAttribute("aria-orientation", this.direction), this.setAttribute("aria-disabled", String(this._isDisabled)), this.setAttribute("aria-required", String(this.required));
230
+ }
231
+ _isRadioUnavailable(e) {
232
+ if (l(e) || e.matches(":disabled")) return !0;
233
+ let t = this._getComposedAncestors(e), n = (e) => {
234
+ let n = [...e.children].find((e) => e.localName === "summary");
235
+ return n !== void 0 && t.includes(n);
236
+ };
237
+ if (t.some((e) => e.hasAttribute("hidden") || e.hasAttribute("inert") || e.getAttribute("aria-hidden")?.toLowerCase() === "true" || e.localName === "details" && !e.hasAttribute("open") && !n(e))) return !0;
238
+ let r = e.ownerDocument.defaultView;
239
+ if (!r) return !1;
240
+ let i = r.getComputedStyle(e).visibility;
241
+ if (i === "hidden" || i === "collapse") return !0;
242
+ for (let e of t) {
243
+ let t = r.getComputedStyle(e);
244
+ if (t.display === "none" || t.getPropertyValue("content-visibility") === "hidden") return !0;
245
+ }
246
+ return !1;
247
+ }
248
+ _observeAvailabilityAncestors() {
249
+ this._availabilityObserver?.disconnect(), this._availabilityObserver = null, this._availabilityResizeObserver?.disconnect(), this._availabilityResizeObserver = null;
250
+ let e = this._getComposedAncestors(this);
251
+ if (this._syncAvailabilityToggleTargets(e), this._syncAvailabilitySlotTargets(e), e.length !== 0) {
252
+ this._availabilityObserver = new MutationObserver((e) => {
253
+ e.some((e) => e.attributeName === "popover" || e.attributeName === "slot") && this._observeAvailabilityAncestors(), this._groupController.sync();
254
+ });
255
+ for (let t of e) this._availabilityObserver.observe(t, {
256
+ attributes: !0,
257
+ attributeFilter: [...y]
258
+ });
259
+ if (typeof ResizeObserver < "u") {
260
+ this._availabilityResizeObserver = new ResizeObserver(() => this._groupController.sync());
261
+ for (let t of e) this._availabilityResizeObserver.observe(t);
262
+ }
263
+ }
264
+ }
265
+ _syncAvailabilityToggleTargets(e) {
266
+ for (let e of this._availabilityToggleTargets) e.removeEventListener("toggle", this._handleAvailabilityToggle);
267
+ this._availabilityToggleTargets.clear();
268
+ for (let t of e) t.hasAttribute("popover") && (t.addEventListener("toggle", this._handleAvailabilityToggle), this._availabilityToggleTargets.add(t));
269
+ }
270
+ _syncAvailabilitySlotTargets(e) {
271
+ for (let e of this._availabilitySlotTargets) e.removeEventListener("slotchange", this._handleAvailabilitySlotChange);
272
+ this._availabilitySlotTargets.clear();
273
+ for (let t of e) t.localName === "slot" && (t.addEventListener("slotchange", this._handleAvailabilitySlotChange), this._availabilitySlotTargets.add(t));
274
+ }
92
275
  formDisabledCallback(e) {
93
276
  this._formAssociation.setDisabled(e), this._groupController.sync();
94
277
  }
@@ -103,23 +286,31 @@ var m = ["horizontal", "vertical"], h = class extends t(c) {
103
286
  }
104
287
  }
105
288
  render() {
106
- return l`<div class="wui-radio-group"><slot></slot></div>`;
289
+ return f`<div class="wui-radio-group"><slot></slot></div>`;
107
290
  }
108
291
  };
109
- e([f({
292
+ e([h({
110
293
  type: String,
111
294
  reflect: !0
112
- })], h.prototype, "name", void 0), e([f({
295
+ })], S.prototype, "name", void 0), e([h({
113
296
  type: Boolean,
114
297
  reflect: !0
115
- })], h.prototype, "disabled", void 0), e([f({
298
+ })], S.prototype, "disabled", void 0), e([h({
116
299
  type: Boolean,
117
300
  reflect: !0
118
- })], h.prototype, "required", void 0), e([f({
301
+ })], S.prototype, "required", void 0), e([h({
302
+ type: String,
303
+ attribute: "aria-label",
304
+ reflect: !0
305
+ })], S.prototype, "ariaLabel", void 0), e([h({
306
+ type: String,
307
+ attribute: "aria-labelledby",
308
+ reflect: !0
309
+ })], S.prototype, "ariaLabelledby", void 0), e([h({
119
310
  type: String,
120
311
  reflect: !0
121
- })], h.prototype, "direction", null), e([p()], h.prototype, "_value", void 0), h = e([d("web-ui-radio-group")], h);
312
+ })], S.prototype, "direction", null), e([g()], S.prototype, "_value", void 0), S = e([m("web-ui-radio-group")], S);
122
313
  //#endregion
123
- export { h as WebUiRadioGroup };
314
+ export { S as WebUiRadioGroup };
124
315
 
125
316
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/radio-group/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { defineGroupCoordinator, GroupController } from '@/shared/group-management'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport type { WebUiRadio } from '../radio'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_DIRECTIONS = ['horizontal', 'vertical'] as const\n\n@customElement('web-ui-radio-group')\nexport class WebUiRadioGroup extends FormAssociated(LitElement) {\n static override styles = unsafeCSS(style)\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 @property({ type: String, reflect: true })\n get direction(): 'horizontal' | 'vertical' {\n return this._direction\n }\n set direction(v: string) {\n const old = this._direction\n this._direction = normalizeLiteral(v, ALLOWED_DIRECTIONS, 'vertical')\n this.requestUpdate('direction', old)\n }\n private _direction: 'horizontal' | 'vertical' = 'vertical'\n\n @state() private _value = ''\n\n private readonly _groupController = new GroupController(\n this,\n defineGroupCoordinator<WebUiRadio, string>({\n host: this,\n getItems: () => [...this.querySelectorAll<WebUiRadio>('web-ui-radio')],\n getValue: () => this._value,\n setValue: value => {\n this.value = value\n },\n getDisabled: () => this._isDisabled,\n isItem: (target): target is WebUiRadio => target instanceof HTMLElement && target.matches('web-ui-radio'),\n // 选中判定按元素身份而非 value 相等:value 重复时按值比较会把多个成员\n // 同时标为选中,破坏单选不变式。重复值取第一个匹配(或已选中的那个,\n // 避免每次 sync 把选中项跳回第一个)。\n isItemSelected: (radio, value) => {\n if (!value) return false\n let selected: WebUiRadio | undefined\n for (const item of this.querySelectorAll<WebUiRadio>('web-ui-radio')) {\n if (item.value !== value) continue\n if (!selected) selected = item\n if (item.checked) {\n selected = item\n break\n }\n }\n return radio === selected\n },\n getNextValue: (radio, value) => (radio.checked ? radio.value : value),\n valuesEqual: (a, b) => a === b,\n copyValue: value => value,\n setItemSelected: (radio, selected) => {\n radio.checked = selected\n },\n // 点击同值成员时 value 不变,仍需把选中态收到被点击的那一项\n resyncOnUnchangedValue: clicked => {\n for (const radio of this.querySelectorAll<WebUiRadio>('web-ui-radio')) {\n radio.checked = radio === clicked\n }\n },\n dispatchValueChange: () => {\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n }).make(),\n // 每次成员集合同步后把组值剪到现存成员范围内\n { afterSync: () => this._pruneRemovedMembers() }\n )\n\n /**\n * 成员被移除后,组值若仍指向它就成了幽灵值(表单照旧提交一个不存在的 option)。\n * 剪枝条件是「曾经出现在成员里、现在消失了」——不能用「不在现存成员里就剪」,\n * 否则 v-if / 异步渲染时先于成员到达的合法组值会被误清。\n */\n private _knownMemberValues = new Set<string>()\n\n private _pruneRemovedMembers() {\n if (!this._value) return\n const items = [...this.querySelectorAll<WebUiRadio>('web-ui-radio')]\n if (items.length === 0) return\n const alive = new Set(items.map(item => item.value))\n if (!alive.has(this._value) && this._knownMemberValues.has(this._value)) this.value = ''\n this._knownMemberValues = alive\n }\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._formAssociation.sync()\n this.requestUpdate('value', old)\n }\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formAssociation.isFormDisabled()\n }\n\n private readonly _formAssociation = defineFormAssociation<string>({\n host: this,\n initialize: () => {\n const attributeValue = this.getAttribute('value')\n if (attributeValue !== null) this.value = attributeValue\n },\n getState: () => this._value,\n setState: value => {\n this.value = value\n },\n getFormValue: () => (this.name && this._value ? this._value : null),\n getFormState: () => this._value,\n restoreState: state => {\n if (typeof state === 'string') this.value = state\n },\n syncValidity: () => this._syncValidity()\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n override formDisabledCallback(disabled: boolean) {\n this._formAssociation.setDisabled(disabled)\n this._groupController.sync()\n }\n\n private _syncValidity() {\n const internals = this._formAssociation.getInternals()\n if (!internals || typeof internals.setValidity !== 'function') return\n if (this._isDisabled || !this.required || this._value) {\n internals.setValidity({})\n return\n }\n internals.setValidity({ valueMissing: true }, 'Select an option')\n }\n\n override render() {\n return html`<div class=\"wui-radio-group\"><slot></slot></div>`\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-radio-group': WebUiRadioGroup\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/radio-group/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { defineGroupCoordinator, GroupController } from '@/shared/group-management'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport type { WebUiRadio } from '../radio'\nimport { activateRadio, focusRadio, isRadioDisabled } from '../radio/interaction'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_DIRECTIONS = ['horizontal', 'vertical'] as const\nconst RADIO_GROUP_KEYS = {\n next: ['ArrowRight', 'ArrowDown'],\n previous: ['ArrowLeft', 'ArrowUp']\n} as const\nconst AVAILABILITY_ATTRIBUTES = ['hidden', 'inert', 'aria-hidden', 'style', 'class', 'open', 'popover', 'slot'] as const\n\ninterface DocumentAvailabilityObserver {\n readonly subscribers: Set<() => void>\n readonly mediaQueries: Map<string, MediaQueryList>\n readonly observer: MutationObserver\n readonly view: Window\n readonly notify: () => void\n readonly refreshMediaQueries: () => void\n readonly handleStylesheetLoad: (event: Event) => void\n readonly handleTabKeydown: (event: KeyboardEvent) => void\n}\n\nconst documentAvailabilityObservers = new WeakMap<Document, DocumentAvailabilityObserver>()\n\nfunction subscribeToDocumentAvailability(document: Document, callback: () => void): () => void {\n const view = document.defaultView\n if (!view) return () => {}\n\n let state = documentAvailabilityObservers.get(document)\n if (!state) {\n const subscribers = new Set<() => void>()\n const mediaQueries = new Map<string, MediaQueryList>()\n const notify = () => subscribers.forEach(subscriber => subscriber())\n const subscribeMediaQuery = (query: string) => {\n const normalized = query.trim()\n if (!normalized || normalized === 'all' || mediaQueries.has(normalized)) return\n try {\n const mediaQuery = view.matchMedia(normalized)\n mediaQuery.addEventListener('change', notify)\n mediaQueries.set(normalized, mediaQuery)\n } catch {\n // Invalid or unsupported media syntax cannot change computed visibility.\n }\n }\n const scanRules = (rules: CSSRuleList, visited = new Set<CSSStyleSheet>()) => {\n for (const rule of Array.from(rules)) {\n if (rule instanceof CSSMediaRule) subscribeMediaQuery(rule.conditionText)\n if (rule instanceof CSSImportRule && rule.styleSheet && !visited.has(rule.styleSheet)) {\n visited.add(rule.styleSheet)\n subscribeMediaQuery(rule.media.mediaText)\n try {\n scanRules(rule.styleSheet.cssRules, visited)\n } catch {\n // Cross-origin stylesheets may hide their rules from the current document.\n }\n }\n if ('cssRules' in rule) {\n try {\n scanRules((rule as CSSGroupingRule).cssRules, visited)\n } catch {\n // Some grouping rules expose inaccessible imported rules.\n }\n }\n }\n }\n const refreshMediaQueries = () => {\n for (const mediaQuery of mediaQueries.values()) mediaQuery.removeEventListener('change', notify)\n mediaQueries.clear()\n for (const styleSheet of Array.from(document.styleSheets)) {\n subscribeMediaQuery(styleSheet.media.mediaText)\n try {\n scanRules(styleSheet.cssRules, new Set([styleSheet]))\n } catch {\n // Cross-origin stylesheets may hide their rules from the current document.\n }\n }\n }\n const handleStylesheetLoad = (event: Event) => {\n const target = event.target\n if (!(target instanceof HTMLLinkElement) || !target.relList.contains('stylesheet')) return\n refreshMediaQueries()\n notify()\n }\n // CSSStyleSheet has no rule-change event. Refresh before the browser's Tab\n // default action so CSSOM-only visibility changes cannot strand the group.\n const handleTabKeydown = (event: KeyboardEvent) => {\n if (event.key === 'Tab') {\n refreshMediaQueries()\n notify()\n }\n }\n const observer = new MutationObserver(() => {\n refreshMediaQueries()\n notify()\n })\n const styleRoot = document.head ?? document.documentElement\n observer.observe(styleRoot, { attributes: true, childList: true, characterData: true, subtree: true })\n view.addEventListener('resize', notify)\n document.addEventListener('load', handleStylesheetLoad, true)\n document.addEventListener('keydown', handleTabKeydown, true)\n state = {\n subscribers,\n mediaQueries,\n observer,\n view,\n notify,\n refreshMediaQueries,\n handleStylesheetLoad,\n handleTabKeydown\n }\n documentAvailabilityObservers.set(document, state)\n refreshMediaQueries()\n }\n\n state.subscribers.add(callback)\n return () => {\n const current = documentAvailabilityObservers.get(document)\n if (!current) return\n current.subscribers.delete(callback)\n if (current.subscribers.size > 0) return\n current.observer.disconnect()\n current.view.removeEventListener('resize', current.notify)\n document.removeEventListener('load', current.handleStylesheetLoad, true)\n document.removeEventListener('keydown', current.handleTabKeydown, true)\n for (const mediaQuery of current.mediaQueries.values()) mediaQuery.removeEventListener('change', current.notify)\n current.mediaQueries.clear()\n documentAvailabilityObservers.delete(document)\n }\n}\n\n@customElement('web-ui-radio-group')\nexport class WebUiRadioGroup extends FormAssociated(LitElement) {\n static override styles = unsafeCSS(style)\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n @property({ type: String, attribute: 'aria-label', reflect: true }) override ariaLabel: string | null = null\n @property({ type: String, attribute: 'aria-labelledby', reflect: true }) ariaLabelledby: string | undefined\n\n @property({ type: String, reflect: true })\n get direction(): 'horizontal' | 'vertical' {\n return this._direction\n }\n set direction(v: string) {\n const old = this._direction\n this._direction = normalizeLiteral(v, ALLOWED_DIRECTIONS, 'vertical')\n this.requestUpdate('direction', old)\n }\n private _direction: 'horizontal' | 'vertical' = 'vertical'\n\n @state() private _value = ''\n\n private _getRadios(): WebUiRadio[] {\n return [...this.querySelectorAll<WebUiRadio>('web-ui-radio')].filter(\n radio => radio.closest('web-ui-radio-group') === this\n )\n }\n\n private _findSelectedRadio(radios: readonly WebUiRadio[], value: string): WebUiRadio | undefined {\n if (!value) return undefined\n const matching = radios.filter(radio => radio.value === value)\n return matching.find(radio => radio.checked) ?? matching[0]\n }\n\n private _getRovingTabStop(radio: WebUiRadio, radios: readonly WebUiRadio[], value: string): boolean {\n if (this._isDisabled || this._isRadioUnavailable(radio)) return false\n const enabled = radios.filter(item => !this._isRadioUnavailable(item))\n const selected = enabled.find(item => item.checked) ?? this._findSelectedRadio(enabled, value)\n return radio === (selected ?? enabled[0])\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n if (this._isDisabled || event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) return\n const target = event\n .composedPath()\n .find((node): node is WebUiRadio => node instanceof HTMLElement && node.matches('web-ui-radio'))\n if (!target || target.closest('web-ui-radio-group') !== this) return\n\n const radios = this._getRadios()\n const targetIndex = radios.indexOf(target)\n if (targetIndex < 0) return\n\n const enabledRadios = radios.filter(radio => !this._isRadioUnavailable(radio))\n if (enabledRadios.length === 0) return\n const currentIndex = enabledRadios.indexOf(target)\n\n let delta = RADIO_GROUP_KEYS.next.some(key => event.key === key)\n ? 1\n : RADIO_GROUP_KEYS.previous.some(key => event.key === key)\n ? -1\n : 0\n if (\n delta &&\n this.direction === 'horizontal' &&\n (event.key === 'ArrowLeft' || event.key === 'ArrowRight') &&\n getComputedStyle(this).direction === 'rtl'\n ) {\n delta *= -1\n }\n let nextRadio: WebUiRadio | undefined\n if (delta) {\n if (currentIndex >= 0) {\n nextRadio = enabledRadios[(currentIndex + delta + enabledRadios.length) % enabledRadios.length]\n } else {\n for (let step = 1; step <= radios.length; step++) {\n const candidateIndex = (((targetIndex + delta * step) % radios.length) + radios.length) % radios.length\n const candidate = radios[candidateIndex]\n if (candidate && !this._isRadioUnavailable(candidate)) {\n nextRadio = candidate\n break\n }\n }\n }\n } else if (event.key === 'Home') {\n nextRadio = enabledRadios[0]\n } else if (event.key === 'End') {\n nextRadio = enabledRadios[enabledRadios.length - 1]\n } else {\n return\n }\n\n if (!nextRadio) return\n event.preventDefault()\n focusRadio(nextRadio)\n if (!nextRadio.checked) activateRadio(nextRadio)\n }\n\n private readonly _groupController = new GroupController(\n this,\n defineGroupCoordinator<WebUiRadio, string>({\n host: this,\n getItems: () => this._getRadios(),\n getValue: () => this._value,\n setValue: value => {\n this.value = value\n },\n getDisabled: () => this._isDisabled,\n isItem: (target): target is WebUiRadio =>\n target instanceof HTMLElement &&\n target.matches('web-ui-radio') &&\n target.closest('web-ui-radio-group') === this,\n // 选中判定按元素身份而非 value 相等:value 重复时按值比较会把多个成员\n // 同时标为选中,破坏单选不变式。重复值取第一个匹配(或已选中的那个,\n // 避免每次 sync 把选中项跳回第一个)。\n isItemSelected: (radio, value) => radio === this._findSelectedRadio(this._getRadios(), value),\n getItemSelected: radio => radio.checked,\n getNextValue: (radio, value) => (radio.checked ? radio.value : value),\n valuesEqual: (a, b) => a === b,\n copyValue: value => value,\n setItemSelected: (radio, selected) => {\n radio.checked = selected\n },\n getRovingTabStop: (radio, _index, radios, value) => this._getRovingTabStop(radio, radios, value),\n handleKeyDown: event => this._handleKeyDown(event),\n // 点击同值成员时 value 不变,仍需把选中态收到被点击的那一项\n resyncOnUnchangedValue: clicked => {\n for (const radio of this._getRadios()) {\n radio.checked = radio === clicked\n }\n this._groupController.sync()\n },\n dispatchValueChange: () => {\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n }).make(),\n // 每次成员集合同步后把组值剪到现存成员范围内\n {\n observeAttributes: ['disabled', ...AVAILABILITY_ATTRIBUTES],\n afterSync: () => this._pruneRemovedMembers()\n }\n )\n\n /**\n * 成员被移除后,组值若仍指向它就成了幽灵值(表单照旧提交一个不存在的 option)。\n * 剪枝条件是「曾经出现在成员里、现在消失了」——不能用「不在现存成员里就剪」,\n * 否则 v-if / 异步渲染时先于成员到达的合法组值会被误清。\n */\n private _knownMemberValues = new Set<string>()\n private _availabilityObserver: MutationObserver | null = null\n private _availabilityResizeObserver: ResizeObserver | null = null\n private _availabilityToggleTargets = new Set<Element>()\n private _availabilitySlotTargets = new Set<Element>()\n private _unsubscribeDocumentAvailability: (() => void) | null = null\n private readonly _handleAvailabilityToggle = () => this._groupController.sync()\n private readonly _handleAvailabilitySlotChange = () => {\n this._observeAvailabilityAncestors()\n this._groupController.sync()\n }\n\n private _getComposedAncestors(element: Element): Element[] {\n const ancestors: Element[] = []\n const visited = new Set<Element>()\n let current: Element | null = element\n\n while (current && !visited.has(current)) {\n visited.add(current)\n ancestors.push(current)\n const root = current.getRootNode()\n current = current.assignedSlot ?? current.parentElement ?? (root instanceof ShadowRoot ? root.host : null)\n }\n\n return ancestors\n }\n\n private _pruneRemovedMembers() {\n if (!this._value) return\n const items = this._getRadios()\n if (items.length === 0) return\n const alive = new Set(items.map(item => item.value))\n if (!alive.has(this._value) && this._knownMemberValues.has(this._value)) this.value = ''\n this._knownMemberValues = alive\n }\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._formAssociation.sync()\n this.requestUpdate('value', old)\n }\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formAssociation.isFormDisabled()\n }\n\n private readonly _formAssociation = defineFormAssociation<string>({\n host: this,\n initialize: () => {\n const attributeValue = this.getAttribute('value')\n if (attributeValue !== null) this.value = attributeValue\n },\n getState: () => this._value,\n setState: value => {\n this.value = value\n },\n getFormValue: () => (this.name && this._value ? this._value : null),\n getFormState: () => this._value,\n restoreState: state => {\n if (typeof state === 'string') this.value = state\n },\n syncValidity: () => this._syncValidity()\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n override connectedCallback() {\n this._syncHostSemantics()\n this._observeAvailabilityAncestors()\n this._unsubscribeDocumentAvailability?.()\n this._unsubscribeDocumentAvailability = subscribeToDocumentAvailability(this.ownerDocument, () =>\n this._groupController.sync()\n )\n super.connectedCallback()\n }\n\n override disconnectedCallback() {\n this._availabilityObserver?.disconnect()\n this._availabilityObserver = null\n this._availabilityResizeObserver?.disconnect()\n this._availabilityResizeObserver = null\n this._syncAvailabilityToggleTargets([])\n this._syncAvailabilitySlotTargets([])\n this._unsubscribeDocumentAvailability?.()\n this._unsubscribeDocumentAvailability = null\n super.disconnectedCallback()\n }\n\n override updated() {\n this._syncHostSemantics()\n }\n\n private _syncHostSemantics() {\n this.setAttribute('role', 'radiogroup')\n this.setAttribute('aria-orientation', this.direction)\n this.setAttribute('aria-disabled', String(this._isDisabled))\n this.setAttribute('aria-required', String(this.required))\n }\n\n private _isRadioUnavailable(radio: WebUiRadio) {\n if (isRadioDisabled(radio) || radio.matches(':disabled')) return true\n\n const ancestors = this._getComposedAncestors(radio)\n const isInVisibleSummary = (details: Element) => {\n const summary = [...details.children].find(child => child.localName === 'summary')\n return summary !== undefined && ancestors.includes(summary)\n }\n if (\n ancestors.some(\n element =>\n element.hasAttribute('hidden') ||\n element.hasAttribute('inert') ||\n element.getAttribute('aria-hidden')?.toLowerCase() === 'true' ||\n (element.localName === 'details' && !element.hasAttribute('open') && !isInVisibleSummary(element))\n )\n )\n return true\n\n const view = radio.ownerDocument.defaultView\n if (!view) return false\n const radioVisibility = view.getComputedStyle(radio).visibility\n if (radioVisibility === 'hidden' || radioVisibility === 'collapse') return true\n\n for (const element of ancestors) {\n const style = view.getComputedStyle(element)\n if (style.display === 'none' || style.getPropertyValue('content-visibility') === 'hidden') {\n return true\n }\n }\n return false\n }\n\n private _observeAvailabilityAncestors() {\n this._availabilityObserver?.disconnect()\n this._availabilityObserver = null\n this._availabilityResizeObserver?.disconnect()\n this._availabilityResizeObserver = null\n\n const ancestors = this._getComposedAncestors(this)\n this._syncAvailabilityToggleTargets(ancestors)\n this._syncAvailabilitySlotTargets(ancestors)\n if (ancestors.length === 0) return\n\n this._availabilityObserver = new MutationObserver(records => {\n if (records.some(record => record.attributeName === 'popover' || record.attributeName === 'slot')) {\n this._observeAvailabilityAncestors()\n }\n this._groupController.sync()\n })\n for (const ancestor of ancestors) {\n this._availabilityObserver.observe(ancestor, {\n attributes: true,\n attributeFilter: [...AVAILABILITY_ATTRIBUTES]\n })\n }\n\n if (typeof ResizeObserver !== 'undefined') {\n this._availabilityResizeObserver = new ResizeObserver(() => this._groupController.sync())\n for (const ancestor of ancestors) this._availabilityResizeObserver.observe(ancestor)\n }\n }\n\n private _syncAvailabilityToggleTargets(ancestors: readonly Element[]) {\n for (const target of this._availabilityToggleTargets) {\n target.removeEventListener('toggle', this._handleAvailabilityToggle)\n }\n this._availabilityToggleTargets.clear()\n\n for (const ancestor of ancestors) {\n if (!ancestor.hasAttribute('popover')) continue\n ancestor.addEventListener('toggle', this._handleAvailabilityToggle)\n this._availabilityToggleTargets.add(ancestor)\n }\n }\n\n private _syncAvailabilitySlotTargets(ancestors: readonly Element[]) {\n for (const target of this._availabilitySlotTargets) {\n target.removeEventListener('slotchange', this._handleAvailabilitySlotChange)\n }\n this._availabilitySlotTargets.clear()\n\n for (const ancestor of ancestors) {\n if (ancestor.localName !== 'slot') continue\n ancestor.addEventListener('slotchange', this._handleAvailabilitySlotChange)\n this._availabilitySlotTargets.add(ancestor)\n }\n }\n\n override formDisabledCallback(disabled: boolean) {\n this._formAssociation.setDisabled(disabled)\n this._groupController.sync()\n }\n\n private _syncValidity() {\n const internals = this._formAssociation.getInternals()\n if (!internals || typeof internals.setValidity !== 'function') return\n if (this._isDisabled || !this.required || this._value) {\n internals.setValidity({})\n return\n }\n internals.setValidity({ valueMissing: true }, 'Select an option')\n }\n\n override render() {\n return html`<div class=\"wui-radio-group\"><slot></slot></div>`\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-radio-group': WebUiRadioGroup\n }\n}\n"],"mappings":"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"}
@@ -380,6 +380,7 @@ export declare class WebUiSegmented extends WebUiSegmented_base {
380
380
  private _settleFlight;
381
381
  private _settleRequest;
382
382
  private _settleTimer;
383
+ connectedCallback(): void;
383
384
  disconnectedCallback(): void;
384
385
  private readonly _groupController;
385
386
  get value(): string;
@@ -390,6 +391,7 @@ export declare class WebUiSegmented extends WebUiSegmented_base {
390
391
  private handlePointerDown;
391
392
  private handlePointerUp;
392
393
  private handlePointerLeave;
394
+ private handleKeyDown;
393
395
  private readonly _formAssociation;
394
396
  private readonly _formAssociationController;
395
397
  formDisabledCallback(disabled: boolean): void;
@@ -1,5 +1,5 @@
1
1
  import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
2
- import t from "../../assets/glass.js";
2
+ import t from "../../classes/glass.js";
3
3
  import { installPointerFocusSuppression as n } from "../../shared/focus/pointer-focus.js";
4
4
  import { FormAssociated as r, FormAssociationController as i, defineFormAssociation as a } from "../../shared/form-association/index.js";
5
5
  import { GroupController as o, defineGroupCoordinator as s } from "../../shared/group-management/index.js";
@@ -18,7 +18,13 @@ function S(e) {
18
18
  let t = l(getComputedStyle(e).getPropertyValue("--wui-duration-trigger"));
19
19
  return t === null ? 160 : Math.max(0, t);
20
20
  }
21
- var C = class extends r(m) {
21
+ function C(e, t) {
22
+ if (!t) return;
23
+ let n;
24
+ for (let r of e) if (r.value === t && (n ||= r, r.checked)) return r;
25
+ return n;
26
+ }
27
+ var w = class extends r(m) {
22
28
  constructor(...e) {
23
29
  super(...e), this.name = "", this._variant = "inset", this.disabled = !1, this.required = !1, this._value = "", this._indicatorReady = !1, this._settling = !1, this._pressed = !1, this._isDragging = !1, this._dragGestureHandle = null, this._settleFlight = null, this._settleRequest = 0, this._groupController = new o(this, s({
24
30
  host: this,
@@ -29,13 +35,22 @@ var C = class extends r(m) {
29
35
  },
30
36
  getDisabled: () => this._isDisabled,
31
37
  isItem: (e) => e instanceof HTMLElement && e.matches("web-ui-segmented-trigger"),
32
- isItemSelected: (e, t) => e.value === t,
38
+ isItemSelected: (e, t) => e === C(this.querySelectorAll("web-ui-segmented-trigger"), t),
39
+ isItemTabStop: (e, t) => {
40
+ let n = t.filter((e) => !e.disabled), r = C(t, this._value);
41
+ return e === (r && !r.disabled ? r : n[0]);
42
+ },
43
+ getItemSelected: (e) => e.checked,
33
44
  getNextValue: (e, t) => e.checked ? e.value : t,
34
45
  valuesEqual: (e, t) => e === t,
35
46
  copyValue: (e) => e,
36
47
  setItemSelected: (e, t) => {
37
48
  e.checked = t;
38
49
  },
50
+ resyncOnUnchangedValue: (e) => {
51
+ for (let t of this.querySelectorAll("web-ui-segmented-trigger")) t.checked = t === e;
52
+ this._groupController.sync(), requestAnimationFrame(() => void this._updateIndicator());
53
+ },
39
54
  dispatchValueChange: () => {
40
55
  this.dispatchEvent(new Event("input", {
41
56
  bubbles: !0,
@@ -45,7 +60,10 @@ var C = class extends r(m) {
45
60
  composed: !0
46
61
  }));
47
62
  }
48
- }).make(), { afterSync: () => requestAnimationFrame(() => void this._updateIndicator()) }), this._formAssociation = a({
63
+ }).make(), {
64
+ observeAttributes: ["disabled"],
65
+ afterSync: () => requestAnimationFrame(() => void this._updateIndicator())
66
+ }), this._formAssociation = a({
49
67
  host: this,
50
68
  initialize: () => {
51
69
  let e = this.getAttribute("value");
@@ -72,6 +90,13 @@ var C = class extends r(m) {
72
90
  let t = this._variant;
73
91
  this._variant = c(e, x, "inset"), this.requestUpdate("variant", t);
74
92
  }
93
+ connectedCallback() {
94
+ super.connectedCallback(), customElements.whenDefined("web-ui-segmented-trigger").then(async () => {
95
+ if (!this.isConnected) return;
96
+ let e = [...this.querySelectorAll("web-ui-segmented-trigger")];
97
+ await Promise.all(e.map((e) => e.updateComplete)), this.isConnected && this._groupController.sync();
98
+ });
99
+ }
75
100
  disconnectedCallback() {
76
101
  super.disconnectedCallback(), this._dragGestureHandle?.destroy(), this._dragGestureHandle = null, clearTimeout(this._settleTimer), this._settleTimer = void 0;
77
102
  }
@@ -86,13 +111,12 @@ var C = class extends r(m) {
86
111
  return this.disabled || this._formAssociation.isFormDisabled();
87
112
  }
88
113
  async _updateIndicator() {
89
- let e = this.querySelectorAll("web-ui-segmented-trigger"), t = 0, n = 0;
90
- e.forEach((e) => {
91
- if (e.value === this._value) {
92
- let r = e.getBoundingClientRect(), i = this.getBoundingClientRect();
93
- t = r.left - i.left, n = r.width;
94
- }
95
- }), this._indicatorReady && this._openSettleFlight() && await this.updateComplete, this.style.setProperty("--indicator-left", `${t}px`), this.style.setProperty("--indicator-width", `${n}px`), this._indicatorReady ||= (this.renderRoot.querySelector(".wui-segmented-indicator")?.offsetWidth, !0);
114
+ let e = this.querySelectorAll("web-ui-segmented-trigger"), t = 0, n = 0, r = C(e, this._value);
115
+ if (r) {
116
+ let e = r.getBoundingClientRect(), i = this.getBoundingClientRect();
117
+ t = e.left - i.left, n = e.width;
118
+ }
119
+ this._indicatorReady && this._openSettleFlight() && await this.updateComplete, this.style.setProperty("--indicator-left", `${t}px`), this.style.setProperty("--indicator-width", `${n}px`), this._indicatorReady ||= (this.renderRoot.querySelector(".wui-segmented-indicator")?.offsetWidth, !0);
96
120
  }
97
121
  _openSettleFlight() {
98
122
  let e = this._settleTimer !== void 0, t = {};
@@ -108,7 +132,7 @@ var C = class extends r(m) {
108
132
  if (this._isDisabled) return;
109
133
  let t = [...this.querySelectorAll("web-ui-segmented-trigger")], n = t.filter((e) => !e.disabled);
110
134
  if (n.length === 0) return;
111
- let r = t.find((e) => e.value === this._value);
135
+ let r = C(t, this._value);
112
136
  if (!r || r.disabled) return;
113
137
  let i = r.getBoundingClientRect();
114
138
  if (!(e.clientX >= i.left && e.clientX <= i.right && e.clientY >= i.top && e.clientY <= i.bottom)) return;
@@ -149,7 +173,7 @@ var C = class extends r(m) {
149
173
  let e = f(t, v);
150
174
  e !== -1 && n[e] && (i = n[e]);
151
175
  }
152
- i.value === this._value ? this._updateIndicator() : (this.value = i.value, this._groupController.sync(), this.dispatchEvent(new Event("input", {
176
+ i.value === this._value ? i === r ? this._updateIndicator() : i.shadowRoot?.querySelector("[role=\"option\"]")?.click() : (this.value = i.value, this._groupController.sync(), this.dispatchEvent(new Event("input", {
153
177
  bubbles: !0,
154
178
  composed: !0
155
179
  })), this.dispatchEvent(new Event("change", {
@@ -170,6 +194,37 @@ var C = class extends r(m) {
170
194
  handlePointerLeave() {
171
195
  this._dragGestureHandle?.isDragging() || (this._pressed = !1);
172
196
  }
197
+ handleKeyDown(e) {
198
+ if (this._isDisabled || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
199
+ let t = e.composedPath().find((e) => e instanceof HTMLElement && e.matches("web-ui-segmented-trigger"));
200
+ if (!t) return;
201
+ let n = [...this.querySelectorAll("web-ui-segmented-trigger")], r = n.filter((e) => !e.disabled), i = n.indexOf(t);
202
+ if (i === -1 || r.length === 0) return;
203
+ let a = getComputedStyle(this).direction === "rtl" ? -1 : 1, o = (e) => {
204
+ for (let t = 1; t <= n.length; t += 1) {
205
+ let r = (i + e * t + n.length) % n.length, a = n[r];
206
+ if (a && !a.disabled) return a;
207
+ }
208
+ return t;
209
+ }, s;
210
+ switch (e.key) {
211
+ case "ArrowRight":
212
+ s = o(a);
213
+ break;
214
+ case "ArrowLeft":
215
+ s = o(a === 1 ? -1 : 1);
216
+ break;
217
+ case "Home":
218
+ s = r[0];
219
+ break;
220
+ case "End":
221
+ s = r[r.length - 1];
222
+ break;
223
+ default: return;
224
+ }
225
+ let c = s.shadowRoot?.querySelector("[role=\"option\"]");
226
+ c && (e.preventDefault(), c.focus(), (s !== t || !s.checked) && c.click());
227
+ }
173
228
  formDisabledCallback(e) {
174
229
  this._formAssociation.setDisabled(e), this._groupController.sync();
175
230
  }
@@ -187,6 +242,7 @@ var C = class extends r(m) {
187
242
  })}
188
243
  role="listbox"
189
244
  aria-orientation="horizontal"
245
+ @keydown=${this.handleKeyDown}
190
246
  @pointerdown=${this.handlePointerDown}
191
247
  @pointerup=${this.handlePointerUp}
192
248
  @pointercancel=${this.handlePointerUp}
@@ -201,17 +257,17 @@ var C = class extends r(m) {
201
257
  e([v({
202
258
  type: String,
203
259
  reflect: !0
204
- })], C.prototype, "name", void 0), e([v({
260
+ })], w.prototype, "name", void 0), e([v({
205
261
  type: String,
206
262
  reflect: !0
207
- })], C.prototype, "variant", null), e([v({
263
+ })], w.prototype, "variant", null), e([v({
208
264
  type: Boolean,
209
265
  reflect: !0
210
- })], C.prototype, "disabled", void 0), e([v({
266
+ })], w.prototype, "disabled", void 0), e([v({
211
267
  type: Boolean,
212
268
  reflect: !0
213
- })], C.prototype, "required", void 0), e([y()], C.prototype, "_value", void 0), e([y()], C.prototype, "_indicatorReady", void 0), e([y()], C.prototype, "_settling", void 0), e([y()], C.prototype, "_pressed", void 0), e([y()], C.prototype, "_isDragging", void 0), C = e([_("web-ui-segmented")], C);
269
+ })], w.prototype, "required", void 0), e([y()], w.prototype, "_value", void 0), e([y()], w.prototype, "_indicatorReady", void 0), e([y()], w.prototype, "_settling", void 0), e([y()], w.prototype, "_pressed", void 0), e([y()], w.prototype, "_isDragging", void 0), w = e([_("web-ui-segmented")], w);
214
270
  //#endregion
215
- export { C as WebUiSegmented };
271
+ export { w as WebUiSegmented };
216
272
 
217
273
  //# sourceMappingURL=index.js.map