@typed/ui 1.0.0-beta.5 → 1.0.0-beta.7

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 (128) hide show
  1. package/dist/Alert.d.ts +35 -41
  2. package/dist/Alert.d.ts.map +1 -1
  3. package/dist/Alert.js +23 -20
  4. package/dist/Button.d.ts +34 -78
  5. package/dist/Button.d.ts.map +1 -1
  6. package/dist/Button.js +16 -12
  7. package/dist/Carousel.d.ts +35 -236
  8. package/dist/Carousel.d.ts.map +1 -1
  9. package/dist/Carousel.js +13 -136
  10. package/dist/Checkbox.d.ts +55 -90
  11. package/dist/Checkbox.d.ts.map +1 -1
  12. package/dist/Checkbox.js +44 -38
  13. package/dist/Collection.d.ts +15 -15
  14. package/dist/Collection.js +7 -7
  15. package/dist/Combobox.d.ts +38 -187
  16. package/dist/Combobox.d.ts.map +1 -1
  17. package/dist/Combobox.js +9 -80
  18. package/dist/Component.d.ts +30 -24
  19. package/dist/Component.d.ts.map +1 -1
  20. package/dist/Component.js +23 -12
  21. package/dist/Composite.d.ts +50 -50
  22. package/dist/Composite.js +20 -20
  23. package/dist/Dialog.d.ts +34 -34
  24. package/dist/Dialog.d.ts.map +1 -1
  25. package/dist/Dialog.js +16 -14
  26. package/dist/Disclosure.d.ts +15 -15
  27. package/dist/Disclosure.js +6 -6
  28. package/dist/Dom/Events.d.ts +4 -4
  29. package/dist/Dom/Events.js +4 -4
  30. package/dist/Dom/Props.d.ts +9 -9
  31. package/dist/Dom/Props.js +4 -4
  32. package/dist/Dom/Refs.d.ts +2 -2
  33. package/dist/Dom/Refs.js +1 -1
  34. package/dist/Dom/Render.d.ts +2 -2
  35. package/dist/Dom/Render.js +2 -2
  36. package/dist/Dom/Types.d.ts +33 -33
  37. package/dist/Dom/index.d.ts +5 -5
  38. package/dist/Dom/index.d.ts.map +1 -1
  39. package/dist/Dom/index.js +4 -4
  40. package/dist/Dom.d.ts +1 -1
  41. package/dist/Dom.js +1 -1
  42. package/dist/Focusable.d.ts +5 -5
  43. package/dist/Focusable.js +1 -1
  44. package/dist/Form.d.ts +565 -533
  45. package/dist/Form.d.ts.map +1 -1
  46. package/dist/Form.js +350 -195
  47. package/dist/Grid.d.ts +39 -220
  48. package/dist/Grid.d.ts.map +1 -1
  49. package/dist/Grid.js +12 -107
  50. package/dist/Group.d.ts +50 -69
  51. package/dist/Group.d.ts.map +1 -1
  52. package/dist/Group.js +33 -25
  53. package/dist/Heading.d.ts +41 -40
  54. package/dist/Heading.d.ts.map +1 -1
  55. package/dist/Heading.js +26 -16
  56. package/dist/Hovercard.d.ts +18 -18
  57. package/dist/Hovercard.js +6 -6
  58. package/dist/HttpRouter.d.ts +3 -3
  59. package/dist/HttpRouter.js +5 -5
  60. package/dist/Link.d.ts +17 -21
  61. package/dist/Link.d.ts.map +1 -1
  62. package/dist/Link.js +11 -0
  63. package/dist/Listbox.d.ts +31 -163
  64. package/dist/Listbox.d.ts.map +1 -1
  65. package/dist/Listbox.js +9 -80
  66. package/dist/Menu.d.ts +67 -376
  67. package/dist/Menu.d.ts.map +1 -1
  68. package/dist/Menu.js +17 -179
  69. package/dist/Menubar.d.ts +24 -142
  70. package/dist/Menubar.d.ts.map +1 -1
  71. package/dist/Menubar.js +8 -66
  72. package/dist/Meter.d.ts +72 -132
  73. package/dist/Meter.d.ts.map +1 -1
  74. package/dist/Meter.js +35 -42
  75. package/dist/NativeDetails.d.ts +1 -1
  76. package/dist/NativeDetails.js +1 -1
  77. package/dist/NativeDialog.d.ts +7 -5
  78. package/dist/NativeDialog.d.ts.map +1 -1
  79. package/dist/NativeDialog.js +42 -4
  80. package/dist/NativePopover.d.ts +6 -4
  81. package/dist/NativePopover.d.ts.map +1 -1
  82. package/dist/NativePopover.js +43 -5
  83. package/dist/Popover.d.ts +18 -19
  84. package/dist/Popover.d.ts.map +1 -1
  85. package/dist/Popover.js +7 -8
  86. package/dist/RadioGroup.d.ts +86 -188
  87. package/dist/RadioGroup.d.ts.map +1 -1
  88. package/dist/RadioGroup.js +55 -105
  89. package/dist/Role.d.ts +4 -4
  90. package/dist/Role.js +1 -1
  91. package/dist/Select.d.ts +109 -220
  92. package/dist/Select.d.ts.map +1 -1
  93. package/dist/Select.js +67 -117
  94. package/dist/Separator.d.ts +30 -26
  95. package/dist/Separator.d.ts.map +1 -1
  96. package/dist/Separator.js +16 -10
  97. package/dist/Slider.d.ts +64 -111
  98. package/dist/Slider.d.ts.map +1 -1
  99. package/dist/Slider.js +47 -42
  100. package/dist/SpinButton.d.ts +64 -111
  101. package/dist/SpinButton.d.ts.map +1 -1
  102. package/dist/SpinButton.js +47 -42
  103. package/dist/Storybook.d.ts +2 -2
  104. package/dist/Storybook.js +1 -1
  105. package/dist/Switch.d.ts +52 -91
  106. package/dist/Switch.d.ts.map +1 -1
  107. package/dist/Switch.js +30 -36
  108. package/dist/Tabs.d.ts +44 -224
  109. package/dist/Tabs.d.ts.map +1 -1
  110. package/dist/Tabs.js +10 -94
  111. package/dist/Toolbar.d.ts +24 -142
  112. package/dist/Toolbar.d.ts.map +1 -1
  113. package/dist/Toolbar.js +8 -66
  114. package/dist/Tooltip.d.ts +20 -20
  115. package/dist/Tooltip.js +6 -6
  116. package/dist/Tree.d.ts +43 -229
  117. package/dist/Tree.d.ts.map +1 -1
  118. package/dist/Tree.js +12 -113
  119. package/dist/TreeGrid.d.ts +45 -264
  120. package/dist/TreeGrid.d.ts.map +1 -1
  121. package/dist/TreeGrid.js +13 -125
  122. package/dist/VisuallyHidden.d.ts +41 -27
  123. package/dist/VisuallyHidden.d.ts.map +1 -1
  124. package/dist/VisuallyHidden.js +27 -10
  125. package/dist/WindowSplitter.d.ts +68 -108
  126. package/dist/WindowSplitter.d.ts.map +1 -1
  127. package/dist/WindowSplitter.js +106 -23
  128. package/package.json +9 -8
