@nldd/design-system 0.8.88 → 0.8.90

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 (108) hide show
  1. package/README.md +4 -4
  2. package/custom-elements.json +303 -64
  3. package/dist/components/components.js +897 -201
  4. package/dist/components/content/image/image.d.ts +23 -3
  5. package/dist/components/content/image/image.d.ts.map +1 -1
  6. package/dist/components/content/image/image.js +74 -17
  7. package/dist/components/content/image/image.js.map +1 -1
  8. package/dist/components/content/image/image.template.js +1 -1
  9. package/dist/components/content/image/image.template.js.map +1 -1
  10. package/dist/components/{dist-LX8LuMac.js → dist-BLaE_n_F.js} +1 -1
  11. package/dist/components/{dist-CX3DK4i7.js → dist-BeymuiGt.js} +3 -3
  12. package/dist/components/{dist-CbCO0WCd.js → dist-CENYEz7C.js} +1 -1
  13. package/dist/components/{dist-B_Mnmrj4.js → dist-CYLM5ciE.js} +1 -1
  14. package/dist/components/{dist-fIxe0l7k.js → dist-DHA-0RyT.js} +91 -34
  15. package/dist/components/{dist-CgDuh26K.js → dist-D_ckX1sK.js} +1 -1
  16. package/dist/components/{dist-eVFegyjM.js → dist-Dh_b9r4M.js} +1 -1
  17. package/dist/components/{dist-DXZ-cFAl.js → dist-DkZlotgT.js} +2 -2
  18. package/dist/components/{dist-CSrO_mYe.js → dist-TCqV9dho.js} +1 -1
  19. package/dist/components/{dist-ByH8hQze.js → dist-Y54Lma86.js} +2 -2
  20. package/dist/components/{dist-CRwuSgMM.js → dist-yyE8P2O6.js} +2 -2
  21. package/dist/components/inputs/radio-button/radio-button.d.ts +58 -18
  22. package/dist/components/inputs/radio-button/radio-button.d.ts.map +1 -1
  23. package/dist/components/inputs/radio-button/radio-button.js +136 -29
  24. package/dist/components/inputs/radio-button/radio-button.js.map +1 -1
  25. package/dist/components/inputs/radio-button/radio-button.styles.d.ts.map +1 -1
  26. package/dist/components/inputs/radio-button/radio-button.styles.js +17 -23
  27. package/dist/components/inputs/radio-button/radio-button.styles.js.map +1 -1
  28. package/dist/components/inputs/radio-button/radio-button.template.d.ts.map +1 -1
  29. package/dist/components/inputs/radio-button/radio-button.template.js +13 -10
  30. package/dist/components/inputs/radio-button/radio-button.template.js.map +1 -1
  31. package/dist/components/inputs/radio-button-field/radio-button-field.d.ts +65 -18
  32. package/dist/components/inputs/radio-button-field/radio-button-field.d.ts.map +1 -1
  33. package/dist/components/inputs/radio-button-field/radio-button-field.js +151 -29
  34. package/dist/components/inputs/radio-button-field/radio-button-field.js.map +1 -1
  35. package/dist/components/inputs/radio-button-field/radio-button-field.styles.d.ts.map +1 -1
  36. package/dist/components/inputs/radio-button-field/radio-button-field.styles.js +17 -0
  37. package/dist/components/inputs/radio-button-field/radio-button-field.styles.js.map +1 -1
  38. package/dist/components/inputs/radio-button-field/radio-button-field.template.d.ts.map +1 -1
  39. package/dist/components/inputs/radio-button-field/radio-button-field.template.js +21 -12
  40. package/dist/components/inputs/radio-button-field/radio-button-field.template.js.map +1 -1
  41. package/dist/components/inputs/radio-button-group/radio-button-group.d.ts +3 -0
  42. package/dist/components/inputs/radio-button-group/radio-button-group.d.ts.map +1 -1
  43. package/dist/components/inputs/radio-button-group/radio-button-group.js +16 -4
  44. package/dist/components/inputs/radio-button-group/radio-button-group.js.map +1 -1
  45. package/dist/components/inputs/segmented-control/segmented-control.d.ts +46 -13
  46. package/dist/components/inputs/segmented-control/segmented-control.d.ts.map +1 -1
  47. package/dist/components/inputs/segmented-control/segmented-control.js +145 -16
  48. package/dist/components/inputs/segmented-control/segmented-control.js.map +1 -1
  49. package/dist/components/inputs/segmented-control/segmented-control.styles.d.ts.map +1 -1
  50. package/dist/components/inputs/segmented-control/segmented-control.styles.js +16 -0
  51. package/dist/components/inputs/segmented-control/segmented-control.styles.js.map +1 -1
  52. package/dist/components/inputs/segmented-control/segmented-control.template.d.ts.map +1 -1
  53. package/dist/components/inputs/segmented-control/segmented-control.template.js +47 -24
  54. package/dist/components/inputs/segmented-control/segmented-control.template.js.map +1 -1
  55. package/dist/components/inputs/text-editor/text-editor.cursor.d.ts.map +1 -1
  56. package/dist/components/inputs/text-editor/text-editor.cursor.js +14 -1
  57. package/dist/components/inputs/text-editor/text-editor.cursor.js.map +1 -1
  58. package/dist/components/inputs/text-editor/text-editor.mentions.d.ts.map +1 -1
  59. package/dist/components/inputs/text-editor/text-editor.mentions.js +3 -1
  60. package/dist/components/inputs/text-editor/text-editor.mentions.js.map +1 -1
  61. package/dist/components/inputs/toggle-button/toggle-button.d.ts +36 -2
  62. package/dist/components/inputs/toggle-button/toggle-button.d.ts.map +1 -1
  63. package/dist/components/inputs/toggle-button/toggle-button.js +116 -3
  64. package/dist/components/inputs/toggle-button/toggle-button.js.map +1 -1
  65. package/dist/components/inputs/toggle-button/toggle-button.styles.d.ts.map +1 -1
  66. package/dist/components/inputs/toggle-button/toggle-button.styles.js +17 -1
  67. package/dist/components/inputs/toggle-button/toggle-button.styles.js.map +1 -1
  68. package/dist/components/inputs/toggle-button/toggle-button.template.d.ts.map +1 -1
  69. package/dist/components/inputs/toggle-button/toggle-button.template.js +25 -2
  70. package/dist/components/inputs/toggle-button/toggle-button.template.js.map +1 -1
  71. package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts +4 -0
  72. package/dist/components/inputs/toggle-button-group/toggle-button-group.d.ts.map +1 -1
  73. package/dist/components/inputs/toggle-button-group/toggle-button-group.js +21 -2
  74. package/dist/components/inputs/toggle-button-group/toggle-button-group.js.map +1 -1
  75. package/dist/components/lists-and-tables/list/list.d.ts +1 -1
  76. package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
  77. package/dist/components/lists-and-tables/list/list.js +4 -3
  78. package/dist/components/lists-and-tables/list/list.js.map +1 -1
  79. package/dist/components/lists-and-tables/list/list.template.d.ts.map +1 -1
  80. package/dist/components/lists-and-tables/list/list.template.js +15 -10
  81. package/dist/components/lists-and-tables/list/list.template.js.map +1 -1
  82. package/dist/components/status-and-feedback/notification/notification-region.d.ts +4 -0
  83. package/dist/components/status-and-feedback/notification/notification-region.d.ts.map +1 -1
  84. package/dist/components/status-and-feedback/notification/notification-region.js +99 -30
  85. package/dist/components/status-and-feedback/notification/notification-region.js.map +1 -1
  86. package/dist/components/status-and-feedback/notification/notification.d.ts +7 -1
  87. package/dist/components/status-and-feedback/notification/notification.d.ts.map +1 -1
  88. package/dist/components/status-and-feedback/notification/notification.js +21 -1
  89. package/dist/components/status-and-feedback/notification/notification.js.map +1 -1
  90. package/dist/components/status-and-feedback/notification/notification.styles.d.ts.map +1 -1
  91. package/dist/components/status-and-feedback/notification/notification.styles.js +6 -0
  92. package/dist/components/status-and-feedback/notification/notification.styles.js.map +1 -1
  93. package/dist/css/variables.css +2 -2
  94. package/dist/nldd.min.js +618 -540
  95. package/dist/types/vue.d.ts +22 -18
  96. package/dist/utilities/described-by-mixin.d.ts +2 -2
  97. package/dist/utilities/described-by-mixin.d.ts.map +1 -1
  98. package/dist/utilities/described-by-mixin.js +11 -6
  99. package/dist/utilities/described-by-mixin.js.map +1 -1
  100. package/dist/utilities/radio-grouping.d.ts +66 -0
  101. package/dist/utilities/radio-grouping.d.ts.map +1 -0
  102. package/dist/utilities/radio-grouping.js +133 -0
  103. package/dist/utilities/radio-grouping.js.map +1 -0
  104. package/dist/utilities/radio-position.d.ts +20 -0
  105. package/dist/utilities/radio-position.d.ts.map +1 -0
  106. package/dist/utilities/radio-position.js +11 -0
  107. package/dist/utilities/radio-position.js.map +1 -0
  108. package/package.json +10 -10
