@rak200/ui 0.2.18 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,10 +45,7 @@ npm install @rak200/ui
45
45
  </ui-select>
46
46
  </ui-field>
47
47
 
48
- <ui-field>
49
- <label slot="label">Email notifications</label>
50
- <ui-switch><input type="checkbox" name="notify" checked /></ui-switch>
51
- </ui-field>
48
+ <ui-switch label="Email notifications" name="notify" checked></ui-switch>
52
49
 
53
50
  <ui-button><ui-icon name="check"></ui-icon> Save</ui-button>
54
51
  <ui-button variant="secondary">Cancel</ui-button>
@@ -83,7 +80,9 @@ which one you are looking at.
83
80
  ## Documentation
84
81
 
85
82
  The reference lives in [docs/](docs/README.md) — one page per unit. The playground shows the
86
- components; `docs/` is what describes them.
83
+ components; `docs/` is what describes them. It renders under the token sheet a host inserts, and
84
+ its toolbar switches the colour scheme — so what the site shows is what a page gets, in both
85
+ schemes rather than one.
87
86
 
88
87
  ## Status
89
88
 
@@ -2,20 +2,202 @@ import { LitElement, type CSSResult, type TemplateResult } from 'lit';
2
2
  /**
3
3
  * A boolean control, drawn from the token layer rather than replaced.
4
4
  *
5
- * The `<input type="checkbox">` is the host's own and stays in the light DOM; this element
6
- * is the box around it. {@link UiCheckbox} and {@link UiSwitch} differ in what they draw
7
- * and in what they announce, never in what they are made of.
5
+ * {@link UiCheckbox} and {@link UiSwitch} differ in what they draw and in what they
6
+ * announce, never in what they are made of. Both render a native `<input type="checkbox">`
7
+ * inside a `<label>` in this element's shadow root, so every behaviour a boolean control
8
+ * has stays the platform's — see the docblock on the shared styles above.
9
+ *
10
+ * **The element is the form control**, through `ElementInternals`. An `<input>` inside a
11
+ * shadow root has no form owner, so the value reaches a submit because this element passes
12
+ * it on and never because the input did.
13
+ *
14
+ * That is the entire price, and it is worth listing because it is smaller than it looks:
15
+ * `setFormValue`, `setValidity`, the three form lifecycle callbacks a form can no longer
16
+ * perform directly, and a re-dispatch of `change`, which is non-composed. **None of it is
17
+ * accessibility** — the role, the checked state, the tab stop and what `disabled` does to
18
+ * it are all still the platform's, because the control really is one.
19
+ *
20
+ * The same object pays the other half, which is a cost of the control being *in here*
21
+ * rather than of the form: two states a host stylesheet could no longer see. See
22
+ * {@link UiToggle.expose}.
8
23
  */
9
24
  declare class UiToggle extends LitElement {
25
+ #private;
26
+ static readonly formAssociated = true;
27
+ /**
28
+ * Focus is delegated, so `focus()` and `reportValidity()` reach the control.
29
+ *
30
+ * Neither is optional: the host is not a focusable element, so without this a call to
31
+ * either lands on something that cannot take focus and does nothing — and the second
32
+ * one is what the browser does on its own when a form with an invalid control is
33
+ * submitted.
34
+ */
35
+ static readonly shadowRootOptions: {
36
+ delegatesFocus: boolean;
37
+ clonable?: boolean;
38
+ customElementRegistry?: CustomElementRegistry | null;
39
+ mode: ShadowRootMode;
40
+ serializable?: boolean;
41
+ slotAssignment?: SlotAssignmentMode;
42
+ };
43
+ static readonly properties: {
44
+ label: {
45
+ type: StringConstructor;
46
+ reflect: boolean;
47
+ };
48
+ name: {
49
+ type: StringConstructor;
50
+ reflect: boolean;
51
+ };
52
+ value: {
53
+ type: StringConstructor;
54
+ reflect: boolean;
55
+ };
56
+ checked: {
57
+ type: BooleanConstructor;
58
+ };
59
+ disabled: {
60
+ type: BooleanConstructor;
61
+ reflect: boolean;
62
+ };
63
+ required: {
64
+ type: BooleanConstructor;
65
+ reflect: boolean;
66
+ };
67
+ error: {
68
+ type: StringConstructor;
69
+ reflect: boolean;
70
+ };
71
+ };
72
+ /**
73
+ * The short road to a label. `slot="label"` overrides it where markup is needed.
74
+ *
75
+ * A plain field rather than the `accessor` keyword, for the reason `src/button.ts`
76
+ * gives beside its own — and so for every property below.
77
+ */
78
+ label: string;
79
+ /**
80
+ * The name the value is submitted under.
81
+ *
82
+ * **Reflected, and that is a requirement rather than a convenience.** A form reads a
83
+ * form-associated custom element's name from the content attribute, so a host who sets
84
+ * only the property would submit nothing at all — silently, with a value published and
85
+ * no entry to carry it.
86
+ */
87
+ name: string;
88
+ /** What a checked control submits, which the platform spells `on` by default. */
89
+ value: string;
90
+ /**
91
+ * Whether the control is on.
92
+ *
93
+ * **Not reflected, which is the platform's own answer rather than an omission.** A
94
+ * native checkbox's `checked` IDL attribute does not reflect either: the content
95
+ * attribute is the *default*, which is what a form reset returns to, and an attribute
96
+ * that followed every click would make the default whatever the user last did.
97
+ *
98
+ * A host stylesheet reaches the live state through `:state(checked)` — see
99
+ * {@link UiToggle.expose}, and the measurement there for why it is not `::part()`.
100
+ */
101
+ checked: boolean;
102
+ /** Whether the control rejects interaction. Reflected, the way the platform's is. */
103
+ disabled: boolean;
104
+ /** Whether a form is invalid while this control is off. Reflected, likewise. */
105
+ required: boolean;
106
+ /** The error message, which paints the boundary and is announced with the control. */
107
+ error: string;
108
+ /**
109
+ * Published after every render, and after the first one too — Lit calls this on the
110
+ * initial update as well, which is why there is no `firstUpdated` beside it. A second
111
+ * call from there would be a statement no test could distinguish from its own absence.
112
+ */
113
+ updated(): void;
114
+ /**
115
+ * Puts one internal state where a host stylesheet can select on it.
116
+ *
117
+ * **This is what replaces the attribute `checked` deliberately does not reflect**, and
118
+ * the alternative was measured rather than assumed: `::part(box):checked` does not
119
+ * match. A `::part()` may be followed by user-action pseudo-classes and not by state
120
+ * ones, so a host had no way at all to reach a state this element keeps in its shadow
121
+ * root — which would have made *not reflecting* a decision that costs the host
122
+ * something, rather than one that costs nothing.
123
+ *
124
+ * Only the two states with no other route are exposed. `:valid`, `:invalid` and
125
+ * `:disabled` already match on this element, measured, because a form-associated
126
+ * custom element takes part in them; `required` reflects, so `[required]` reaches it.
127
+ *
128
+ * @param state - The name, as `:state(name)` spells it.
129
+ */
130
+ protected expose(state: string, on: boolean): void;
131
+ /**
132
+ * What the inner control announces itself as, where the platform needs telling.
133
+ *
134
+ * Empty here, and the attribute is then omitted rather than written blank: an
135
+ * `<input type="checkbox">` already announces `checkbox`, and restating it would be
136
+ * this component overriding the platform with the platform. {@link UiSwitch} is the
137
+ * one that has something to add.
138
+ */
139
+ protected readonly controlRole: string;
140
+ /**
141
+ * The listener, as a field rather than a method, which is this repository's shape for
142
+ * one — `src/toast.ts` carries the same. What it delegates to is a method, so a
143
+ * subclass can extend the mirroring without restating the binding.
144
+ *
145
+ * **The `change` is re-dispatched rather than left to bubble**, because it does not:
146
+ * `change` is one of the events the platform marks non-composed, so the one the inner
147
+ * control fires stops at the shadow boundary and a host listening on the tag would
148
+ * hear nothing. `input` needs no such help — it is composed, and arrives retargeted to
149
+ * this element on its own.
150
+ */
151
+ protected readonly changed: (event: Event) => void;
152
+ /**
153
+ * Mirrors the platform's own state back into the properties it came from.
154
+ *
155
+ * Read off the control rather than inverted from what was there: the platform is what
156
+ * just changed it, and asking is the only way to stay right about a state this element
157
+ * did not decide.
158
+ */
159
+ protected sync(control: HTMLInputElement): void;
160
+ /**
161
+ * A form reset, which the platform calls and this element cannot see any other way.
162
+ *
163
+ * The content attribute is what it returns to, which is exactly `defaultChecked` on a
164
+ * native control — and it stays a usable default only because `checked` is not
165
+ * reflected onto it.
166
+ */
167
+ formResetCallback(): void;
168
+ /** A `<fieldset disabled>` above this element, which reaches it and nothing below. */
169
+ formDisabledCallback(disabled: boolean): void;
170
+ /** Restoring after a back-navigation, where the browser hands the value back. */
171
+ formStateRestoreCallback(state: string | null): void;
172
+ /** The form this element participates in, for a host that needs it. */
173
+ get form(): HTMLFormElement | null;
174
+ /** Whether the control currently satisfies its constraints. */
175
+ get validity(): ValidityState;
176
+ /** The message a form would report for it, empty while the control is valid. */
177
+ get validationMessage(): string;
10
178
  render(): TemplateResult;
179
+ /**
180
+ * The whole drawing, with the one thing the two elements disagree on passed in.
181
+ *
182
+ * **A parameter rather than an overridable hook**, and the difference is one the
183
+ * mutation floor found: a hook returning `false` is indistinguishable from a hook
184
+ * returning nothing, because `input.indeterminate` coerces `undefined` to `false` — so
185
+ * no test could tell the base implementation from its own absence. Passed at the call
186
+ * site it is a value, and `<ui-switch>` reading back an unmixed control is what checks
187
+ * it.
188
+ *
189
+ * The mixed state is bound rather than written onto the control after render, which is
190
+ * what keeps this element free of a query whose null branch nothing could reach.
191
+ */
192
+ protected template(mixed: boolean): TemplateResult;
11
193
  }