package/dist/Grid.js CHANGED
@@ -8,6 +8,8 @@
8
8
  * the state and pure operations without mounting UI, or supply custom hosts without replacing native
9
9
  * events and browser-owned focus.
10
10
  *
11
+ * Learn the interaction in the [Grid guide](/explore/ui-grid).
12
+ *
11
13
  * @since 1.0.0
12
14
  * @category modules
13
15
  * @packageDocumentation
@@ -22,15 +24,6 @@ import * as Dom from "./Dom.js";
22
24
  * Effect Schema used by makeState to encode, decode, and hydrate Grid state.
23
25
  *
24
26
  * @remarks
25
- * ## Why
26
- *
27
- * A public schema makes hydration and serialized state use the same runtime validation as direct
28
- * construction.
29
- *
30
- * ## Ownership and lifetime
31
- *
32
- * This declaration is data or schema metadata and acquires no resources.
33
- *
34
27
  * @example
35
28
  * ```ts
36
29
  * import * as Schema from "effect/Schema";
@@ -39,19 +32,13 @@ import * as Dom from "./Dom.js";
39
32
  * const decodeState = Schema.decodeUnknownEffect(Grid.StateSchema);
40
33
  * ```
41
34
  * @since 1.0.0
42
- * @category schemas
35
+ * @category Cell focus
43
36
  */
44
37
  export const StateSchema = Schema.Struct({ activeId: Schema.NullOr(Schema.String) });
45
38
  /**
46
39
  * Creates hydrated Grid state. activeId defaults to null.
47
40
  *
48
41
  * @remarks
49
- * ## Why
50
- *
51
- * State and collection ownership can be composed and tested independently from any renderer.
52
- *
53
- * ## Ownership and lifetime
54
- *
55
42
  * The returned Effect creates the RefSubject when run. That state is renderer-independent;
56
43
  * collection registrations belong to the separate Scope that runs register or ref, not to state
57
44
  * creation.
@@ -70,7 +57,7 @@ export const StateSchema = Schema.Struct({ activeId: Schema.NullOr(Schema.String
70
57
  * );
71
58
  * ```
72
59
  * @since 1.0.0
73
- * @category constructors
60
+ * @category Cell focus
74
61
  */