@@ -1,4 +1,4 @@
1
- import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, W as EditorView, ct as EditorSelection, n as ExternalTokenizer, p as bracketMatchingHandle, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, y as foldNodeProp } from "./dist-fIxe0l7k.js";
1
+ import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, W as EditorView, ct as EditorSelection, n as ExternalTokenizer, p as bracketMatchingHandle, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, y as foldNodeProp } from "./dist-DHA-0RyT.js";
2
2
  //#region node_modules/@lezer/xml/dist/index.js
3
3
  var StartTag = 1;
4
4
  var StartCloseTag = 2;
@@ -1,5 +1,5 @@
1
- import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, m as continuedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, u as LanguageSupport, y as foldNodeProp } from "./dist-fIxe0l7k.js";
2
- import { a as ifNotIn, r as completeFromList } from "./dist-CgDuh26K.js";
1
+ import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, m as continuedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, u as LanguageSupport, y as foldNodeProp } from "./dist-DHA-0RyT.js";
2
+ import { a as ifNotIn, r as completeFromList } from "./dist-D_ckX1sK.js";
3
3
  //#region node_modules/@codemirror/lang-sql/dist/index.js
4
4
  var whitespace = 36;
5
5
  var LineComment = 1;
@@ -1,4 +1,4 @@
1
- import { C as indentNodeProp, M as styleTags, N as tags, g as delimitedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, v as foldInside, y as foldNodeProp } from "./dist-fIxe0l7k.js";
1
+ import { C as indentNodeProp, M as styleTags, N as tags, g as delimitedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, v as foldInside, y as foldNodeProp } from "./dist-DHA-0RyT.js";
2
2
  //#region node_modules/@lezer/yaml/dist/index.js