12
194
  /**
13
195
  * A checkbox, styled by the token layer rather than replaced.
14
196
  *
15
- * **The `<input>` is yours.** You write it, you set its attributes, and it stays in the
16
- * light DOM — so `name`, `checked`, `required` and `disabled` are the platform's business,
17
- * and it reaches a form submit because it is a native control inside a `<form>`. The same
18
- * shape `<ui-input>` has, for the same reason.
197
+ * **The control is this element's**, which RFC 0005 decided and reversed an earlier rule to
198
+ * do: the `<input>` and its `<label>` are rendered together in one shadow root, so `name`,
199
+ * `checked`, `required` and `disabled` are properties here rather than attributes a host
200
+ * writes on a control it supplies.
19
201
  *
20
202
  * **The indeterminate state is drawn, and that is not a feature being added.**
21
203
  * `appearance: none` takes the platform's dash away with the rest of the drawing, so a
@@ -23,19 +205,68 @@ declare class UiToggle extends LitElement {
23
205
  * rather than a missing one. The dash below is what stops that, and nothing here invites
24
206
  * a tri-state that APG says is rare.
25
207
  *
26
- * Composes with {@link UiField}, which finds the control through this wrapper and wires
27
- * the label, the help, the error and `aria-invalid` to it.
28
- *
29
208
  * @example
30
209
  * ```html
31
- * <ui-field>
32
- * <label slot="label">Send a receipt</label>
33
- * <ui-checkbox><input type="checkbox" name="receipt" /></ui-checkbox>
34
- * </ui-field>
210
+ * <ui-checkbox label="Send a receipt" name="receipt"></ui-checkbox>
211
+ * ```
212
+ *
213
+ * @example A label an attribute cannot hold.
214
+ * ```html
215
+ * <ui-checkbox name="terms">
216
+ * <span slot="label">I accept the <a href="/terms">terms</a></span>
217
+ * </ui-checkbox>
35
218
  * ```
36
219
  */
37
220
  export declare class UiCheckbox extends UiToggle {
221
+ static readonly properties: {
222
+ indeterminate: {
223
+ type: BooleanConstructor;
224
+ };
225
+ label: {
226
+ type: StringConstructor;
227
+ reflect: boolean;
228
+ };
229
+ name: {
230
+ type: StringConstructor;
231
+ reflect: boolean;
232
+ };
233
+ value: {
234
+ type: StringConstructor;
235
+ reflect: boolean;
236
+ };
237
+ checked: {
238
+ type: BooleanConstructor;
239
+ };
240
+ disabled: {
241
+ type: BooleanConstructor;
242
+ reflect: boolean;
243
+ };
244
+ required: {
245
+ type: BooleanConstructor;
246
+ reflect: boolean;
247
+ };
248
+ error: {
249
+ type: StringConstructor;
250
+ reflect: boolean;
251
+ };
252
+ };
253
+ /**
254
+ * The mixed state, which the platform stopped drawing once `appearance` was removed.
255
+ *
256
+ * It takes an attribute where the platform offers none, which is this element having
257
+ * become the control rather than a box around one — and it is not reflected, for the
258
+ * reason `checked` is not.
259
+ */
260
+ indeterminate: boolean;
38
261
  static readonly styles: CSSResult[];
262
+ render(): TemplateResult;
263
+ updated(): void;
264
+ /**
265
+ * A toggle answers the question the mixed state was asking, and the platform has
266
+ * already cleared it on the control — so this reads it back rather than assuming.
267
+ * Without it the next render would put the mixed state straight back.
268
+ */
269
+ protected sync(control: HTMLInputElement): void;
39
270
  }