75
62
  export function makeState(initial = {}) {
76
63
  return RefSubject.hydrate(StateSchema, { activeId: initial.activeId ?? null });
@@ -79,12 +66,6 @@ export function makeState(initial = {}) {
79
66
  * Creates a scoped Collection for Grid items.
80
67
  *
81
68
  * @remarks
82
- * ## Why
83
- *
84
- * State and collection ownership can be composed and tested independently from any renderer.
85
- *
86
- * ## Ownership and lifetime
87
- *
88
69
  * The returned Effect allocates the RefSubject in the caller's Scope. Each later registration is
89
70
  * owned by the Scope that runs register, independently of this construction Effect.
90
71
  *
@@ -101,31 +82,18 @@ export function makeState(initial = {}) {
101
82
  * );
102
83
  * ```
103
84
  * @since 1.0.0
104
- * @category constructors
85
+ * @category Cell registration
105
86
  */
106
87
  export const makeCollection = Collection.makeState;
107
88
  /**
108
89
  * Sets activeId, including null to clear virtual focus.
109
90
  *
110
91
  * @remarks
111
- * ## Why
112
- *
113
92
  * The operation exposes Grid's transition directly so callers can compose it in Effect programs
114
93
  * and native event handlers.
115
94
  *
116
- * ## Ownership and lifetime
117
- *
118
- * The returned Effect performs the update or DOM side effect only when run, preserves the declared
119
- * error and service channels, and retains no resources after completion.
120
- *
121
- * ## Example
122
- *
123
- * Import with `import { activate } from "@typed/ui/Grid";` Extend the [Grid.makeState runnable
124
- * setup](/reference/%40typed%2Fui%2FGrid%23makeState). Inside the linked Effect program invoke
125
- * `yield* activate(state, "item-2")`, then read the state snapshot to observe the transition
126
- * described above.
127
95
  * @since 1.0.0
128
- * @category combinators
96
+ * @category Cell focus
129
97
  */
130
98
  export function activate(state, activeId) {
131
99
  return RefSubject.update(state, (current) => ({ ...current, activeId }));
@@ -159,25 +127,12 @@ function rootInternalProps(options) {
159
127
  * focus.
160
128
  *
161
129
  * @remarks
162
- * ## Why
163
- *
164
- * The component applies the family behavior while leaving callers free to supply a custom host
165
- * through the shared DOM boundary.
166
- *
167
- * ## Ownership and lifetime
168
- *
169
130
  * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
170
131
  * collection registrations only when rendered. The rendering Scope removes those resources;
171
132
  * unrelated nodes and attributes remain caller-owned.
172
133
  *
173
- * ## Example
174
- *
175
- * Import with `import { Root } from "@typed/ui/Grid";` Extend the [Grid.makeState runnable
176
- * setup](/reference/%40typed%2Fui%2FGrid%23makeState). Replace the linked program's final snapshot
177
- * read with `Root({ state, label: "Schedule", content: "Rows" })`; render that Fx before the same
178
- * Scope closes.
179
134
  * @since 1.0.0
180
- * @category components
135
+ * @category Grid surface
181
136
  */
182
137
  export function Root(options, host) {
183
138
  return Dom.renderHost()(options, host, rootInternalProps(options), options.content, (props, content) => {
@@ -191,13 +146,6 @@ function rowInternalProps({ property, }) {
191
146
  * Renders an ARIA row and forwards an optional one-based aria-rowindex.
192
147
  *
193
148
  * @remarks
194
- * ## Why
195
- *
196
- * The component applies the family behavior while leaving callers free to supply a custom host
197
- * through the shared DOM boundary.
198
- *
199
- * ## Ownership and lifetime
200
- *
201
149
  * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
202
150
  * collection registrations only when rendered. The rendering Scope removes those resources;
203
151
  * unrelated nodes and attributes remain caller-owned.
@@ -209,7 +157,7 @@ function rowInternalProps({ property, }) {
209
157
  * const view = Grid.Row({ rowIndex: 1, content: "Cells" });
210
158
  * ```
211
159
  * @since 1.0.0
212
- * @category components
160
+ * @category Rows
213
161
  */
214
162
  export function Row(options, host) {
215
163
  return Dom.renderHost()(options, host, rowInternalProps, options.content, (props, content) => html `<div ...${props}>${content}</div>`);
@@ -242,25 +190,12 @@ function cell(options, host, role) {
242
190
  * Renders and optionally registers a gridcell with row and column coordinates.
243
191
  *
244
192
  * @remarks
245
- * ## Why
246
- *
247
- * The component applies the family behavior while leaving callers free to supply a custom host
248
- * through the shared DOM boundary.
249
- *
250
- * ## Ownership and lifetime
251
- *
252
193
  * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
253
194
  * collection registrations only when rendered. The rendering Scope removes those resources;
254
195
  * unrelated nodes and attributes remain caller-owned.
255
196
  *
256
- * ## Example
257
- *
258
- * Import with `import { Cell } from "@typed/ui/Grid";` Extend the [Grid.makeState runnable
259
- * setup](/reference/%40typed%2Fui%2FGrid%23makeState). Replace the linked program's final snapshot
260
- * read with `Cell({ state, id: "r1c1", rowId: "r1", columnIndex: 1, content: "Monday" })`; render
261
- * that Fx before the same Scope closes.
262
197
  * @since 1.0.0
263
- * @category components
198
+ * @category Cells and headers
264
199
  */
265
200
  export function Cell(options, host) {
266
201
  return cell(options, host, "gridcell");
@@ -269,25 +204,12 @@ export function Cell(options, host) {
269
204
  * Renders the Cell contract with the columnheader role.
270
205
  *
271
206
  * @remarks
272
- * ## Why
273
- *
274
- * The component applies the family behavior while leaving callers free to supply a custom host
275
- * through the shared DOM boundary.
276
- *
277
- * ## Ownership and lifetime
278
- *
279
207
  * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
280
208
  * collection registrations only when rendered. The rendering Scope removes those resources;
281
209
  * unrelated nodes and attributes remain caller-owned.
282
210
  *
283
- * ## Example
284
- *
285
- * Import with `import { ColumnHeader } from "@typed/ui/Grid";` Extend the [Grid.makeState runnable
286
- * setup](/reference/%40typed%2Fui%2FGrid%23makeState). Replace the linked program's final snapshot
287
- * read with `ColumnHeader({ state, id: "day", rowId: "headers", columnIndex: 1, content: "Day" })`;
288
- * render that Fx before the same Scope closes.
289
211
  * @since 1.0.0
290
- * @category components
212
+ * @category Cells and headers
291
213
  */
292
214
  export function ColumnHeader(options, host) {
293
215
  return cell(options, host, "columnheader");
@@ -296,25 +218,12 @@ export function ColumnHeader(options, host) {
296
218
  * Renders the Cell contract with the rowheader role.
297
219
  *
298
220
  * @remarks
299
- * ## Why
300
- *
301
- * The component applies the family behavior while leaving callers free to supply a custom host
302
- * through the shared DOM boundary.
303
- *
304
- * ## Ownership and lifetime
305
- *
306
221
  * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
307
222
  * collection registrations only when rendered. The rendering Scope removes those resources;
308
223
  * unrelated nodes and attributes remain caller-owned.
309
224
  *
310
- * ## Example
311
- *
312
- * Import with `import { RowHeader } from "@typed/ui/Grid";` Extend the [Grid.makeState runnable
313
- * setup](/reference/%40typed%2Fui%2FGrid%23makeState). Replace the linked program's final snapshot
314
- * read with `RowHeader({ state, id: "week-1", rowId: "week-1", columnIndex: 1, content: "Week 1"
315
- * })`; render that Fx before the same Scope closes.
316
225
  * @since 1.0.0
317
- * @category components
226
+ * @category Cells and headers
318
227
  */
319
228
  export function RowHeader(options, host) {
320
229
  return cell(options, host, "rowheader");
@@ -334,13 +243,9 @@ function onKeyDown(state, collection, event) {
334
243
  * in-column, and Ctrl+Home/End reaches grid endpoints.
335
244
  *
336
245
  * @remarks
337
- * ## Why
338
- *
339
246
  * Separating this deterministic policy from event wiring lets applications test it directly and
340
247
  * reuse it in custom composites.
341
248
  *
342
- * ## Ownership and lifetime
343
- *
344
249
  * This is a synchronous calculation. It acquires no resources and does not mutate the input array,
345
250
  * state, event, or DOM.
346
251
  *
@@ -351,7 +256,7 @@ function onKeyDown(state, collection, event) {
351
256
  * const nextId = Grid.moveActiveId([{ id: "a", value: { rowId: "r1", columnIndex: 1 } }], "a", { key: "ArrowRight", ctrlKey: false });
352
257
  * ```
353
258
  * @since 1.0.0
354
- * @category combinators
259
+ * @category Spatial navigation
355
260
  */
356
261
  export function moveActiveId(items, activeId, event) {
357
262
  if (items.length === 0)
package/dist/Group.d.ts CHANGED
@@ -1,15 +1,12 @@
1
1
  /**
2
- * Group supplies a neutral ARIA group host and an optional label host. Callers retain the normal
3
- * Dom host-override contract and must provide either an accessible label or a labelled-by
4
- * relationship where the surrounding widget requires one.
2
+ * Explicitly named collections of related content.
3
+ * Group.Label is a span; connect its ID through labelledBy rather than assuming implicit wiring.
5
4
  *
6
- * @remarks
7
- * The module keeps policy, state transitions, and DOM rendering separable so applications can use
8
- * the state and pure operations without mounting UI, or supply custom hosts without replacing native
9
- * events and browser-owned focus.
5
+ * Read the [Group guide](/explore/ui-group) for a complete example.
10
6
  *
7
+ * [Platform reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/group_role).
11
8
  * @since 1.0.0
12
- * @category modules
9
+ * @category Overview
13
10
  * @packageDocumentation
14
11
  */
15
12
  import type * as Scope from "effect/Scope";
@@ -18,43 +15,31 @@ import { type Renderable, type RenderEvent, type RenderTemplate } from "@typed/t
18
15
  import * as Dom from "./Dom.js";
19
16
  import type { HostResult } from "./Dom/Types.js";
20
17
  /**
21
- * Inputs accepted by Group.Group in addition to the shared DOM host options.
18
+ * Related content with either a direct accessible label or an external label ID.
22
19
  *
23
20
  * @remarks
24
- * ## Why
25
- *
26
- * The options type makes required state, content, accessible relationships, and custom-host inputs
27
- * visible before rendering.
28
- *
29
- * ## Ownership and lifetime
30
- *
31
- * This declaration is data or schema metadata and acquires no resources.
32
- *
33
- * ## Example
34
- *
35
- * Import with `import type { GroupOptions } from "@typed/ui/Group";` Extend the [Group.Group
36
- * runnable setup](/reference/%40typed%2Fui%2FGroup%23Group). A labeled group host accepts
37
- * `const options: GroupOptions = { label: "Formatting", content: "Controls" }`.
21
+ * Use labelledBy when visible text already names the group; use label when that text is absent.
22
+ * Native fieldset/legend and composite keyboard behavior are not created by these options.
38
23
  * @since 1.0.0
39
- * @category models
24
+ * @category Component options
40
25
  */
41
26
  export interface GroupOptions extends Dom.HostOptions<HTMLDivElement> {
42
27
  /**
43
28
  * Renderable child content for the component host.
44
29
  * @since 1.0.0
45
- * @category models
30
+ * @category Rendered content
46
31
  */
47
32
  readonly content: Renderable.Any;
48
33
  /**
49
34
  * Accessible label rendered through aria-label.
50
35
  * @since 1.0.0
51
- * @category models
36
+ * @category Accessible naming
52
37
  */
53
38
  readonly label?: Renderable.Any<string | null | undefined>;
54
39
  /**
55
40
  * Id of the external element used through aria-labelledby.
56
41
  * @since 1.0.0
57
- * @category models
42
+ * @category Accessible naming
58
43
  */
59
44
  readonly labelledBy?: Renderable.Any<string | null | undefined>;
60
45
  }
@@ -65,73 +50,69 @@ declare function internalProps<const Options extends GroupOptions>({ property }:
65
50
  };
66
51
  type GroupInternalProps<Options extends GroupOptions> = ReturnType<typeof internalProps<Options>>;
67
52
  /**
68
- * Renders a div host with role=group and caller-controlled aria-label or aria-labelledby.
53
+ * Renders a semantic group with an explicit accessible name.
69
54
  *
70
55
  * @remarks
71
- * ## Why
72
- *
73
- * The component applies the family behavior while leaving callers free to supply a custom host
74
- * through the shared DOM boundary.
75
- *
76
- * ## Ownership and lifetime
77
- *
78
- * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
79
- * collection registrations only when rendered. The rendering Scope removes those resources;
80
- * unrelated nodes and attributes remain caller-owned.
56
+ * label becomes aria-label; labelledBy references existing visible text through aria-labelledby.
57
+ * The div does not implement fieldset disabling, toolbar navigation, or child selection. Name
58
+ * each interactive child independently.
81
59
  *
82
60
  * @example
83
61
  * ```ts
62
+ * import { RefSubject } from "@typed/fx";
63
+ * import { html } from "@typed/template";
64
+ * import { Button } from "@typed/ui/Button";
65
+ * import { component } from "@typed/ui/Component";
84
66
  * import * as Group from "@typed/ui/Group";
85
67
  *
86
- * const view = Group.Group({ label: "Formatting", content: "Controls" });
68
+ * export const PreviewActions = component(function* () {
69
+ * const rotation = yield* RefSubject.make(45);
70
+ * const scale = yield* RefSubject.make(150);
71
+ * return html`<section>
72
+ * <p>Rotation: ${rotation} degrees. Scale: ${scale}%.</p>
73
+ * ${Group.Label({
74
+ * content: "Preview controls",
75
+ * props: { id: "preview-control-label", class: "control-group-label" },
76
+ * })}
77
+ * ${Group.Group({
78
+ * labelledBy: "preview-control-label",
79
+ * props: { class: "preview-actions" },
80
+ * content: [
81
+ * Button({ content: "Reset rotation", onclick: RefSubject.set(rotation, 0) }),
82
+ * Button({ content: "Reset scale", onclick: RefSubject.set(scale, 100) }),
83
+ * ],
84
+ * })}
85
+ * </section>`;
86
+ * });
87
87
  * ```
88
88
  * @since 1.0.0
89
- * @category components
89
+ * @category Structure and naming
90
90
  */
91
91
  export declare function Group<const Options extends GroupOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, GroupInternalProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
92
92
  /**
93
- * Inputs accepted by Group.Label in addition to the shared DOM host options.
93
+ * Visible span content and host props for an explicitly linked group label.
94
94
  *
95
95
  * @remarks
96
- * ## Why
97
- *
98
- * The options type makes required state, content, accessible relationships, and custom-host inputs
99
- * visible before rendering.
100
- *
101
- * ## Ownership and lifetime
102
- *
103
- * This declaration is data or schema metadata and acquires no resources.
104
- *
105
- * ## Example
106
- *
107
- * Import with `import type { LabelOptions } from "@typed/ui/Group";` Extend the [Group.Group
108
- * runnable setup](/reference/%40typed%2Fui%2FGroup%23Group). A visible group label accepts
109
- * `const options: LabelOptions = { content: "Formatting" }`.
96
+ * Set props.id and reference it through Group.labelledBy. There is no generated ID or implicit
97
+ * relationship.
110
98
  * @since 1.0.0
111
- * @category models
99
+ * @category Component options
112
100
  */
113
101
  export interface LabelOptions extends Dom.HostOptions<HTMLSpanElement> {
114
102
  /**
115
103
  * Renderable child content for the component host.
116
104
  * @since 1.0.0
117
- * @category models
105
+ * @category Rendered content
118
106
  */
119
107
  readonly content: Renderable.Any;
120
108
  }
121
109
  /**
122
- * Renders the group's visible label content without inventing an implicit id relationship.
110
+ * Renders visible group-label text in a span.
123
111
  *
124
112
  * @remarks
125
- * ## Why
126
- *
127
- * The component applies the family behavior while leaving callers free to supply a custom host
128
- * through the shared DOM boundary.
129
- *
130
- * ## Ownership and lifetime
131
- *
132
- * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
133
- * collection registrations only when rendered. The rendering Scope removes those resources;
134
- * unrelated nodes and attributes remain caller-owned.
113
+ * Pass an ID through props and reference it from Group.labelledBy to create a relationship.
114
+ * Rendering this span beside a group does not connect them automatically, and it does not create
115
+ * heading semantics.
135
116
  *
136
117
  * @example
137
118
  * ```ts
@@ -140,7 +121,7 @@ export interface LabelOptions extends Dom.HostOptions<HTMLSpanElement> {
140
121
  * const view = Group.Label({ content: "Formatting" });
141
122
  * ```
142
123
  * @since 1.0.0
143
- * @category components
124
+ * @category Controls
144
125
  */
145
126
  export declare function Label<const Options extends LabelOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, Record<never, never>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
146
127
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"Group.d.ts","sourceRoot":"","sources":["../src/Group.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAQ,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,YAAa,SAAQ,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC;IACnE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACjE;AAED,iBAAS,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,YAAY,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC;IAEtG,IAAI;IACJ,YAAY;IACZ,iBAAiB;EAEpB;AAED,KAAK,kBAAkB,CAAC,OAAO,SAAS,YAAY,IAAI,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AAElG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,YAAY,EAAE,KAAK,CAAC,IAAI,SAAS,UAAU,GAAG,KAAK,EAC7F,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,GAC3G,EAAE,CACH,WAAW,EACX,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,EAChC,UAAU,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,cAAc,CACnE,CAQA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,YAAa,SAAQ,GAAG,CAAC,WAAW,CAAC,eAAe,CAAC;IACpE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,YAAY,EAAE,KAAK,CAAC,IAAI,SAAS,UAAU,GAAG,KAAK,EAC7F,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,GACpG,EAAE,CACH,WAAW,EACX,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,EAChC,UAAU,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,cAAc,CACnE,CAQA"}
1
+ {"version":3,"file":"Group.d.ts","sourceRoot":"","sources":["../src/Group.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAQ,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAa,SAAQ,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC;IACnE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC;IACjC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACjE;AAED,iBAAS,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,YAAY,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC;IAEtG,IAAI;IACJ,YAAY;IACZ,iBAAiB;EAEpB;AAED,KAAK,kBAAkB,CAAC,OAAO,SAAS,YAAY,IAAI,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AAElG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,YAAY,EAAE,KAAK,CAAC,IAAI,SAAS,UAAU,GAAG,KAAK,EAC7F,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,GAC3G,EAAE,CACH,WAAW,EACX,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,EAChC,UAAU,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,cAAc,CACnE,CAQA;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAa,SAAQ,GAAG,CAAC,WAAW,CAAC,eAAe,CAAC;IACpE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,YAAY,EAAE,KAAK,CAAC,IAAI,SAAS,UAAU,GAAG,KAAK,EAC7F,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,GACpG,EAAE,CACH,WAAW,EACX,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,EAChC,UAAU,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,cAAc,CACnE,CAQA"}
package/dist/Group.js CHANGED
@@ -8,46 +8,54 @@ function internalProps({ property }) {
8
8
  };
9
9
  }
10
10
  /**
11
- * Renders a div host with role=group and caller-controlled aria-label or aria-labelledby.
11
+ * Renders a semantic group with an explicit accessible name.
12
12
  *
13
13
  * @remarks
14
- * ## Why
15
- *
16
- * The component applies the family behavior while leaving callers free to supply a custom host
17
- * through the shared DOM boundary.
18
- *
19
- * ## Ownership and lifetime
20
- *
21
- * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
22
- * collection registrations only when rendered. The rendering Scope removes those resources;
23
- * unrelated nodes and attributes remain caller-owned.
14
+ * label becomes aria-label; labelledBy references existing visible text through aria-labelledby.
15
+ * The div does not implement fieldset disabling, toolbar navigation, or child selection. Name
16
+ * each interactive child independently.
24
17
  *
25
18
  * @example
26
19
  * ```ts
20
+ * import { RefSubject } from "@typed/fx";
21
+ * import { html } from "@typed/template";
22
+ * import { Button } from "@typed/ui/Button";
23
+ * import { component } from "@typed/ui/Component";
27
24
  * import * as Group from "@typed/ui/Group";
28
25
  *
29
- * const view = Group.Group({ label: "Formatting", content: "Controls" });
26
+ * export const PreviewActions = component(function* () {
27
+ * const rotation = yield* RefSubject.make(45);
28
+ * const scale = yield* RefSubject.make(150);
29
+ * return html`<section>
30
+ * <p>Rotation: ${rotation} degrees. Scale: ${scale}%.</p>
31
+ * ${Group.Label({
32
+ * content: "Preview controls",
33
+ * props: { id: "preview-control-label", class: "control-group-label" },
34
+ * })}
35
+ * ${Group.Group({
36
+ * labelledBy: "preview-control-label",
37
+ * props: { class: "preview-actions" },
38
+ * content: [
39
+ * Button({ content: "Reset rotation", onclick: RefSubject.set(rotation, 0) }),
40
+ * Button({ content: "Reset scale", onclick: RefSubject.set(scale, 100) }),
41
+ * ],
42
+ * })}
43
+ * </section>`;
44
+ * });
30
45
  * ```
31
46
  * @since 1.0.0
32
- * @category components
47
+ * @category Structure and naming
33
48
  */
34
49
  export function Group(options, host) {
35
50
  return Dom.renderHost()(options, host, internalProps, options.content, (props, content) => html `<div ...${props}>${content}</div>`);
36
51
  }
37
52
  /**
38
- * Renders the group's visible label content without inventing an implicit id relationship.
53
+ * Renders visible group-label text in a span.
39
54
  *
40
55
  * @remarks
41
- * ## Why
42
- *
43
- * The component applies the family behavior while leaving callers free to supply a custom host
44
- * through the shared DOM boundary.
45
- *
46
- * ## Ownership and lifetime
47
- *
48
- * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
49
- * collection registrations only when rendered. The rendering Scope removes those resources;
50
- * unrelated nodes and attributes remain caller-owned.
56
+ * Pass an ID through props and reference it from Group.labelledBy to create a relationship.
57
+ * Rendering this span beside a group does not connect them automatically, and it does not create
58
+ * heading semantics.
51
59
  *
52
60
  * @example
53
61
  * ```ts
@@ -56,7 +64,7 @@ export function Group(options, host) {
56
64
  * const view = Group.Label({ content: "Formatting" });
57
65
  * ```
58
66
  * @since 1.0.0
59
- * @category components
67
+ * @category Controls
60
68
  */
61
69
  export function Label(options, host) {
62
70
  return Dom.renderHost()(options, host, () => ({}), options.content, (props, content) => html `<span ...${props}>${content}</span>`);
package/dist/Heading.d.ts CHANGED
@@ -1,38 +1,29 @@
1
+ /**
2
+ * Contextual heading semantics independent of typography.
3
+ * The default div uses role=heading and aria-level; fixed native headings remain useful.
4
+ *
5
+ * Read the [Heading guide](/explore/ui-heading) for a complete example.
6
+ *
7
+ * [Platform reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/heading_role).
8
+ * @since 1.0.0
9
+ * @category Overview
10
+ * @packageDocumentation
11
+ */
1
12
  import type * as Scope from "effect/Scope";
2
13
  import type { Fx } from "@typed/fx/Fx";
3
14
  import { type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
4
15
  import * as Dom from "./Dom.js";
5
16
  import type { HostResult } from "./Dom/Types.js";
6
17
  /**
7
- * Options for an ARIA heading whose level may be reactive.
8
- * @remarks
9
- * ## Why
10
- * Separating heading semantics from a fixed tag supports reusable components
11
- * whose outline level is selected by their context.
12
- * ## Ownership and lifetime
13
- * The options are inert; rendering owns dynamic values for its Scope.
14
- * @since 1.0.0
15
- * @category models
16
18
  */
17
19
  export interface HeadingOptions extends Dom.HostOptions<HTMLDivElement> {
18
- /** Heading content and accessible name.
19
- * @remarks
20
- * ## Why
21
- * Visible content participates directly in the accessibility tree.
22
- * ## Ownership and lifetime
23
- * Dynamic content follows the rendered Scope.
20
+ /**
21
+ * Heading content and accessible name.
24
22
  * @since 1.0.0
25
- * @category content
23
+ * @category Rendered content
26
24
  */
27
25
  readonly content: Renderable.Any;
28
- /** ARIA heading level, defaulting to one.
29
- * @remarks
30
- * ## Why
31
- * The level communicates document hierarchy even when the host tag is fixed.
32
- * ## Ownership and lifetime
33
- * The reflected value retains no resources.
34
- * @since 1.0.0
35
- * @category accessibility
26
+ /**
36
27
  */
37
28
  readonly level?: Renderable.Any<number | null | undefined>;
38
29
  }
@@ -42,44 +33,54 @@ declare function internalProps<const Options extends HeadingOptions>({ property,
42
33
  };
43
34
  type HeadingInternalProps<Options extends HeadingOptions> = ReturnType<typeof internalProps<Options>>;
44
35
  /**
45
- * Renders a host with `role="heading"` and a reactive `aria-level`.
36
+ * Renders a div with heading semantics and an explicit level.
37
+ *
46
38
  * @remarks
47
- * ## Why
48
- * The primitive lets a design system preserve document-outline semantics when
49
- * its visual host cannot be selected statically.
50
- * ## Ownership and lifetime
51
- * Running the returned Fx owns its dynamic attributes and content in an Effect
52
- * Scope. A custom host must preserve `role` and `aria-level`.
39
+ * level defaults to one and may be reactive; it does not choose font size, infer nesting, or
40
+ * validate the document outline. Use native h1–h6 markup when the level is fixed. A custom host
41
+ * must keep its native level and aria-level consistent.
42
+ *
53
43
  * @example
54
44
  * ```ts
55
- * import { Heading } from "@typed/ui/Heading"
45
+ * import { html } from "@typed/template";
46
+ * import { Heading } from "@typed/ui/Heading";
47
+ *
48
+ * export function AccountSection(level: 2 | 3) {
49
+ * return html`<section aria-labelledby="account-section-title">
50
+ * ${Heading({
51
+ * level,
52
+ * content: "Account security",
53
+ * props: { id: "account-section-title", class: "section-title" },
54
+ * })}
55
+ * <p>Review the devices and credentials that can access this account.</p>
56
+ * </section>`;
57
+ * }
56
58
  *
57
- * const title = Heading({ level: 3, content: "Details" })
59
+ * export const AccountPage = html`<main>
60
+ * <h1>Account settings</h1>
61
+ * ${AccountSection(2)}
62
+ * </main>`;
58
63
  * ```
59
64
  * @since 1.0.0
60
- * @category components
65
+ * @category Structure and naming
61
66
  */
62
67
  export declare function Heading<const Options extends HeadingOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, HeadingInternalProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
63
68
  /**
64
69
  * Alias for `Heading` retained for level-oriented imports.
65
70
  * @remarks
66
- * ## Why
67
71
  * The alias names the role the component plays in a contextual heading system.
68
- * ## Ownership and lifetime
69
72
  * It has exactly the same Scope and host ownership as `Heading`.
70
73
  * @since 1.0.0
71
- * @category aliases
74
+ * @category Aliases
72
75
  */
73
76
  export declare const Level: typeof Heading;
74
77
  /**
75
78
  * Descriptive alias for `Heading`.
76
79
  * @remarks
77
- * ## Why
78
80
  * The name remains available without duplicating an implementation contract.
79
- * ## Ownership and lifetime
80
81
  * It has exactly the same Scope and host ownership as `Heading`.
81
82
  * @since 1.0.0
82
- * @category aliases
83
+ * @category Aliases
83
84
  */
84
85
  export declare const HeadingLevel: typeof Heading;
85
86
  export {};