3
3
  var blockEnd = 63;
4
4
  var eof = 64;
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, O as sublanguageProp, P as IterMode, R as NodeWeakMap, W as EditorView, _ as flatIndent, ct as EditorSelection, g as delimitedIndent, h as defineLanguageFacet, i as LocalTokenGroup, m as continuedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, v as foldInside, y as foldNodeProp } from "./dist-fIxe0l7k.js";
3
- import { a as ifNotIn, o as snippetCompletion, r as completeFromList } from "./dist-CgDuh26K.js";
2
+ import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, O as sublanguageProp, P as IterMode, R as NodeWeakMap, W as EditorView, _ as flatIndent, ct as EditorSelection, g as delimitedIndent, h as defineLanguageFacet, i as LocalTokenGroup, m as continuedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, v as foldInside, y as foldNodeProp } from "./dist-DHA-0RyT.js";
3
+ import { a as ifNotIn, o as snippetCompletion, r as completeFromList } from "./dist-D_ckX1sK.js";
4
4
  //#region node_modules/@lezer/javascript/dist/index.js
5
5
  var noSemi = 316;
6
6
  var noSemiType = 317;
@@ -1,5 +1,5 @@
1
- import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, P as IterMode, R as NodeWeakMap, g as delimitedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, v as foldInside, y as foldNodeProp } from "./dist-fIxe0l7k.js";
2
- import { a as ifNotIn, o as snippetCompletion, r as completeFromList } from "./dist-CgDuh26K.js";
1
+ import { A as syntaxTree, C as indentNodeProp, M as styleTags, N as tags, P as IterMode, R as NodeWeakMap, g as delimitedIndent, n as ExternalTokenizer, r as LRParser, s as LRLanguage, t as ContextTracker, u as LanguageSupport, v as foldInside, y as foldNodeProp } from "./dist-DHA-0RyT.js";
2
+ import { a as ifNotIn, o as snippetCompletion, r as completeFromList } from "./dist-D_ckX1sK.js";
3
3
  //#region node_modules/@lezer/python/dist/index.js
4
4
  var printKeyword = 1;
5
5
  var indent = 194;
@@ -1,34 +1,46 @@
1
1
  /**
2
2
  * Nederlandse Digitale Dienst Radio Button Component (Lit + TypeScript)
3
3
  *
4
- * WAI-ARIA: Wrap radio buttons in a <fieldset>/<legend> or a container with
5
- * role="radiogroup" and aria-labelledby for proper group semantics.
4
+ * WAI-ARIA: put the buttons of one group in a container with
5
+ * role="radiogroup" and a name of its own. A screen reader counts the options
6
+ * from that container, so a bare <fieldset> (which is a group, not a
7
+ * radiogroup) leaves them uncounted. nldd-radio-button-group does this for you.
8
+ *
9
+ * Radio buttons with the same name, in the same form and the same tree, form
10
+ * one group the way native radios do: checking one unchecks the others, the
11
+ * arrow keys move between them, Tab stops at the group once, and a screen
12
+ * reader hears each one's place in it. The element itself is the radio, because
13
+ * an input per shadow root would leave every button a group of one.
14
+ *
15
+ * The shape is all this component draws. A radio with a label beside it is
16
+ * nldd-radio-button-field.
6
17
  *
7
18
  * @example
8
- * <fieldset>
9
- * <legend>Kies een optie</legend>
10
- * <nldd-radio-button name="options" value="1">Optie 1</nldd-radio-button>
11
- * <nldd-radio-button name="options" value="2">Optie 2</nldd-radio-button>
19
+ * <fieldset role="radiogroup" aria-labelledby="options-label">
20
+ * <legend id="options-label">Kies een optie</legend>
21
+ * <nldd-radio-button name="options" value="1" accessible-label="Optie 1"></nldd-radio-button>
22
+ * <nldd-radio-button name="options" value="2" accessible-label="Optie 2"></nldd-radio-button>
12
23
  * </fieldset>
13
24
  *
14
25
  * @element nldd-radio-button
15
26
  * @attr {boolean} checked - Checked state
16
27
  * @attr {boolean} disabled - Disabled state
17
28
  * @attr {boolean} no-tab - Takes the control out of the tab order (tabindex="-1"), for a control owned by a roving container (a row of an nldd-list, where the arrow keys move between rows) that manages focus itself. Still mouse- and script-focusable.
18
- * @attr {boolean} decorative - Renders the shape without the input: no focus, no
29
+ * @attr {boolean} decorative - Renders the shape only: no role, no focus, no
19
30
  * name/value, nothing announced. For a control that owns the state elsewhere,
20
- * such as a list row that is itself the radio; putting a real input in there
21
- * would nest a control inside a control.
22
- * @attr {boolean} required - Required state
31
+ * such as a list row or an nldd-radio-button-field that is itself the radio;
32
+ * putting a second radio in there would nest a control inside a control.
33
+ * @attr {boolean} required - Required state. What it asks is whether anything in the group is checked, as a native radio does.
34
+ * @attr {boolean} focus-ring - Draws the focus ring around the shape. Set by nldd-radio-button-field, which is the radio itself and holds the focus. Not part of the public API.
23
35
  * @attr {string} name - Radio group name for form submission; ties the buttons of one group together
24
36
  * @attr {string} value - Value submitted with the form when this radio button is checked
25
- * @attr {string} accessible-label - Accessible label forwarded as aria-label to the native input.
37
+ * @attr {string} accessible-label - Accessible label, set as aria-label on this element: it is the radio.
26
38
  * @attr {boolean} invalid - Marks the control as invalid. Announced with aria-invalid; nothing is drawn for it.
27
39
  * Note: aria-labelledby is not supported as IDREF resolution cannot cross shadow DOM boundaries.
28
40
  *
29
41
  * @fires change - When checked state changes; detail: { checked: boolean, value: string, name: string }
30
42
  */