40
271
  /**
41
272
  * A switch, which is a checkbox that says *on* and *off* rather than *checked*.
@@ -43,28 +274,22 @@ export declare class UiCheckbox extends UiToggle {
43
274
  * **The difference is semantic and the drawing follows it**, which is the order that
44
275
  * matters: a switch takes effect immediately and a checkbox is a value you submit, so the
45
276
  * two are not one component with two skins. `role="switch"` is what carries that to a
46
- * screen reader, and this element sets it on the slotted control rather than asking the
47
- * host to remember — forgetting it would leave a control that looks like a switch and
48
- * announces as a checkbox, with nothing anywhere to read. A role the host wrote is never
49
- * overwritten, the same way {@link UiField} never overwrites an `id` it did not generate.
277
+ * screen reader, and this element writes it on the control it renders — so a host has
278
+ * nothing to remember and nothing to forget.
50
279
  *
51
280
  * There is no native switch to delegate to: `<input type="checkbox" switch>` is
52
281
  * unsupported in the engine this suite measures, so the element is a checkbox with a role
53
282
  * and a drawing. A host who wants the mixed state wants {@link UiCheckbox} — `switch` has
54
- * no third value, so this element does not draw one.
283
+ * no third value, so this element does not draw one and offers no property for one.
55
284
  *
56
285
  * @example
57
286
  * ```html
58
- * <ui-field>
59
- * <label slot="label">Email notifications</label>
60
- * <ui-switch><input type="checkbox" name="notify" checked /></ui-switch>
61
- * </ui-field>
287
+ * <ui-switch label="Email notifications" name="notify" checked></ui-switch>
62
288
  * ```
63
289
  */
64
290
  export declare class UiSwitch extends UiToggle {
65
- #private;
66
291
  static readonly styles: CSSResult[];
67
- render(): TemplateResult;
292
+ protected readonly controlRole: string;
68
293
  }
69
294
  declare global {
70
295
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../src/checkbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AA6IjF;;;;;;GAMG;AACH,cAAM,QAAS,SAAQ,UAAU;IACpB,MAAM,IAAI,cAAc;CAGpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,UAAW,SAAQ,QAAQ;IACpC,gBAAyB,MAAM,EAAE,SAAS,EAAE,CA+B1C;CACL;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,QAAS,SAAQ,QAAQ;;IAClC,gBAAyB,MAAM,EAAE,SAAS,EAAE,CAuC1C;IAEO,MAAM,IAAI,cAAc;CAmBpC;AAWD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,aAAa,EAAE,UAAU,CAAC;QAC1B,WAAW,EAAE,QAAQ,CAAC;KACzB;CACJ"}
1
+ {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../src/checkbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAqL1F;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,cAAM,QAAS,SAAQ,UAAU;;IAC7B,MAAM,CAAC,QAAQ,CAAC,cAAc,QAAQ;IAEtC;;;;;;;OAOG;IACH,gBAAyB,iBAAiB;;;;;;;MAGxC;IAEF,gBAAyB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAQjC;IAEF;;;;;OAKG;IACH,KAAK,SAAM;IAEX;;;;;;;OAOG;IACH,IAAI,SAAM;IAEV,iFAAiF;IACjF,KAAK,SAAQ;IAEb;;;;;;;;;;OAUG;IACH,OAAO,UAAS;IAEhB,qFAAqF;IACrF,QAAQ,UAAS;IAEjB,gFAAgF;IAChF,QAAQ,UAAS;IAEjB,sFAAsF;IACtF,KAAK,SAAM;IAoBX;;;;OAIG;IACM,OAAO,IAAI,IAAI;IAKxB;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI;IAQlD;;;;;;;OAOG;IACH,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAM;IAE5C;;;;;;;;;;OAUG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,GAAI,OAAO,KAAK,KAAG,IAAI,CAG/C;IAEF;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAI/C;;;;;;OAMG;IACH,iBAAiB,IAAI,IAAI;IAIzB,sFAAsF;IACtF,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAI7C,iFAAiF;IACjF,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIpD,uEAAuE;IACvE,IAAI,IAAI,IAAI,eAAe,GAAG,IAAI,CAEjC;IAED,+DAA+D;IAC/D,IAAI,QAAQ,IAAI,aAAa,CAE5B;IAED,gFAAgF;IAChF,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAEQ,MAAM,IAAI,cAAc;IAIjC;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc;CAwBrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,UAAW,SAAQ,QAAQ;IACpC,gBAAyB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAGjC;IAEF;;;;;;OAMG;IACH,aAAa,UAAS;IAEtB,gBAAyB,MAAM,EAAE,SAAS,EAAE,CA6C1C;IAEO,MAAM,IAAI,cAAc;IAIxB,OAAO,IAAI,IAAI;IAKxB;;;;OAIG;cACgB,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;CAI3D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,QAAS,SAAQ,QAAQ;IAClC,gBAAyB,MAAM,EAAE,SAAS,EAAE,CAuC1C;IAEF,mBAA4B,WAAW,EAAE,MAAM,CAAY;CAC9D;AAWD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,aAAa,EAAE,UAAU,CAAC;QAC1B,WAAW,EAAE,QAAQ,CAAC;KACzB;CACJ"}
package/dist/checkbox.js CHANGED
@@ -1,4 +1,4 @@
1
- import { LitElement, css, html } from 'lit';
1
+ import { LitElement, css, html, nothing } from 'lit';
2
2
  import { reference } from './reference.js';
3
3
  /**
4
4
  * The size both controls are drawn at, and a floor rather than a preference.
@@ -19,12 +19,6 @@ const size = css `max(24px, calc(${reference('--ui-space')} * 3))`;
19
19
  * decision. **A mask has no colour**: only its alpha is read, so the black below is a
20
20
  * shape and never a value. What the tick shows is the surface behind the control, punched
21
21
  * out of the accent fill by `mask-composite: exclude`.
22
- *
23
- * The alternative was a mark rendered into the shadow root, and it is not available:
24
- * `:host(:has(input:checked))` is invalid in this engine — `CSS.supports` says so, so it
25
- * is a selector that does not exist rather than one that fails to update — and shadow CSS
26
- * has no other way to read a slotted control's state. Only `::slotted(input:checked)`
27
- * does, which means the control has to paint its own mark.
28
22
  */
29
23
  const tick = css `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E")`;
30
24
  /** A mask layer covering the whole control, which the mark is then subtracted from. */
@@ -32,10 +26,20 @@ const whole = css `linear-gradient(#000, #000)`;
32
26
  /**
33
27
  * What a drawn boolean control looks like, which both elements share.
34
28
  *
35
- * The control is the host's own `<input type="checkbox">`, slotted, for the reason
36
- * `src/input.ts` gives at length: an IDREF does not cross a shadow boundary, so a control
37
- * rendered in here could not be labelled by the `<label>` beside it. Everything below
38
- * reaches it through `::slotted`.
29
+ * **The control and its label are rendered together, in this element's shadow root.** RFC
30
+ * 0005 settled that and measured why: an ARIA relationship needs every end of it inside one
31
+ * tree scope, and the arrangement that strands a control is the one that puts the control on
32
+ * one side of a shadow boundary and its label on the other — not the fact that the control
33
+ * is rendered. With the `<label>` and the `<input>` in the same root the association is the
34
+ * platform's, and so is everything that follows from it: the toggle, the <kbd>Space</kbd>
35
+ * key, the click target over the label text, and the rule that a link inside a label
36
+ * follows the link rather than toggling. None of that is written in this file, which is the
37
+ * point of the shape.
38
+ *
39
+ * The state is this element's own, so these rules read `input:checked` directly. The
40
+ * `::slotted(input:checked)` this file used to be built on was forced by
41
+ * `:host(:has(input:checked))` being invalid in this engine, and that constraint went with
42
+ * the slotted control.
39
43
  *
40
44
  * **`appearance: none` is the whole cost of this component**, and it is taken knowingly.
41
45
  * It buys one drawing for the pair — the same border, radius, focus ring and accent the
@@ -48,21 +52,43 @@ const whole = css `linear-gradient(#000, #000)`;
48
52
  * target-size floor at {@link size}, and the forced-colors block at the end.
49
53
  */
50
54
  const toggle = css `
55
+ /* A column, because the error sits under the control rather than beside it — and
56
+ flex-start rather than the default stretch, so a message wider than the label does
57
+ not widen the label, which is the click target. */
51
58
  :host {
52
59
  display: inline-flex;
60
+ flex-direction: column;
61
+ align-items: flex-start;
62
+ gap: calc(${reference('--ui-space')} / 2);
63
+ font-family: ${reference('--ui-font')};
64
+ }
65
+
66
+ /* The label is the whole pair's worth of click target, which a host used to have to
67
+ build by wrapping the component in a <label> of their own.
68
+
69
+ flex rather than inline-flex, and the difference is one the platform erases: a flex
70
+ item's display is blockified, so inline-flex here would compute to flex anyway — a
71
+ declaration no rendering could tell from this one. */
72
+ label {
73
+ display: flex;
74
+ align-items: center;
75
+ gap: ${reference('--ui-space')};
76
+ cursor: pointer;
77
+ color: ${reference('--ui-color-text')};
53
78
  }
54
79
 
55
- ::slotted(input) {
80
+ input {
56
81
  appearance: none;
57
82
  box-sizing: border-box;
58
83
  /* The user agent puts 3px around a checkbox. Left in, it would sit inside the
59
84
  host box and put the control off centre in any layout that aligns to it. */
60
85
  margin: 0;
86
+ flex: none;
61
87
  block-size: ${size};
62
88
  background-color: ${reference('--ui-color-surface')};
63
89
  background-repeat: no-repeat;
64
90
  border: 1px solid ${reference('--ui-color-border')};
65
- cursor: pointer;
91
+ cursor: inherit;
66
92
  /* The focus ring is deliberately not in this list, for the reason src/button.ts
67
93
  gives beside its own: delaying the affordance that says *this is where you are*
68
94
  is the opposite of what it exists to do. */
@@ -71,7 +97,7 @@ const toggle = css `
71
97
  border-color ${reference('--ui-duration-state')} ${reference('--ui-easing-state')};
72
98
  }
73
99
 
74
- ::slotted(input:checked) {
100
+ input:checked {
75
101
  background-color: ${reference('--ui-color-accent')};
76
102
  border-color: ${reference('--ui-color-accent')};
77
103
  }
@@ -82,35 +108,50 @@ const toggle = css `
82
108
 
83
109
  The disabled guard is measured rather than assumed: a disabled control still
84
110
  matches :hover. */
85
- ::slotted(input:hover:not(:disabled)) {
111
+ input:hover:not(:disabled) {
86
112
  border-color: ${reference('--ui-color-text')};
87
113
  }
88
114
 
89
- ::slotted(input:checked:hover:not(:disabled)) {
115
+ input:checked:hover:not(:disabled) {
90
116
  background-color: ${reference('--ui-color-accent-hover')};
91
117
  border-color: ${reference('--ui-color-accent-hover')};
92
118
  }
93
119
 
94
120
  /* A visible focus ring is not decoration: removing it is the single most common way a
95
121
  component stops being usable by keyboard. */
96
- ::slotted(input:focus-visible) {
122
+ input:focus-visible {
97
123
  outline: 2px solid ${reference('--ui-color-focus')};
98
124
  outline-offset: 2px;
99
125
  }
100
126
 
101
- ::slotted(input:disabled) {
102
- cursor: not-allowed;
127
+ input:disabled {
103
128
  opacity: 0.5;
104
129
  }
105
130
 
106
- /* The error state is not this component's to decide: ui-field sets aria-invalid on
107
- the control as part of the wiring it already owns, and this rule reads it — so the
108
- message under the field and the control cannot disagree about whether there is an
109
- error. Only the boundary moves; a red fill on a switch would read as *on*. */
110
- ::slotted(input[aria-invalid='true']) {
131
+ /* Read off the host rather than through :has(), because the property is reflected and
132
+ the host attribute is therefore the same fact one selector earlier. */
133
+ :host([disabled]) label {
134
+ cursor: not-allowed;
135
+ color: ${reference('--ui-color-text-muted')};
136
+ }
137
+
138
+ /* Read off the control's own aria-invalid rather than off a host attribute, which is
139
+ the same source a screen reader uses and the same rule this file carried when
140
+ ui-field was the one writing it. One property now feeds all three — the boundary,
141
+ the message and setValidity — so they cannot disagree. Only the boundary moves; a
142
+ red fill on a switch would read as *on*.
143
+
144
+ Not :host([error]): a reflected string property whose default is empty puts an
145
+ empty attribute on the host, and an attribute-presence selector matches it. */
146
+ input[aria-invalid='true'] {
111
147
  border-color: ${reference('--ui-color-danger')};
112
148
  }
113
149
 
150
+ .error {
151
+ color: ${reference('--ui-color-danger')};
152
+ font-size: ${reference('--ui-text-supporting')};
153
+ }
154
+
114
155
  /* Forced colors replaces every author colour with one from the user's palette, so
115
156
  the accent that says *checked* becomes the same Canvas as the surface that says
116
157
  *not* — the state disappears, silently, for the people who turned the mode on to
@@ -122,13 +163,12 @@ const toggle = css `
122
163
  half-transparent against a palette chosen for contrast. GrayText is what that mode
123
164
  has for *unavailable*, and it is a colour rather than a veil. */
124
165
  @media (forced-colors: active) {
125
- ::slotted(input:checked),
126
- ::slotted(input:indeterminate) {
166
+ input:checked {
127
167
  background-color: Highlight;
128
168
  border-color: Highlight;
129
169
  }
130
170
 
131
- ::slotted(input:disabled) {
171
+ input:disabled {
132
172
  border-color: GrayText;
133
173
  opacity: 1;
134
174
  }
@@ -137,22 +177,245 @@ const toggle = css `
137
177
  /**
138
178
  * A boolean control, drawn from the token layer rather than replaced.
139
179
  *
140
- * The `<input type="checkbox">` is the host's own and stays in the light DOM; this element
141
- * is the box around it. {@link UiCheckbox} and {@link UiSwitch} differ in what they draw
142
- * and in what they announce, never in what they are made of.
180
+ * {@link UiCheckbox} and {@link UiSwitch} differ in what they draw and in what they
181
+ * announce, never in what they are made of. Both render a native `<input type="checkbox">`
182
+ * inside a `<label>` in this element's shadow root, so every behaviour a boolean control
183
+ * has stays the platform's — see the docblock on the shared styles above.
184
+ *
185
+ * **The element is the form control**, through `ElementInternals`. An `<input>` inside a
186
+ * shadow root has no form owner, so the value reaches a submit because this element passes
187
+ * it on and never because the input did.
188
+ *
189
+ * That is the entire price, and it is worth listing because it is smaller than it looks:
190
+ * `setFormValue`, `setValidity`, the three form lifecycle callbacks a form can no longer
191
+ * perform directly, and a re-dispatch of `change`, which is non-composed. **None of it is
192
+ * accessibility** — the role, the checked state, the tab stop and what `disabled` does to
193
+ * it are all still the platform's, because the control really is one.
194
+ *
195
+ * The same object pays the other half, which is a cost of the control being *in here*
196
+ * rather than of the form: two states a host stylesheet could no longer see. See
197
+ * {@link UiToggle.expose}.
143
198
  */
144
199
  class UiToggle extends LitElement {
200
+ constructor() {
201
+ super(...arguments);
202
+ /**
203
+ * The short road to a label. `slot="label"` overrides it where markup is needed.
204
+ *
205
+ * A plain field rather than the `accessor` keyword, for the reason `src/button.ts`
206
+ * gives beside its own — and so for every property below.
207
+ */
208
+ this.label = '';
209
+ /**
210
+ * The name the value is submitted under.
211
+ *
212
+ * **Reflected, and that is a requirement rather than a convenience.** A form reads a
213
+ * form-associated custom element's name from the content attribute, so a host who sets
214
+ * only the property would submit nothing at all — silently, with a value published and
215
+ * no entry to carry it.
216
+ */
217
+ this.name = '';
218
+ /** What a checked control submits, which the platform spells `on` by default. */
219
+ this.value = 'on';
220
+ /**
221
+ * Whether the control is on.
222
+ *
223
+ * **Not reflected, which is the platform's own answer rather than an omission.** A
224
+ * native checkbox's `checked` IDL attribute does not reflect either: the content
225
+ * attribute is the *default*, which is what a form reset returns to, and an attribute
226
+ * that followed every click would make the default whatever the user last did.
227
+ *
228
+ * A host stylesheet reaches the live state through `:state(checked)` — see
229
+ * {@link UiToggle.expose}, and the measurement there for why it is not `::part()`.
230
+ */
231
+ this.checked = false;
232
+ /** Whether the control rejects interaction. Reflected, the way the platform's is. */
233
+ this.disabled = false;
234
+ /** Whether a form is invalid while this control is off. Reflected, likewise. */
235
+ this.required = false;
236
+ /** The error message, which paints the boundary and is announced with the control. */
237
+ this.error = '';
238
+ this.#internals = this.attachInternals();
239
+ /**
240
+ * What the inner control announces itself as, where the platform needs telling.
241
+ *
242
+ * Empty here, and the attribute is then omitted rather than written blank: an
243
+ * `<input type="checkbox">` already announces `checkbox`, and restating it would be
244
+ * this component overriding the platform with the platform. {@link UiSwitch} is the
245
+ * one that has something to add.
246
+ */
247
+ this.controlRole = '';
248
+ /**
249
+ * The listener, as a field rather than a method, which is this repository's shape for
250
+ * one — `src/toast.ts` carries the same. What it delegates to is a method, so a
251
+ * subclass can extend the mirroring without restating the binding.
252
+ *
253
+ * **The `change` is re-dispatched rather than left to bubble**, because it does not:
254
+ * `change` is one of the events the platform marks non-composed, so the one the inner
255
+ * control fires stops at the shadow boundary and a host listening on the tag would
256
+ * hear nothing. `input` needs no such help — it is composed, and arrives retargeted to
257
+ * this element on its own.
258
+ */
259
+ this.changed = (event) => {
260
+ this.sync(event.target);
261
+ this.dispatchEvent(new Event('change', { bubbles: true }));
262
+ };
263
+ }
264
+ static { this.formAssociated = true; }
265
+ /**
266
+ * Focus is delegated, so `focus()` and `reportValidity()` reach the control.
267
+ *
268
+ * Neither is optional: the host is not a focusable element, so without this a call to
269
+ * either lands on something that cannot take focus and does nothing — and the second
270
+ * one is what the browser does on its own when a form with an invalid control is
271
+ * submitted.
272
+ */
273
+ static { this.shadowRootOptions = {
274
+ ...LitElement.shadowRootOptions,
275
+ delegatesFocus: true,
276
+ }; }
277
+ static { this.properties = {
278
+ label: { type: String, reflect: true },
279
+ name: { type: String, reflect: true },
280
+ value: { type: String, reflect: true },
281
+ checked: { type: Boolean },
282
+ disabled: { type: Boolean, reflect: true },
283
+ required: { type: Boolean, reflect: true },
284
+ error: { type: String, reflect: true },
285
+ }; }
286
+ #internals;
287
+ /** The form value and the validity, which move together here or disagree anywhere. */
288
+ #publish() {
289
+ this.#internals.setFormValue(this.checked ? this.value : null);
290
+ if (this.error !== '') {
291
+ this.#internals.setValidity({ customError: true }, this.error);
292
+ }
293
+ else if (this.required && !this.checked) {
294
+ this.#internals.setValidity({ valueMissing: true }, 'Please tick this box if you want to proceed.');
295
+ }
296
+ else {
297
+ this.#internals.setValidity({});
298
+ }
299
+ }
300
+ /**
301
+ * Published after every render, and after the first one too — Lit calls this on the
302
+ * initial update as well, which is why there is no `firstUpdated` beside it. A second
303
+ * call from there would be a statement no test could distinguish from its own absence.
304
+ */
305
+ updated() {
306
+ this.#publish();
307
+ this.expose('checked', this.checked);
308
+ }
309
+ /**
310
+ * Puts one internal state where a host stylesheet can select on it.
311
+ *
312
+ * **This is what replaces the attribute `checked` deliberately does not reflect**, and
313
+ * the alternative was measured rather than assumed: `::part(box):checked` does not
314
+ * match. A `::part()` may be followed by user-action pseudo-classes and not by state
315
+ * ones, so a host had no way at all to reach a state this element keeps in its shadow
316
+ * root — which would have made *not reflecting* a decision that costs the host
317
+ * something, rather than one that costs nothing.
318
+ *
319
+ * Only the two states with no other route are exposed. `:valid`, `:invalid` and
320
+ * `:disabled` already match on this element, measured, because a form-associated
321
+ * custom element takes part in them; `required` reflects, so `[required]` reaches it.
322
+ *
323
+ * @param state - The name, as `:state(name)` spells it.
324
+ */
325
+ expose(state, on) {
326
+ if (on) {
327
+ this.#internals.states.add(state);
328
+ }
329
+ else {
330
+ this.#internals.states.delete(state);
331
+ }
332
+ }
333
+ /**
334
+ * Mirrors the platform's own state back into the properties it came from.
335
+ *
336
+ * Read off the control rather than inverted from what was there: the platform is what
337
+ * just changed it, and asking is the only way to stay right about a state this element
338
+ * did not decide.
339
+ */
340
+ sync(control) {
341
+ this.checked = control.checked;
342
+ }
343
+ /**
344
+ * A form reset, which the platform calls and this element cannot see any other way.
345
+ *
346
+ * The content attribute is what it returns to, which is exactly `defaultChecked` on a
347
+ * native control — and it stays a usable default only because `checked` is not
348
+ * reflected onto it.
349
+ */
350
+ formResetCallback() {
351
+ this.checked = this.hasAttribute('checked');
352
+ }
353
+ /** A `<fieldset disabled>` above this element, which reaches it and nothing below. */
354
+ formDisabledCallback(disabled) {
355
+ this.disabled = disabled;
356
+ }
357
+ /** Restoring after a back-navigation, where the browser hands the value back. */
358
+ formStateRestoreCallback(state) {
359
+ this.checked = state !== null;
360
+ }
361
+ /** The form this element participates in, for a host that needs it. */
362
+ get form() {
363
+ return this.#internals.form;
364
+ }
365
+ /** Whether the control currently satisfies its constraints. */
366
+ get validity() {
367
+ return this.#internals.validity;
368
+ }
369
+ /** The message a form would report for it, empty while the control is valid. */
370
+ get validationMessage() {
371
+ return this.#internals.validationMessage;
372
+ }
145
373
  render() {
146
- return html `<slot></slot>`;
374
+ return this.template(false);
375
+ }
376
+ /**
377
+ * The whole drawing, with the one thing the two elements disagree on passed in.
378
+ *
379
+ * **A parameter rather than an overridable hook**, and the difference is one the
380
+ * mutation floor found: a hook returning `false` is indistinguishable from a hook
381
+ * returning nothing, because `input.indeterminate` coerces `undefined` to `false` — so
382
+ * no test could tell the base implementation from its own absence. Passed at the call
383
+ * site it is a value, and `<ui-switch>` reading back an unmixed control is what checks
384
+ * it.
385
+ *
386
+ * The mixed state is bound rather than written onto the control after render, which is
387
+ * what keeps this element free of a query whose null branch nothing could reach.
388
+ */
389
+ template(mixed) {
390
+ return html `
391
+ <label part="label">
392
+ <input
393
+ type="checkbox"
394
+ part="box"
395
+ role=${this.controlRole === '' ? nothing : this.controlRole}
396
+ .checked=${this.checked}
397
+ .indeterminate=${mixed}
398
+ ?disabled=${this.disabled}
399
+ ?required=${this.required}
400
+ aria-invalid=${this.error === '' ? nothing : 'true'}
401
+ aria-describedby=${this.error === '' ? nothing : 'error'}
402
+ @change=${this.changed}
403
+ />
404
+ <span part="text"><slot name="label">${this.label}</slot></span>
405
+ </label>
406
+ ${this.error === ''
407
+ ? nothing
408
+ : html `<span class="error" id="error" part="error">${this.error}</span>`}
409
+ `;
147
410
  }
148
411
  }
149
412
  /**
150
413
  * A checkbox, styled by the token layer rather than replaced.
151
414
  *
152
- * **The `<input>` is yours.** You write it, you set its attributes, and it stays in the
153
- * light DOM — so `name`, `checked`, `required` and `disabled` are the platform's business,
154
- * and it reaches a form submit because it is a native control inside a `<form>`. The same
155
- * shape `<ui-input>` has, for the same reason.
415
+ * **The control is this element's**, which RFC 0005 decided and reversed an earlier rule to
416
+ * do: the `<input>` and its `<label>` are rendered together in one shadow root, so `name`,
417
+ * `checked`, `required` and `disabled` are properties here rather than attributes a host
418
+ * writes on a control it supplies.
156
419
  *
157
420
  * **The indeterminate state is drawn, and that is not a feature being added.**
158
421
  * `appearance: none` takes the platform's dash away with the rest of the drawing, so a
@@ -160,22 +423,38 @@ class UiToggle extends LitElement {
160
423
  * rather than a missing one. The dash below is what stops that, and nothing here invites
161
424
  * a tri-state that APG says is rare.
162
425
  *
163
- * Composes with {@link UiField}, which finds the control through this wrapper and wires
164
- * the label, the help, the error and `aria-invalid` to it.
165
- *
166
426
  * @example
167
427
  * ```html
168
- * <ui-field>
169
- * <label slot="label">Send a receipt</label>
170
- * <ui-checkbox><input type="checkbox" name="receipt" /></ui-checkbox>
171
- * </ui-field>
428
+ * <ui-checkbox label="Send a receipt" name="receipt"></ui-checkbox>
429
+ * ```
430
+ *
431
+ * @example A label an attribute cannot hold.
432
+ * ```html
433
+ * <ui-checkbox name="terms">
434
+ * <span slot="label">I accept the <a href="/terms">terms</a></span>
435
+ * </ui-checkbox>
172
436
  * ```
173
437
  */
174
438
  export class UiCheckbox extends UiToggle {
439
+ constructor() {
440
+ super(...arguments);
441
+ /**
442
+ * The mixed state, which the platform stopped drawing once `appearance` was removed.
443
+ *
444
+ * It takes an attribute where the platform offers none, which is this element having
445
+ * become the control rather than a box around one — and it is not reflected, for the
446
+ * reason `checked` is not.
447
+ */
448
+ this.indeterminate = false;
449
+ }
450
+ static { this.properties = {
451
+ ...UiToggle.properties,
452
+ indeterminate: { type: Boolean },
453
+ }; }
175
454
  static { this.styles = [
176
455
  toggle,
177
456
  css `
178
- ::slotted(input) {
457
+ input {
179
458
  inline-size: ${size};
180
459
  border-radius: ${reference('--ui-radius')};
181
460
  }
@@ -183,7 +462,7 @@ export class UiCheckbox extends UiToggle {
183
462
  /* The mark is a hole: the whole control, minus the shape, so what shows
184
463
  through is whatever the control sits on. The docblock on the mask constant
185
464
  above says why a hole rather than a colour. */
186
- ::slotted(input:checked) {
465
+ input:checked {
187
466
  mask-image: ${whole}, ${tick};
188
467
  mask-composite: exclude;
189
468
  mask-size: 100% 100%;
@@ -191,7 +470,7 @@ export class UiCheckbox extends UiToggle {
191
470
  }
192
471
 
193
472
  /* A dash needs no drawing: a rectangle is a gradient with a size. */
194
- ::slotted(input:indeterminate) {
473
+ input:indeterminate {
195
474
  background-color: ${reference('--ui-color-accent')};
196
475
  border-color: ${reference('--ui-color-accent')};
197
476
  mask-image: ${whole}, ${whole};
@@ -202,8 +481,38 @@ export class UiCheckbox extends UiToggle {
202
481
  mask-position: center;
203
482
  mask-repeat: no-repeat;
204
483
  }
484
+
485
+ /* The mixed state's forced-colors override lives here rather than beside the
486
+ checked one in the shared sheet, and the cascade is why: the rule above is
487
+ in a later sheet at equal specificity, so a Highlight declared back there
488
+ loses to the accent declared here — and the accent is exactly what forced
489
+ colors replaces with the surface, taking the state away for the reader who
490
+ turned the mode on to see it. Measured, as a test the shared block passed
491
+ for :checked and could not pass for this one. */
492
+ @media (forced-colors: active) {
493
+ input:indeterminate {
494
+ background-color: Highlight;
495
+ border-color: Highlight;
496
+ }
497
+ }
205
498
  `,
206
499
  ]; }
500
+ render() {
501
+ return this.template(this.indeterminate);
502
+ }
503
+ updated() {
504
+ super.updated();
505
+ this.expose('indeterminate', this.indeterminate);
506
+ }
507
+ /**
508
+ * A toggle answers the question the mixed state was asking, and the platform has
509
+ * already cleared it on the control — so this reads it back rather than assuming.
510
+ * Without it the next render would put the mixed state straight back.
511
+ */
512
+ sync(control) {
513
+ super.sync(control);
514
+ this.indeterminate = control.indeterminate;
515
+ }
207
516
  }
208
517
  /**
209
518
  * A switch, which is a checkbox that says *on* and *off* rather than *checked*.
@@ -211,29 +520,28 @@ export class UiCheckbox extends UiToggle {
211
520
  * **The difference is semantic and the drawing follows it**, which is the order that
212
521
  * matters: a switch takes effect immediately and a checkbox is a value you submit, so the
213
522
  * two are not one component with two skins. `role="switch"` is what carries that to a
214
- * screen reader, and this element sets it on the slotted control rather than asking the
215
- * host to remember — forgetting it would leave a control that looks like a switch and
216
- * announces as a checkbox, with nothing anywhere to read. A role the host wrote is never
217
- * overwritten, the same way {@link UiField} never overwrites an `id` it did not generate.
523
+ * screen reader, and this element writes it on the control it renders — so a host has
524
+ * nothing to remember and nothing to forget.
218
525
  *
219
526
  * There is no native switch to delegate to: `<input type="checkbox" switch>` is
220
527
  * unsupported in the engine this suite measures, so the element is a checkbox with a role
221
528
  * and a drawing. A host who wants the mixed state wants {@link UiCheckbox} — `switch` has
222
- * no third value, so this element does not draw one.
529
+ * no third value, so this element does not draw one and offers no property for one.
223
530
  *
224
531
  * @example
225
532
  * ```html
226
- * <ui-field>
227
- * <label slot="label">Email notifications</label>
228
- * <ui-switch><input type="checkbox" name="notify" checked /></ui-switch>
229
- * </ui-field>
533
+ * <ui-switch label="Email notifications" name="notify" checked></ui-switch>
230
534
  * ```
231
535
  */
232
536
  export class UiSwitch extends UiToggle {
537
+ constructor() {
538
+ super(...arguments);
539
+ this.controlRole = 'switch';
540
+ }
233
541
  static { this.styles = [
234
542
  toggle,
235
543
  css `
236
- ::slotted(input) {
544
+ input {
237
545
  inline-size: calc(${size} * 5 / 3);
238
546
  /* Any radius at or above half the block size rounds the ends fully, so
239
547
  the whole size is a pill at every size this control can take. */
@@ -245,10 +553,10 @@ export class UiSwitch extends UiToggle {
245
553
  colour — restating it here changed no pixel, which is how it was
246
554
  found: as a mutant no test could possibly kill. */
247
555
  background-color: ${reference('--ui-color-border')};
248
- /* The thumb is a background layer rather than an element, because an
249
- element would have to live in the shadow root and could not be told
250
- the control is on. A closest-side radius comes from the layer's
251
- own size, so one number moves the thumb. */
556
+ /* The thumb is a background layer rather than an element, because the
557
+ layer moves with one number where an element would need a second rule
558
+ to be told the control is on. A closest-side radius comes from the
559
+ layer's own size. */
252
560
  background-image: radial-gradient(
253
561
  circle closest-side,
254
562
  ${reference('--ui-color-surface')} 100%,
@@ -265,28 +573,11 @@ export class UiSwitch extends UiToggle {
265
573
  ${reference('--ui-easing-state')};
266
574
  }
267
575
 
268
- ::slotted(input:checked) {
576
+ input:checked {
269
577
  background-position: calc(100% - ${size} / 6) center;
270
578
  }
271
579
  `,
272
580
  ]; }
273
- render() {
274
- return html `<slot @slotchange=${this.#announce}></slot>`;
275
- }
276
- /**
277
- * Marks the slotted control a switch for anything reading the accessibility tree.
278
- *
279
- * On `slotchange` rather than once, because the host may replace the control — a
280
- * framework re-render is indistinguishable from that here, and a switch that
281
- * announces itself correctly only until the first re-render is worse than one that
282
- * never did.
283
- */
284
- #announce() {
285
- const control = this.querySelector('input');
286
- if (control !== null && !control.hasAttribute('role')) {
287
- control.setAttribute('role', 'switch');
288
- }
289
- }
290
581
  }
291
582
  // Stryker disable next-line StringLiteral: the registration runs once, at import, inside
292
583
  // the warm process Stryker switches mutants in — so by the time a mutant on this line is
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.js","sourceRoot":"","sources":["../src/checkbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkbox.js","sourceRoot":"","sources":["../src/checkbox.ts"],"names":[],"mappings":"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"}
package/dist/field.d.ts CHANGED
@@ -3,8 +3,12 @@ import { LitElement, type TemplateResult } from 'lit';
3
3
  * Form plumbing: a label bound to a control, help and error text bound through
4
4
  * `aria-describedby`, and `aria-invalid` while the field is in error.
5
5
  *
6
- * Written once here rather than per control. Every form component in the v0 cut needs the
7
- * same wiring, and five copies of it are five chances to get one subtly wrong.
6
+ * Written once here rather than per control that needs it, because copies of one wiring are
7
+ * copies of one chance to get it subtly wrong.
8
+ *
9
+ * **`<ui-checkbox>` and `<ui-switch>` are not among them any more.** They render their label,
10
+ * their message and their `aria-invalid` beside the control, in one tree scope, so there is
11
+ * nothing scattered here to point at anything — see `docs/checkbox.md`.
8
12
  *
9
13
  * **Everything is slotted, and that is forced rather than chosen.** An ARIA relationship
10
14
  * by IDREF does not cross a shadow boundary: a `<label for>` rendered in this element's
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAMjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,OAAQ,SAAQ,UAAU;;IACnC,gBAAyB,MAAM,0BAuB7B;IAeO,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAK5B,YAAY,IAAI,IAAI;IAIpB,MAAM,IAAI,cAAc;CAmLpC;AAQD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,UAAU,EAAE,OAAO,CAAC;KACvB;CACJ"}
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAMjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,OAAQ,SAAQ,UAAU;;IACnC,gBAAyB,MAAM,0BAuB7B;IAeO,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAK5B,YAAY,IAAI,IAAI;IAIpB,MAAM,IAAI,cAAc;CAmLpC;AAQD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,UAAU,EAAE,OAAO,CAAC;KACvB;CACJ"}
package/dist/field.js CHANGED
@@ -6,8 +6,12 @@ let sequence = 0;
6
6
  * Form plumbing: a label bound to a control, help and error text bound through
7
7
  * `aria-describedby`, and `aria-invalid` while the field is in error.
8
8
  *
9
- * Written once here rather than per control. Every form component in the v0 cut needs the
10
- * same wiring, and five copies of it are five chances to get one subtly wrong.
9
+ * Written once here rather than per control that needs it, because copies of one wiring are
10
+ * copies of one chance to get it subtly wrong.
11
+ *
12
+ * **`<ui-checkbox>` and `<ui-switch>` are not among them any more.** They render their label,
13
+ * their message and their `aria-invalid` beside the control, in one tree scope, so there is
14
+ * nothing scattered here to point at anything — see `docs/checkbox.md`.
11
15
  *
12
16
  * **Everything is slotted, and that is forced rather than chosen.** An ARIA relationship
13
17
  * by IDREF does not cross a shadow boundary: a `<label for>` rendered in this element's
package/dist/field.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"field.js","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAuB,MAAM,KAAK,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,8DAA8D;AAC9D,IAAI,QAAQ,GAAG,CAAC,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,OAAO,OAAQ,SAAQ,UAAU;aACV,WAAM,GAAG,GAAG,CAAA;;;2BAGd,SAAS,CAAC,WAAW,CAAC;;;;;;wBAMzB,SAAS,CAAC,YAAY,CAAC;;;;qBAI1B,SAAS,CAAC,iBAAiB,CAAC;yBACxB,SAAS,CAAC,sBAAsB,CAAC;;;;;;qBAMrC,SAAS,CAAC,mBAAmB,CAAC;yBAC1B,SAAS,CAAC,sBAAsB,CAAC;;KAErD,CAAC;IAEF,oFAAoF;IACpF,IAAI,CAAU;IAEd;;;;;OAKG;IACM,SAAS,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;QAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEM,iBAAiB;QACtB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAE1B,mFAAmF;QACnF,8EAA8E;QAC9E,kDAAkD;QAClD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1F,CAAC;IAEQ,oBAAoB;QACzB,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;QAC5B,KAAK,CAAC,oBAAoB,EAAE,CAAC;IACjC,CAAC;IAEQ,YAAY;QACjB,IAAI,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC;IAEQ,MAAM;QACX,OAAO,IAAI,CAAA;;;;;;;SAOV,CAAC;IACN,CAAC;IAED,4EAA4E;IAC5E,QAAQ,CAAC,IAAmB;QACxB,MAAM,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,mBAAmB,IAAI,IAAI,CAAC;QACvF,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAE3C,OAAO,KAAK,YAAY,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,CAAC;IAED;;;;;;;;;;;OAWG;IACH,QAAQ;QACJ,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEpC,gFAAgF;QAChF,6EAA6E;QAC7E,gFAAgF;QAChF,6EAA6E;QAC7E,8BAA8B;QAC9B,IAAI,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;YACzC,OAAO,OAAO,CAAC;QACnB,CAAC;QAED,OAAO,OAAO,EAAE,aAAa,CAAC,yBAAyB,CAAC,IAAI,OAAO,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,UAAU;QACN,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAEhC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO;QACX,CAAC;QAED,mFAAmF;QACnF,iFAAiF;QACjF,+EAA+E;QAC/E,kFAAkF;QAClF,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAE7D,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACpB,OAAO,CAAC,EAAE,GAAG,GAAG,GAAG,UAAU,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;QAE5D,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;QAEtE,kFAAkF;QAClF,6EAA6E;QAC7E,EAAE;QACF,oFAAoF;QACpF,oFAAoF;QACpF,+EAA+E;QAC/E,uBAAuB;QACvB,EAAE;QACF,mFAAmF;QACnF,+EAA+E;QAC/E,iFAAiF;QACjF,kFAAkF;QAClF,mFAAmF;QACnF,0DAA0D;QAC1D,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CACjF,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,CAC3B,CAAC;QAEF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,YAAY,CAAC,kBAAkB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAoB,EAAE,GAAW,EAAE,IAA4B;QACpE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,GAAG,OAAO,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC;QAElE,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;aAClD,KAAK,CAAC,GAAG,CAAC;aACV,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,KAAK,CAAC,OAAoB,EAAE,KAA8B,EAAE,UAAkB;QAC1E,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;YACtB,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;gBACpC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC;YAC/B,CAAC;YAED,OAAO;QACX,CAAC;QAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO,CAAC,eAAe,CAAC,iBAAiB,CAAC,CAAC;YAE3C,OAAO;QACX,CAAC;QAED,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YAClB,KAAK,CAAC,EAAE,GAAG,UAAU,CAAC;QAC1B,CAAC;QAED,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,OAAgC,EAAE,UAAkB;QAC3D,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC7D,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACpB,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC;QAC5B,CAAC;QAED,OAAO,OAAO,CAAC,EAAE,CAAC;IACtB,CAAC;;AAGL,yFAAyF;AACzF,yFAAyF;AACzF,yFAAyF;AACzF,oEAAoE;AACpE,cAAc,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"field.js","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"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"}
package/dist/radio.d.ts CHANGED
@@ -84,8 +84,8 @@ export declare class UiRadioGroup extends LitElement {
84
84
  * which lands before this element's. Set a microtask later, the role would arrive
85
85
  * after the only reader that needs it.
86
86
  *
87
- * A `role` the host wrote is never overwritten, the same way `<ui-switch>` never
88
- * overwrites one on the control it announces.
87
+ * A `role` the host wrote is never overwritten, the same courtesy {@link UiField}
88
+ * extends to an `id` it finds already there.
89
89
  */
90
90
  connectedCallback(): void;
91
91
  /**
package/dist/radio.js CHANGED
@@ -258,8 +258,8 @@ export class UiRadioGroup extends LitElement {
258
258
  * which lands before this element's. Set a microtask later, the role would arrive
259
259
  * after the only reader that needs it.
260
260
  *
261
- * A `role` the host wrote is never overwritten, the same way `<ui-switch>` never
262
- * overwrites one on the control it announces.
261
+ * A `role` the host wrote is never overwritten, the same courtesy {@link UiField}
262
+ * extends to an `id` it finds already there.
263
263
  */
264
264
  connectedCallback() {
265
265
  super.connectedCallback();
package/dist/tooltip.js CHANGED
@@ -207,7 +207,7 @@ export class UiTooltip extends LitElement {
207
207
  * one that stops being announced at a moment nothing reports.
208
208
  *
209
209
  * A `role` or an `id` the host wrote is never overwritten, the same courtesy
210
- * `<ui-field>` and `<ui-switch>` extend. `aria-describedby` is **added to** rather than
210
+ * `<ui-field>` and `<ui-radio-group>` extend. `aria-describedby` is **added to** rather than
211
211
  * replaced: the trigger may already be described by a field's help text, and a
212
212
  * description that silently replaced another is the failure nobody sees.
213
213
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rak200/ui",
3
- "version": "0.2.18",
3
+ "version": "0.3.0",
4
4
  "description": "Host-agnostic custom-element UI components for the rak200 ecosystem",
5
5
  "license": "MIT",
6
6
  "author": "rak200 <rak.ricardo@windowslive.com>",
@@ -54,7 +54,7 @@
54
54
  "lit": "^3.3.3"
55
55
  },
56
56
  "devDependencies": {
57
- "@rak200/coding-standard-ts": "github:rak200/coding-standard-ts#0.4.7",
57
+ "@rak200/coding-standard-ts": "github:rak200/coding-standard-ts#0.4.8",
58
58
  "@storybook/addon-a11y": "^10.5.8",
59
59
  "@storybook/web-components-vite": "^10.5.8",
60
60
  "@types/node": "^26.1.2",