31
- import { LitElement } from 'lit';
43
+ import { LitElement, type PropertyValues } from 'lit';
32
44
  import { type FormValue } from '../../../utilities/form-associated-mixin.js';
33
45
  declare const NLDDRadioButton_base: typeof LitElement & (abstract new (...args: any[]) => LitElement & import("../../../utilities/form-associated-mixin.js").FormAssociatedElement) & (abstract new (...args: any[]) => import("../../../utilities/described-by-mixin.js").DescribedElement);
34
46
  export declare class NLDDRadioButton extends NLDDRadioButton_base {
@@ -46,6 +58,9 @@ export declare class NLDDRadioButton extends NLDDRadioButton_base {
46
58
  * script-focusable. */
47
59
  noTab: boolean;
48
60
  required: boolean;
61
+ /** Set by nldd-radio-button-field. Not part of the public API: that field is
62
+ * the radio and holds the focus, while the shape it rings is drawn here. */
63
+ focusRing: boolean;
49
64
  name: string;
50
65
  value: string;
51
66
  accessibleLabel: string;
@@ -59,17 +74,42 @@ export declare class NLDDRadioButton extends NLDDRadioButton_base {
59
74
  * choosing not to show something is not a reason to keep quiet about it.
60
75
  */
61
76
  invalid: boolean;
77
+ /** Its place among the radio buttons that share its name, and whether any of
78
+ * them is checked. */
79
+ private _grouping;
80
+ /** The aria-label this radio wrote on itself, so it only takes back its own. */
81
+ private _appliedLabel;
82
+ /** Whether anything in its group is checked, which is what `required` asks
83
+ * of a radio: one of these, not this one. */
84
+ get _groupHasSelection(): boolean;
85
+ connectedCallback(): void;
86
+ disconnectedCallback(): void;
62
87
  firstUpdated(): void;
88
+ /** Counting happens before the render, not after it: the place this radio is
89
+ * given decides what `updated()` writes on it, and a count from there would
90
+ * ask for a second render of what was just drawn. */
91
+ willUpdate(changed: PropertyValues<this>): void;
92
+ updated(changed: PropertyValues<this>): void;
93
+ /**
94
+ * This element is the radio.
95
+ *
96
+ * A native `<input type="radio">` groups with the radios of the same name in
97
+ * its own tree, and one per shadow root leaves every radio a group of one: a
98
+ * screen reader announces "1 of 1" and Tab stops at each of them. The role
99
+ * on the element itself puts every radio of a group in one tree again, where
100
+ * the browser counts them together.
101
+ */
102
+ private _syncHostAria;
103
+ /** The element assistive software meets is this one, so the description and
104
+ * the invalid state belong here rather than on something inside. */
105
+ describedTarget(): Element | null;
63
106
  formValue(): FormValue;
64
107
  formResetCallback(): void;
65
108
  formStateRestoreCallback(state: File | string | FormData | null): void;
109
+ /** Checks this radio, the way a click or the space bar does. */
66
110
  select(): void;
67
- _handleChange(e: Event): void;
68
- /**
69
- * Delegates focus to the inner native radio `<input>`, so consumers can
70
- * call `radioEl.focus()` without reaching into shadow DOM.
71
- */
72
- focus(options?: FocusOptions): void;
111
+ private _onClick;
112
+ private _onKeyDown;
73
113
  render(): import("lit-html").TemplateResult;
74
114
  }
75
115
  declare global {
@@ -1 +1 @@
1
- {"version":3,"file":"radio-button.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEjC,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,6CAA6C,CAAC;;AAM7F,qBACa,eAAgB,SAAQ,oBAAuC;IAE3E,OAAgB,MAAM,0BAAqB;IAE3C;wEACoE;IACpE,MAAM,CAAC,WAAW,UAAQ;IAG1B,OAAO,CAAC,eAAe,CAAS;IAGhC,OAAO,UAAS;IAGhB,UAAU,UAAS;IAGnB,QAAQ,UAAS;IACjB;;;4BAGwB;IAExB,KAAK,UAAS;IAId,QAAQ,UAAS;IAGjB,IAAI,SAAM;IAGV,KAAK,SAAM;IAGX,eAAe,SAAM;IAGrB;;;;;;;;OAQG;IAEH,OAAO,UAAS;IAEP,YAAY,IAAI,IAAI;IAKpB,SAAS,IAAI,SAAS;IAI/B,iBAAiB,IAAI,IAAI;IAKzB,wBAAwB,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI;IAI/D,MAAM,IAAI,IAAI;IAQd,aAAa,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAWpC;;;OAGG;IACM,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAInC,MAAM;CAGf;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,eAAe,CAAC;KACrC;CACD"}
1
+ {"version":3,"file":"radio-button.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAEtD,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,6CAA6C,CAAC;;AAS7F,qBACa,eAAgB,SAAQ,oBAAuC;IAE3E,OAAgB,MAAM,0BAAqB;IAE3C;wEACoE;IACpE,MAAM,CAAC,WAAW,UAAQ;IAG1B,OAAO,CAAC,eAAe,CAAS;IAGhC,OAAO,UAAS;IAGhB,UAAU,UAAS;IAGnB,QAAQ,UAAS;IACjB;;;4BAGwB;IAExB,KAAK,UAAS;IAId,QAAQ,UAAS;IAEjB;iFAC6E;IAE7E,SAAS,UAAS;IAGlB,IAAI,SAAM;IAGV,KAAK,SAAM;IAGX,eAAe,SAAM;IAGrB;;;;;;;;OAQG;IAEH,OAAO,UAAS;IAEhB;2BACuB;IACvB,OAAO,CAAC,SAAS,CAA2B;IAE5C,gFAAgF;IAChF,OAAO,CAAC,aAAa,CAAuB;IAE5C;kDAC8C;IAC9C,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAEQ,iBAAiB,IAAI,IAAI;IAMzB,oBAAoB,IAAI,IAAI;IAM5B,YAAY,IAAI,IAAI;IAI7B;;0DAEsD;IAC7C,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAM/C,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAKrD;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IA0BrB;yEACqE;IAC5D,eAAe,IAAI,OAAO,GAAG,IAAI;IAKjC,SAAS,IAAI,SAAS;IAI/B,iBAAiB,IAAI,IAAI;IAKzB,wBAAwB,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI;IAItE,gEAAgE;IACzD,MAAM,IAAI,IAAI;IAYrB,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAiBhB;IAEO,MAAM;CAGf;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,qBAAqB;QAC9B,mBAAmB,EAAE,eAAe,CAAC;KACrC;CACD"}
@@ -7,28 +7,40 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  /**
8
8
  * Nederlandse Digitale Dienst Radio Button Component (Lit + TypeScript)
9
9
  *
10
- * WAI-ARIA: Wrap radio buttons in a <fieldset>/<legend> or a container with
11
- * role="radiogroup" and aria-labelledby for proper group semantics.
10
+ * WAI-ARIA: put the buttons of one group in a container with
11
+ * role="radiogroup" and a name of its own. A screen reader counts the options
12
+ * from that container, so a bare <fieldset> (which is a group, not a
13
+ * radiogroup) leaves them uncounted. nldd-radio-button-group does this for you.
14
+ *
15
+ * Radio buttons with the same name, in the same form and the same tree, form
16
+ * one group the way native radios do: checking one unchecks the others, the
17
+ * arrow keys move between them, Tab stops at the group once, and a screen
18
+ * reader hears each one's place in it. The element itself is the radio, because
19
+ * an input per shadow root would leave every button a group of one.
20
+ *
21
+ * The shape is all this component draws. A radio with a label beside it is
22
+ * nldd-radio-button-field.
12
23
  *
13
24
  * @example
14
- * <fieldset>
15
- * <legend>Kies een optie</legend>
16
- * <nldd-radio-button name="options" value="1">Optie 1</nldd-radio-button>
17
- * <nldd-radio-button name="options" value="2">Optie 2</nldd-radio-button>
25
+ * <fieldset role="radiogroup" aria-labelledby="options-label">
26
+ * <legend id="options-label">Kies een optie</legend>
27
+ * <nldd-radio-button name="options" value="1" accessible-label="Optie 1"></nldd-radio-button>
28
+ * <nldd-radio-button name="options" value="2" accessible-label="Optie 2"></nldd-radio-button>
18
29
  * </fieldset>
19
30
  *
20
31
  * @element nldd-radio-button
21
32
  * @attr {boolean} checked - Checked state
22
33
  * @attr {boolean} disabled - Disabled state
23
34
  * @attr {boolean} no-tab - Takes the control out of the tab order (tabindex="-1"), for a control owned by a roving container (a row of an nldd-list, where the arrow keys move between rows) that manages focus itself. Still mouse- and script-focusable.
24
- * @attr {boolean} decorative - Renders the shape without the input: no focus, no
35
+ * @attr {boolean} decorative - Renders the shape only: no role, no focus, no
25
36
  * name/value, nothing announced. For a control that owns the state elsewhere,
26
- * such as a list row that is itself the radio; putting a real input in there
27
- * would nest a control inside a control.
28
- * @attr {boolean} required - Required state
37
+ * such as a list row or an nldd-radio-button-field that is itself the radio;
38
+ * putting a second radio in there would nest a control inside a control.
39
+ * @attr {boolean} required - Required state. What it asks is whether anything in the group is checked, as a native radio does.
40
+ * @attr {boolean} focus-ring - Draws the focus ring around the shape. Set by nldd-radio-button-field, which is the radio itself and holds the focus. Not part of the public API.
29
41
  * @attr {string} name - Radio group name for form submission; ties the buttons of one group together
30
42
  * @attr {string} value - Value submitted with the form when this radio button is checked
31
- * @attr {string} accessible-label - Accessible label forwarded as aria-label to the native input.
43
+ * @attr {string} accessible-label - Accessible label, set as aria-label on this element: it is the radio.
32
44
  * @attr {boolean} invalid - Marks the control as invalid. Announced with aria-invalid; nothing is drawn for it.
33
45
  * Note: aria-labelledby is not supported as IDREF resolution cannot cross shadow DOM boundaries.
34
46
  *
@@ -41,6 +53,9 @@ import { radioButtonStyles } from './radio-button.styles.js';
41
53
  import { radioButtonTemplate } from './radio-button.template.js';
42
54
  import { DescribedBy } from '../../../utilities/described-by-mixin.js';
43
55
  import { reflectNonDefault } from '../../../utilities/reflect-non-default.js';
56
+ import { RadioGrouping } from '../../../utilities/radio-grouping.js';
57
+ import { setOwnedAttribute } from '../../../utilities/owned-attribute.js';
58
+ import { submitOnEnter } from '../../../utilities/implicit-submission.js';
44
59
  let NLDDRadioButton = class NLDDRadioButton extends DescribedBy(FormAssociated(LitElement)) {
45
60
  constructor() {
46
61
  super(...arguments);
@@ -54,6 +69,9 @@ let NLDDRadioButton = class NLDDRadioButton extends DescribedBy(FormAssociated(L
54
69
  * script-focusable. */
55
70
  this.noTab = false;
56
71
  this.required = false;
72
+ /** Set by nldd-radio-button-field. Not part of the public API: that field is
73
+ * the radio and holds the focus, while the shape it rings is drawn here. */
74
+ this.focusRing = false;
57
75
  this.name = '';
58
76
  this.value = '';
59
77
  this.accessibleLabel = '';
@@ -67,10 +85,109 @@ let NLDDRadioButton = class NLDDRadioButton extends DescribedBy(FormAssociated(L
67
85
  * choosing not to show something is not a reason to keep quiet about it.
68
86
  */
69
87
  this.invalid = false;
88
+ /** Its place among the radio buttons that share its name, and whether any of
89
+ * them is checked. */
90
+ this._grouping = new RadioGrouping(this);
91
+ /** The aria-label this radio wrote on itself, so it only takes back its own. */
92
+ this._appliedLabel = null;
93
+ this._onClick = () => {
94
+ this.select();
95
+ };
96
+ this._onKeyDown = (e) => {
97
+ if (this.disabled || this.decorative)
98
+ return;
99
+ // The keys a native radio answers to. Space checks it, Enter submits the
100
+ // form it belongs to, and the arrow keys move through the group.
101
+ if (e.key === ' ') {
102
+ e.preventDefault();
103
+ this.select();
104
+ return;
105
+ }
106
+ if (e.key === 'Enter') {
107
+ submitOnEnter(this, e);
108
+ return;
109
+ }
110
+ // The arrow keys move through the group and check what they land on, as
111
+ // with native radios. Not when a roving container manages focus itself:
112
+ // it set no-tab and owns the keys.
113
+ if (!this.noTab)
114
+ this._grouping.moveWithArrow(e);
115
+ };
116
+ }
117
+ /** Whether anything in its group is checked, which is what `required` asks
118
+ * of a radio: one of these, not this one. */
119
+ get _groupHasSelection() {
120
+ return this._grouping.answered;
121
+ }
122
+ connectedCallback() {
123
+ super.connectedCallback();
124
+ this.addEventListener('click', this._onClick);
125
+ this.addEventListener('keydown', this._onKeyDown);
126
+ }
127
+ disconnectedCallback() {
128
+ super.disconnectedCallback();
129
+ this.removeEventListener('click', this._onClick);
130
+ this.removeEventListener('keydown', this._onKeyDown);
70
131
  }
71
132
  firstUpdated() {
72
133
  this._initialChecked = this.checked;
73
134
  }
135
+ /** Counting happens before the render, not after it: the place this radio is
136
+ * given decides what `updated()` writes on it, and a count from there would
137
+ * ask for a second render of what was just drawn. */
138
+ willUpdate(changed) {
139
+ if (changed.has('checked') && this.checked)
140
+ this._grouping.uncheckOthers();
141
+ if (changed.has('name') || changed.has('decorative'))
142
+ this._grouping.regroup();
143
+ else if (changed.has('checked') || changed.has('disabled'))
144
+ this._grouping.refresh();
145
+ }
146
+ updated(changed) {
147
+ super.updated(changed);
148
+ this._syncHostAria();
149
+ }
150
+ /**
151
+ * This element is the radio.
152
+ *
153
+ * A native `<input type="radio">` groups with the radios of the same name in
154
+ * its own tree, and one per shadow root leaves every radio a group of one: a
155
+ * screen reader announces "1 of 1" and Tab stops at each of them. The role
156
+ * on the element itself puts every radio of a group in one tree again, where
157
+ * the browser counts them together.
158
+ */
159
+ _syncHostAria() {
160
+ if (this.decorative) {
161
+ for (const name of ['role', 'aria-checked', 'aria-disabled', 'aria-posinset', 'aria-setsize', 'tabindex']) {
162
+ this.removeAttribute(name);
163
+ }
164
+ return;
165
+ }
166
+ this.setAttribute('role', 'radio');
167
+ this.setAttribute('aria-checked', String(this.checked));
168
+ this._appliedLabel = setOwnedAttribute(this, 'aria-label', this.accessibleLabel, this._appliedLabel);
169
+ if (this.disabled)
170
+ this.setAttribute('aria-disabled', 'true');
171
+ else
172
+ this.removeAttribute('aria-disabled');
173
+ const position = this._grouping.position;
174
+ if (position) {
175
+ this.setAttribute('aria-posinset', String(position.posInSet));
176
+ this.setAttribute('aria-setsize', String(position.setSize));
177
+ }
178
+ else {
179
+ this.removeAttribute('aria-posinset');
180
+ this.removeAttribute('aria-setsize');
181
+ }
182
+ // A disabled radio is not in the tab order, as a native one is not.
183
+ const tabbable = !this.disabled && !this.noTab && position?.tabbable !== false;
184
+ this.setAttribute('tabindex', tabbable ? '0' : '-1');
185
+ }
186
+ /** The element assistive software meets is this one, so the description and
187
+ * the invalid state belong here rather than on something inside. */
188
+ describedTarget() {
189
+ return this;
190
+ }
74
191
  formValue() {
75
192
  return this.checked ? this.value : null;
76
193
  }
@@ -80,32 +197,19 @@ let NLDDRadioButton = class NLDDRadioButton extends DescribedBy(FormAssociated(L
80
197
  formStateRestoreCallback(state) {
81
198
  this.checked = state !== null;
82
199
  }
200
+ /** Checks this radio, the way a click or the space bar does. */
83
201
  select() {
84
- if (this.disabled || this.checked)
202
+ if (this.disabled || this.decorative || this.checked)
85
203
  return;
86
- const input = this.shadowRoot?.querySelector('input');
87
- if (!input)
88
- return;
89
- input.checked = true;
90
- input.dispatchEvent(new Event('change', { bubbles: true }));
91
- }
92
- _handleChange(e) {
93
- const input = e.target;
94
- this.checked = input.checked;
204
+ this.checked = true;
95
205
  this.commitFormValue();
206
+ this._grouping.uncheckOthers();
96
207
  this.dispatchEvent(new CustomEvent('change', {
97
- detail: { checked: this.checked, value: this.value, name: this.name },
208
+ detail: { checked: true, value: this.value, name: this.name },
98
209
  bubbles: true,
99
210
  composed: true,
100
211
  }));
101
212
  }
102
- /**
103
- * Delegates focus to the inner native radio `<input>`, so consumers can
104
- * call `radioEl.focus()` without reaching into shadow DOM.
105
- */
106
- focus(options) {
107
- this.shadowRoot?.querySelector('.radio-button__input')?.focus(options);
108
- }
109
213
  render() {
110
214
  return radioButtonTemplate(this);
111
215
  }
@@ -129,6 +233,9 @@ __decorate([
129
233
  __decorate([
130
234
  property({ type: Boolean, reflect: true })
131
235
  ], NLDDRadioButton.prototype, "required", void 0);
236
+ __decorate([
237
+ property({ type: Boolean, reflect: true, attribute: 'focus-ring' })
238
+ ], NLDDRadioButton.prototype, "focusRing", void 0);
132
239
  __decorate([
133
240
  property({ reflect: true, converter: reflectNonDefault('') })
134
241
  ], NLDDRadioButton.prototype, "name", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"radio-button.js","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"radio-button.js","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"radio-button.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,yBAoH7B,CAAC"}
1
+ {"version":3,"file":"radio-button.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,yBA8G7B,CAAC"}
@@ -26,12 +26,12 @@ export const radioButtonStyles = css `
26
26
 
27
27
  /* # Elements */
28
28
 
29
- .radio-button__input {
29
+ .radio-button__validation-input {
30
30
  position: absolute;
31
31
  inset: 0;
32
32
  opacity: 0;
33
- z-index: 1;
34
33
  margin: 0;
34
+ pointer-events: none;
35
35
  width: 100%;
36
36
  height: 100%;
37
37
  }
@@ -58,61 +58,55 @@ export const radioButtonStyles = css `
58
58
  transform: translate(-50%, -50%) scale(0);
59
59
  }
60
60
 
61
- .radio-button__input:checked ~ .radio-button__outer-shape {
61
+ :host([checked]) .radio-button__outer-shape {
62
62
  border-color: var(--components-radio-button-is-selected-border-color);
63
63
  background-color: var(--components-radio-button-is-selected-background-color);
64
64
  }
65
65
 
66
- .radio-button__input:checked ~ .radio-button__outer-shape .radio-button__inner-shape {
67
- transform: translate(-50%, -50%) scale(1);
68
- }
69
-
70
- /* Decorative has no input to hang :checked on, so the state comes from the
71
- host attribute instead. */
72
- :host([decorative][checked]) .radio-button__outer-shape {
73
- border-color: var(--components-radio-button-is-selected-border-color);
74
- background-color: var(--components-radio-button-is-selected-background-color);
75
- }
76
-
77
- :host([decorative][checked]) .radio-button__inner-shape {
66
+ :host([checked]) .radio-button__inner-shape {
78
67
  transform: translate(-50%, -50%) scale(1);
79
68
  }
80
69
 
81
70
  @media (hover: hover) {
82
- .radio-button__input:hover:not(:disabled) ~ .radio-button__outer-shape {
71
+ :host(:hover:not([disabled])) .radio-button__outer-shape {
83
72
  border-color: var(--components-radio-button-is-hovered-border-color);
84
73
  }
85
74
 
86
- .radio-button__input:checked:hover:not(:disabled) ~ .radio-button__outer-shape {
75
+ :host([checked]:hover:not([disabled])) .radio-button__outer-shape {
87
76
  border-color: var(--components-radio-button-is-selected-is-hovered-border-color);
88
77
  background-color: var(--components-radio-button-is-selected-is-hovered-background-color);
89
78
  }
90
79
 
91
- .radio-button__input:checked:hover:not(:disabled) ~ .radio-button__outer-shape .radio-button__inner-shape {
80
+ :host([checked]:hover:not([disabled])) .radio-button__inner-shape {
92
81
  border-color: var(--components-radio-button-is-selected-is-hovered-inner-shape-border-color);
93
82
  }
94
83
  }
95
84
 
96
- .radio-button__input:active:not(:disabled) ~ .radio-button__outer-shape {
85
+ :host(:active:not([disabled])) .radio-button__outer-shape {
97
86
  border-color: var(--components-radio-button-is-active-border-color);
98
87
  }
99
88
 
100
- .radio-button__input:checked:active:not(:disabled) ~ .radio-button__outer-shape {
89
+ :host([checked]:active:not([disabled])) .radio-button__outer-shape {
101
90
  border-color: var(--components-radio-button-is-selected-is-active-border-color);
102
91
  background-color: var(--components-radio-button-is-selected-is-active-background-color);
103
92
  }
104
93
 
105
- .radio-button__input:checked:active:not(:disabled) ~ .radio-button__outer-shape .radio-button__inner-shape {
94
+ :host([checked]:active:not([disabled])) .radio-button__inner-shape {
106
95
  border-color: var(--components-radio-button-is-selected-is-active-inner-shape-border-color);
107
96
  }
108
97
 
109
- .radio-button__input:focus-visible ~ .radio-button__outer-shape {
98
+ :host(:focus-visible) {
99
+ outline: none;
100
+ }
101
+
102
+ :host(:focus-visible) .radio-button__outer-shape,
103
+ :host([focus-ring]) .radio-button__outer-shape {
110
104
  outline: var(--semantics-focus-ring-outline);
111
105
  outline-offset: var(--semantics-focus-ring-outline-offset);
112
106
  box-shadow: var(--semantics-focus-ring-box-shadow);
113
107
  }
114
108
 
115
- .radio-button__input:disabled ~ .radio-button__outer-shape {
109
+ :host([disabled]) .radio-button__outer-shape {
116
110
  opacity: var(--primitives-opacity-disabled);
117
111
  }
118
112
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"radio-button.styles.js","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoHnC,CAAC"}
1
+ {"version":3,"file":"radio-button.styles.js","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8GnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"radio-button.template.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,cAAc,EAAE,MAAM,KAAK,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,cAAc,CA6B9E"}
1
+ {"version":3,"file":"radio-button.template.d.ts","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,cAAc,CAgC9E"}
@@ -1,7 +1,7 @@
1
- import { html, nothing } from 'lit';
1
+ import { html } from 'lit';
2
2
  export function radioButtonTemplate(component) {
3
3
  // Decorative: the shape only. Something else owns the interaction and the
4
- // state — a whole row that is itself the control, say — and an input here
4
+ // state — a whole row that is itself the control, say — and a radio here
5
5
  // would be a second control inside it.
6
6
  if (component.decorative) {
7
7
  return html `
@@ -10,17 +10,20 @@ export function radioButtonTemplate(component) {
10
10
  </div>
11
11
  `;
12
12
  }
13
+ // The radio itself is the host element, so nothing here is announced or
14
+ // focused. The input is only there to answer `required` for the form, and it
15
+ // answers the question a radio asks: is anything in this group checked. The
16
+ // name is for the platform: a radio without one is in no group, and a radio in
17
+ // no group never reports a missing value.
13
18
  return html `
14
- <input class="radio-button__input"
19
+ <input class="radio-button__validation-input"
15
20
  type="radio"
16
- .checked=${component.checked}
17
- ?disabled=${component.disabled}
21
+ name="nldd-validation"
18
22
  ?required=${component.required}
19
- name=${component.name || ''}
20
- value=${component.value}
21
- aria-label=${component.accessibleLabel || nothing}
22
- tabindex=${component.noTab ? '-1' : nothing}
23
- @change=${component._handleChange}
23
+ ?disabled=${component.disabled}
24
+ .checked=${component._groupHasSelection}
25
+ tabindex="-1"
26
+ aria-hidden="true"
24
27
  >
25
28
  <div class="radio-button__outer-shape"
26
29
  aria-hidden="true"
@@ -1 +1 @@
1
- {"version":3,"file":"radio-button.template.js","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAkB,MAAM,KAAK,CAAC;AAGpD,MAAM,UAAU,mBAAmB,CAAC,SAA0B;IAC7D,0EAA0E;IAC1E,0EAA0E;IAC1E,uCAAuC;IACvC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAA;;;;GAIV,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;;;cAGE,SAAS,CAAC,OAAO;eAChB,SAAS,CAAC,QAAQ;eAClB,SAAS,CAAC,QAAQ;UACvB,SAAS,CAAC,IAAI,IAAI,EAAE;WACnB,SAAS,CAAC,KAAK;gBACV,SAAS,CAAC,eAAe,IAAI,OAAO;cACtC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;aACjC,SAAS,CAAC,aAAa;;;;;;;EAOlC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"radio-button.template.js","sourceRoot":"","sources":["../../../../src/components/inputs/radio-button/radio-button.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAG3C,MAAM,UAAU,mBAAmB,CAAC,SAA0B;IAC7D,0EAA0E;IAC1E,yEAAyE;IACzE,uCAAuC;IACvC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAA;;;;GAIV,CAAC;IACH,CAAC;IACD,wEAAwE;IACxE,6EAA6E;IAC7E,4EAA4E;IAC5E,+EAA+E;IAC/E,0CAA0C;IAC1C,OAAO,IAAI,CAAA;;;;eAIG,SAAS,CAAC,QAAQ;eAClB,SAAS,CAAC,QAAQ;cACnB,SAAS,CAAC,kBAAkB;;;;;;;;;EASxC,CAAC;AACH,CAAC"}