@typed/ui 1.0.0-beta.4 → 1.0.0-beta.6
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 +53 -9
- package/dist/Alert.d.ts +78 -0
- package/dist/Alert.d.ts.map +1 -0
- package/dist/Alert.js +37 -0
- package/dist/Button.d.ts +144 -0
- package/dist/Button.d.ts.map +1 -0
- package/dist/Button.js +38 -0
- package/dist/Carousel.d.ts +547 -0
- package/dist/Carousel.d.ts.map +1 -0
- package/dist/Carousel.js +387 -0
- package/dist/Checkbox.d.ts +203 -0
- package/dist/Checkbox.d.ts.map +1 -0
- package/dist/Checkbox.js +140 -0
- package/dist/Collection.d.ts +254 -0
- package/dist/Collection.d.ts.map +1 -0
- package/dist/Collection.js +218 -0
- package/dist/Combobox.d.ts +516 -0
- package/dist/Combobox.d.ts.map +1 -0
- package/dist/Combobox.js +371 -0
- package/dist/Component.d.ts +127 -0
- package/dist/Component.d.ts.map +1 -0
- package/dist/Component.js +60 -0
- package/dist/Composite.d.ts +823 -0
- package/dist/Composite.d.ts.map +1 -0
- package/dist/Composite.js +615 -0
- package/dist/Dialog.d.ts +544 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/Dialog.js +355 -0
- package/dist/Disclosure.d.ts +219 -0
- package/dist/Disclosure.d.ts.map +1 -0
- package/dist/Disclosure.js +128 -0
- package/dist/Dom/Events.d.ts +122 -0
- package/dist/Dom/Events.d.ts.map +1 -0
- package/dist/Dom/Events.js +192 -0
- package/dist/Dom/Props.d.ts +161 -0
- package/dist/Dom/Props.d.ts.map +1 -0
- package/dist/Dom/Props.js +110 -0
- package/dist/Dom/Refs.d.ts +58 -0
- package/dist/Dom/Refs.d.ts.map +1 -0
- package/dist/Dom/Refs.js +61 -0
- package/dist/Dom/Render.d.ts +59 -0
- package/dist/Dom/Render.d.ts.map +1 -0
- package/dist/Dom/Render.js +71 -0
- package/dist/Dom/Types.d.ts +570 -0
- package/dist/Dom/Types.d.ts.map +1 -0
- package/dist/Dom/Types.js +1 -0
- package/dist/Dom/index.d.ts +20 -0
- package/dist/Dom/index.d.ts.map +1 -0
- package/dist/Dom/index.js +8 -0
- package/dist/Dom.d.ts +14 -0
- package/dist/Dom.d.ts.map +1 -0
- package/dist/Dom.js +13 -0
- package/dist/Focusable.d.ts +85 -0
- package/dist/Focusable.d.ts.map +1 -0
- package/dist/Focusable.js +35 -0
- package/dist/Form.d.ts +1695 -0
- package/dist/Form.d.ts.map +1 -0
- package/dist/Form.js +987 -0
- package/dist/Grid.d.ts +569 -0
- package/dist/Grid.d.ts.map +1 -0
- package/dist/Grid.js +379 -0
- package/dist/Group.d.ts +147 -0
- package/dist/Group.d.ts.map +1 -0
- package/dist/Group.js +63 -0
- package/dist/Heading.d.ts +86 -0
- package/dist/Heading.d.ts.map +1 -0
- package/dist/Heading.js +48 -0
- package/dist/Hovercard.d.ts +297 -0
- package/dist/Hovercard.d.ts.map +1 -0
- package/dist/Hovercard.js +188 -0
- package/dist/HttpRouter.d.ts +129 -6
- package/dist/HttpRouter.d.ts.map +1 -1
- package/dist/HttpRouter.js +196 -53
- package/dist/Link.d.ts +67 -28
- package/dist/Link.d.ts.map +1 -1
- package/dist/Link.js +91 -37
- package/dist/Listbox.d.ts +437 -0
- package/dist/Listbox.d.ts.map +1 -0
- package/dist/Listbox.js +316 -0
- package/dist/Menu.d.ts +972 -0
- package/dist/Menu.d.ts.map +1 -0
- package/dist/Menu.js +731 -0
- package/dist/Menubar.d.ts +367 -0
- package/dist/Menubar.d.ts.map +1 -0
- package/dist/Menubar.js +265 -0
- package/dist/Meter.d.ts +217 -0
- package/dist/Meter.d.ts.map +1 -0
- package/dist/Meter.js +94 -0
- package/dist/NativeDetails.d.ts +41 -0
- package/dist/NativeDetails.d.ts.map +1 -0
- package/dist/NativeDetails.js +40 -0
- package/dist/NativeDialog.d.ts +64 -0
- package/dist/NativeDialog.d.ts.map +1 -0
- package/dist/NativeDialog.js +50 -0
- package/dist/NativePopover.d.ts +41 -0
- package/dist/NativePopover.d.ts.map +1 -0
- package/dist/NativePopover.js +46 -0
- package/dist/Popover.d.ts +241 -0
- package/dist/Popover.d.ts.map +1 -0
- package/dist/Popover.js +141 -0
- package/dist/RadioGroup.d.ts +432 -0
- package/dist/RadioGroup.d.ts.map +1 -0
- package/dist/RadioGroup.js +291 -0
- package/dist/Role.d.ts +64 -0
- package/dist/Role.d.ts.map +1 -0
- package/dist/Role.js +27 -0
- package/dist/Select.d.ts +529 -0
- package/dist/Select.d.ts.map +1 -0
- package/dist/Select.js +407 -0
- package/dist/Separator.d.ts +54 -0
- package/dist/Separator.d.ts.map +1 -0
- package/dist/Separator.js +26 -0
- package/dist/Slider.d.ts +188 -0
- package/dist/Slider.d.ts.map +1 -0
- package/dist/Slider.js +96 -0
- package/dist/SpinButton.d.ts +188 -0
- package/dist/SpinButton.d.ts.map +1 -0
- package/dist/SpinButton.js +96 -0
- package/dist/Storybook.d.ts +76 -0
- package/dist/Storybook.d.ts.map +1 -0
- package/dist/Storybook.js +102 -0
- package/dist/Switch.d.ts +187 -0
- package/dist/Switch.d.ts.map +1 -0
- package/dist/Switch.js +116 -0
- package/dist/Tab.d.ts +26 -0
- package/dist/Tab.d.ts.map +1 -0
- package/dist/Tab.js +25 -0
- package/dist/Tabs.d.ts +591 -0
- package/dist/Tabs.d.ts.map +1 -0
- package/dist/Tabs.js +346 -0
- package/dist/Toolbar.d.ts +366 -0
- package/dist/Toolbar.d.ts.map +1 -0
- package/dist/Toolbar.js +245 -0
- package/dist/Tooltip.d.ts +296 -0
- package/dist/Tooltip.d.ts.map +1 -0
- package/dist/Tooltip.js +172 -0
- package/dist/Tree.d.ts +591 -0
- package/dist/Tree.d.ts.map +1 -0
- package/dist/Tree.js +434 -0
- package/dist/TreeGrid.d.ts +645 -0
- package/dist/TreeGrid.d.ts.map +1 -0
- package/dist/TreeGrid.js +420 -0
- package/dist/VisuallyHidden.d.ts +54 -0
- package/dist/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden.js +27 -0
- package/dist/WindowSplitter.d.ts +376 -0
- package/dist/WindowSplitter.d.ts.map +1 -0
- package/dist/WindowSplitter.js +222 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -0
- package/package.json +45 -18
- package/src/HttpRouter.test.ts +0 -256
- package/src/HttpRouter.ts +0 -165
- package/src/Link.test.ts +0 -84
- package/src/Link.ts +0 -107
- package/src/index.ts +0 -2
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RadioGroup keeps a selected value and active id in explicit state. Arrow movement skips disabled
|
|
3
|
+
* registered items, updates selection, and moves focus; each item renders a real radio input with
|
|
4
|
+
* ARIA state.
|
|
5
|
+
*
|
|
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.
|
|
10
|
+
*
|
|
11
|
+
* @since 1.0.0
|
|
12
|
+
* @category modules
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
import * as Effect from "effect/Effect";
|
|
16
|
+
import * as Schema from "effect/Schema";
|
|
17
|
+
import { RefSubject } from "@typed/fx";
|
|
18
|
+
import { EventHandler, html, } from "@typed/template";
|
|
19
|
+
import * as Collection from "./Collection.js";
|
|
20
|
+
import * as Composite from "./Composite.js";
|
|
21
|
+
import * as Dom from "./Dom.js";
|
|
22
|
+
/**
|
|
23
|
+
* Effect Schema used by makeState to encode, decode, and hydrate RadioGroup state.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* ## Why
|
|
27
|
+
*
|
|
28
|
+
* A public schema makes hydration and serialized state use the same runtime validation as direct
|
|
29
|
+
* construction.
|
|
30
|
+
*
|
|
31
|
+
* ## Ownership and lifetime
|
|
32
|
+
*
|
|
33
|
+
* This declaration is data or schema metadata and acquires no resources.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import * as Schema from "effect/Schema";
|
|
38
|
+
* import * as RadioGroup from "@typed/ui/RadioGroup";
|
|
39
|
+
*
|
|
40
|
+
* const decodeState = Schema.decodeUnknownEffect(RadioGroup.StateSchema);
|
|
41
|
+
* ```
|
|
42
|
+
* @since 1.0.0
|
|
43
|
+
* @category schemas
|
|
44
|
+
*/
|
|
45
|
+
export const StateSchema = Schema.Struct({
|
|
46
|
+
value: Schema.String,
|
|
47
|
+
activeId: Schema.NullOr(Schema.String),
|
|
48
|
+
orientation: Schema.Literals(["vertical"]),
|
|
49
|
+
loop: Schema.Boolean,
|
|
50
|
+
rtl: Schema.Boolean,
|
|
51
|
+
virtualFocus: Schema.Boolean,
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Creates hydrated RadioGroup state. The caller supplies value; activeId defaults to that value
|
|
55
|
+
* and loop defaults true.
|
|
56
|
+
*
|
|
57
|
+
* @remarks
|
|
58
|
+
* ## Why
|
|
59
|
+
*
|
|
60
|
+
* State and collection ownership can be composed and tested independently from any renderer.
|
|
61
|
+
*
|
|
62
|
+
* ## Ownership and lifetime
|
|
63
|
+
*
|
|
64
|
+
* The returned Effect creates the RefSubject when run. That state is renderer-independent;
|
|
65
|
+
* collection registrations belong to the separate Scope that runs register or ref, not to state
|
|
66
|
+
* creation.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import * as Effect from "effect/Effect";
|
|
71
|
+
* import * as RadioGroup from "@typed/ui/RadioGroup";
|
|
72
|
+
*
|
|
73
|
+
* const program = Effect.scoped(
|
|
74
|
+
* Effect.gen(function* () {
|
|
75
|
+
* const state = yield* RadioGroup.makeState({ value: "email" });
|
|
76
|
+
* const collection = yield* RadioGroup.makeCollection();
|
|
77
|
+
* return { state: yield* state, collection: yield* collection };
|
|
78
|
+
* }),
|
|
79
|
+
* );
|
|
80
|
+
* ```
|
|
81
|
+
* @since 1.0.0
|
|
82
|
+
* @category constructors
|
|
83
|
+
*/
|
|
84
|
+
export function makeState(initial) {
|
|
85
|
+
return RefSubject.hydrate(StateSchema, {
|
|
86
|
+
value: initial.value,
|
|
87
|
+
activeId: initial.activeId ?? null,
|
|
88
|
+
orientation: "vertical",
|
|
89
|
+
loop: initial.loop ?? true,
|
|
90
|
+
rtl: false,
|
|
91
|
+
virtualFocus: false,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Creates a scoped Collection for RadioGroup items.
|
|
96
|
+
*
|
|
97
|
+
* @remarks
|
|
98
|
+
* ## Why
|
|
99
|
+
*
|
|
100
|
+
* State and collection ownership can be composed and tested independently from any renderer.
|
|
101
|
+
*
|
|
102
|
+
* ## Ownership and lifetime
|
|
103
|
+
*
|
|
104
|
+
* The returned Effect allocates the RefSubject in the caller's Scope. Each later registration is
|
|
105
|
+
* owned by the Scope that runs register, independently of this construction Effect.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* import * as Effect from "effect/Effect";
|
|
110
|
+
* import * as RadioGroup from "@typed/ui/RadioGroup";
|
|
111
|
+
*
|
|
112
|
+
* const program = Effect.scoped(
|
|
113
|
+
* Effect.gen(function* () {
|
|
114
|
+
* const collection = yield* RadioGroup.makeCollection();
|
|
115
|
+
* return yield* collection;
|
|
116
|
+
* }),
|
|
117
|
+
* );
|
|
118
|
+
* ```
|
|
119
|
+
* @since 1.0.0
|
|
120
|
+
* @category constructors
|
|
121
|
+
*/
|
|
122
|
+
export const makeCollection = Collection.makeState;
|
|
123
|
+
/**
|
|
124
|
+
* Sets selected value and activeId to the same registered radio id.
|
|
125
|
+
*
|
|
126
|
+
* @remarks
|
|
127
|
+
* ## Why
|
|
128
|
+
*
|
|
129
|
+
* The operation exposes RadioGroup's transition directly so callers can compose it in Effect
|
|
130
|
+
* programs and native event handlers.
|
|
131
|
+
*
|
|
132
|
+
* ## Ownership and lifetime
|
|
133
|
+
*
|
|
134
|
+
* The returned Effect performs the update or DOM side effect only when run, preserves the declared
|
|
135
|
+
* error and service channels, and retains no resources after completion.
|
|
136
|
+
*
|
|
137
|
+
* ## Example
|
|
138
|
+
*
|
|
139
|
+
* Import with `import { setValue } from "@typed/ui/RadioGroup";` Extend the [RadioGroup.makeState
|
|
140
|
+
* runnable setup](/reference/%40typed%2Fui%2FRadioGroup%23makeState). Inside the linked Effect
|
|
141
|
+
* program invoke `yield* setValue(state, "phone", "phone")`, then read state to observe the checked
|
|
142
|
+
* value and active roving-focus id update together.
|
|
143
|
+
* @since 1.0.0
|
|
144
|
+
* @category combinators
|
|
145
|
+
*/
|
|
146
|
+
export function setValue(state, value, activeId) {
|
|
147
|
+
return RefSubject.update(state, (current) => ({
|
|
148
|
+
...current,
|
|
149
|
+
value,
|
|
150
|
+
activeId: activeId ?? current.activeId,
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
function move(state, collection, direction) {
|
|
154
|
+
return Effect.gen(function* () {
|
|
155
|
+
const current = yield* state;
|
|
156
|
+
const items = yield* collection;
|
|
157
|
+
const activeId = current.activeId ?? items.find((item) => item.value === current.value)?.id ?? null;
|
|
158
|
+
const nextId = Composite.moveActiveId(items, { ...current, activeId }, direction);
|
|
159
|
+
const item = nextId === null ? undefined : items.find((item) => item.id === nextId);
|
|
160
|
+
if (item?.value === undefined)
|
|
161
|
+
return current;
|
|
162
|
+
const next = yield* setValue(state, item.value, item.id);
|
|
163
|
+
yield* Composite.focusActive({ state, collection });
|
|
164
|
+
return next;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function rootInternalProps(options) {
|
|
168
|
+
const onkeydown = options.collection === undefined
|
|
169
|
+
? undefined
|
|
170
|
+
: EventHandler.make(Effect.fn(function* (event) {
|
|
171
|
+
const direction = Composite.keyMove(event, { orientation: "vertical" });
|
|
172
|
+
if (direction === undefined)
|
|
173
|
+
return;
|
|
174
|
+
event.preventDefault();
|
|
175
|
+
yield* move(options.state, options.collection, direction);
|
|
176
|
+
}));
|
|
177
|
+
return ({ property }) => ({
|
|
178
|
+
role: "radiogroup",
|
|
179
|
+
"aria-label": property("label", undefined),
|
|
180
|
+
onkeydown,
|
|
181
|
+
ref: options.state,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Renders the radiogroup and maps Arrow keys to selection and focus movement.
|
|
186
|
+
*
|
|
187
|
+
* @remarks
|
|
188
|
+
* ## Why
|
|
189
|
+
*
|
|
190
|
+
* The component applies the family behavior while leaving callers free to supply a custom host
|
|
191
|
+
* through the shared DOM boundary.
|
|
192
|
+
*
|
|
193
|
+
* ## Ownership and lifetime
|
|
194
|
+
*
|
|
195
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
196
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
197
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
198
|
+
*
|
|
199
|
+
* ## Example
|
|
200
|
+
*
|
|
201
|
+
* Import with `import { Root } from "@typed/ui/RadioGroup";` Extend the [RadioGroup.makeState
|
|
202
|
+
* runnable setup](/reference/%40typed%2Fui%2FRadioGroup%23makeState). Replace the linked program's
|
|
203
|
+
* final snapshot read with `Root({ state, label: "Contact method", content: "Choices" })`; render
|
|
204
|
+
* that Fx before the same Scope closes.
|
|
205
|
+
* @since 1.0.0
|
|
206
|
+
* @category components
|
|
207
|
+
*/
|
|
208
|
+
export function Root(options, host) {
|
|
209
|
+
return Dom.renderHost()(options, host, rootInternalProps(options), options.content, (props, content) => {
|
|
210
|
+
return html `<div ...${props}>${content}</div>`;
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
function itemInternalProps(options) {
|
|
214
|
+
const checked = RefSubject.map(options.state, (state) => state.value === options.value);
|
|
215
|
+
const register = options.collection === undefined
|
|
216
|
+
? undefined
|
|
217
|
+
: Collection.ref(options.collection, {
|
|
218
|
+
id: options.id,
|
|
219
|
+
value: options.value,
|
|
220
|
+
textValue: options.value,
|
|
221
|
+
disabled: options.disabled,
|
|
222
|
+
});
|
|
223
|
+
return () => ({
|
|
224
|
+
id: options.id,
|
|
225
|
+
type: "radio",
|
|
226
|
+
role: "radio",
|
|
227
|
+
name: options.name,
|
|
228
|
+
value: options.value,
|
|
229
|
+
"?disabled": options.disabled ?? false,
|
|
230
|
+
"aria-checked": checked,
|
|
231
|
+
"aria-disabled": options.disabled ?? false,
|
|
232
|
+
"?checked": checked,
|
|
233
|
+
".checked": checked,
|
|
234
|
+
onchange: options.disabled === true
|
|
235
|
+
? Effect.void
|
|
236
|
+
: setValue(options.state, options.value, options.id),
|
|
237
|
+
ref: Dom.composeRefs(register, options.ref),
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Renders and optionally registers a native radio input synchronized with selected value.
|
|
242
|
+
*
|
|
243
|
+
* @remarks
|
|
244
|
+
* ## Why
|
|
245
|
+
*
|
|
246
|
+
* The component applies the family behavior while leaving callers free to supply a custom host
|
|
247
|
+
* through the shared DOM boundary.
|
|
248
|
+
*
|
|
249
|
+
* ## Ownership and lifetime
|
|
250
|
+
*
|
|
251
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
252
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
253
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
254
|
+
*
|
|
255
|
+
* ## Example
|
|
256
|
+
*
|
|
257
|
+
* Import with `import { Item } from "@typed/ui/RadioGroup";` Extend the [RadioGroup.makeState
|
|
258
|
+
* runnable setup](/reference/%40typed%2Fui%2FRadioGroup%23makeState). Replace the linked program's
|
|
259
|
+
* final snapshot read with `Item({ state, id: "email", value: "email", name: "contact" })`; render
|
|
260
|
+
* that Fx before the same Scope closes.
|
|
261
|
+
* @since 1.0.0
|
|
262
|
+
* @category components
|
|
263
|
+
*/
|
|
264
|
+
export function Item(options, host) {
|
|
265
|
+
return Dom.renderHost()(options, host, itemInternalProps(options), "", (props) => html `<input ...${props} />`);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Consumer-facing alias of the canonical RadioGroup component with identical behavior and
|
|
269
|
+
* lifetime.
|
|
270
|
+
*
|
|
271
|
+
* @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
|
+
* The alias acquires nothing. Rendering it has exactly the canonical component's Scope and DOM
|
|
280
|
+
* ownership contract.
|
|
281
|
+
*
|
|
282
|
+
* ## Example
|
|
283
|
+
*
|
|
284
|
+
* Import with `import { RadioGroup } from "@typed/ui/RadioGroup";` Extend the [RadioGroup.makeState
|
|
285
|
+
* runnable setup](/reference/%40typed%2Fui%2FRadioGroup%23makeState). Replace the linked program's
|
|
286
|
+
* final snapshot read with `RadioGroup({ state, label: "Contact method", content: "Choices" })`;
|
|
287
|
+
* render that Fx before the same Scope closes.
|
|
288
|
+
* @since 1.0.0
|
|
289
|
+
* @category components
|
|
290
|
+
*/
|
|
291
|
+
export const RadioGroup = Root;
|
package/dist/Role.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type * as Scope from "effect/Scope";
|
|
2
|
+
import type { Fx } from "@typed/fx/Fx";
|
|
3
|
+
import { type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
|
|
4
|
+
import * as Dom from "./Dom.js";
|
|
5
|
+
import type { HostResult } from "./Dom/Types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for assigning explicit ARIA semantics to a generic host.
|
|
8
|
+
* @remarks
|
|
9
|
+
* ## Why
|
|
10
|
+
* This primitive keeps role selection visible when no dedicated component
|
|
11
|
+
* matches the required semantic.
|
|
12
|
+
* ## Ownership and lifetime
|
|
13
|
+
* The model acquires no resources; dynamic values follow the rendered Scope.
|
|
14
|
+
* @since 1.0.0
|
|
15
|
+
* @category models
|
|
16
|
+
*/
|
|
17
|
+
export interface RoleOptions extends Dom.HostOptions<HTMLDivElement> {
|
|
18
|
+
/** Content rendered inside the semantic host.
|
|
19
|
+
* @remarks
|
|
20
|
+
* ## Why
|
|
21
|
+
* Native content remains available to the accessibility tree.
|
|
22
|
+
* ## Ownership and lifetime
|
|
23
|
+
* Dynamic content follows the component Scope.
|
|
24
|
+
* @since 1.0.0
|
|
25
|
+
* @category content
|
|
26
|
+
*/
|
|
27
|
+
readonly content: Renderable.Any;
|
|
28
|
+
/** The explicit ARIA role.
|
|
29
|
+
* @remarks
|
|
30
|
+
* ## Why
|
|
31
|
+
* Callers must choose semantics appropriate to their interaction model.
|
|
32
|
+
* ## Ownership and lifetime
|
|
33
|
+
* The reflected value retains no resources.
|
|
34
|
+
* @since 1.0.0
|
|
35
|
+
* @category accessibility
|
|
36
|
+
*/
|
|
37
|
+
readonly role: Renderable.Any<string | null | undefined>;
|
|
38
|
+
}
|
|
39
|
+
declare function internalProps<const Options extends RoleOptions>({ property, }: Dom.InternalPropsHelpers<Options>): {
|
|
40
|
+
role: Exclude<Dom.Property<Options, "role">, Dom.Nullish> | undefined;
|
|
41
|
+
};
|
|
42
|
+
type RoleInternalProps<Options extends RoleOptions> = ReturnType<typeof internalProps<Options>>;
|
|
43
|
+
/**
|
|
44
|
+
* Renders a generic element with caller-selected ARIA semantics.
|
|
45
|
+
* @remarks
|
|
46
|
+
* ## Why
|
|
47
|
+
* It provides cooperative host composition without pretending every ARIA role
|
|
48
|
+
* has identical keyboard behavior; the caller remains responsible for the
|
|
49
|
+
* chosen role's complete accessibility contract.
|
|
50
|
+
* ## Ownership and lifetime
|
|
51
|
+
* Running the returned Fx owns dynamic attributes and content until its Effect
|
|
52
|
+
* Scope closes. A custom host must preserve the supplied role.
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { Role } from "@typed/ui/Role"
|
|
56
|
+
*
|
|
57
|
+
* const status = Role({ role: "status", content: "Ready" })
|
|
58
|
+
* ```
|
|
59
|
+
* @since 1.0.0
|
|
60
|
+
* @category components
|
|
61
|
+
*/
|
|
62
|
+
export declare function Role<const Options extends RoleOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, RoleInternalProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=Role.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Role.d.ts","sourceRoot":"","sources":["../src/Role.ts"],"names":[],"mappings":"AAAA,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;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAY,SAAQ,GAAG,CAAC,WAAW,CAAC,cAAc,CAAC;IAClE;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC1D;AAED,iBAAS,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,WAAW,EAAE,EACxD,QAAQ,GACT,EAAE,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC;IACzB,IAAI;EACd;AAED,KAAK,iBAAiB,CAAC,OAAO,SAAS,WAAW,IAAI,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AAEhG;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,OAAO,SAAS,WAAW,EAAE,KAAK,CAAC,IAAI,SAAS,UAAU,GAAG,KAAK,EAC3F,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,GAAG,CAAC,YAAY,CACrB,GAAG,CAAC,eAAe,CAAC,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC,EACxD,OAAO,CAAC,SAAS,CAAC,EAClB,IAAI,CACL,GACA,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,CAcA"}
|
package/dist/Role.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { html } from "@typed/template";
|
|
2
|
+
import * as Dom from "./Dom.js";
|
|
3
|
+
function internalProps({ property, }) {
|
|
4
|
+
return { role: property("role", undefined) };
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Renders a generic element with caller-selected ARIA semantics.
|
|
8
|
+
* @remarks
|
|
9
|
+
* ## Why
|
|
10
|
+
* It provides cooperative host composition without pretending every ARIA role
|
|
11
|
+
* has identical keyboard behavior; the caller remains responsible for the
|
|
12
|
+
* chosen role's complete accessibility contract.
|
|
13
|
+
* ## Ownership and lifetime
|
|
14
|
+
* Running the returned Fx owns dynamic attributes and content until its Effect
|
|
15
|
+
* Scope closes. A custom host must preserve the supplied role.
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { Role } from "@typed/ui/Role"
|
|
19
|
+
*
|
|
20
|
+
* const status = Role({ role: "status", content: "Ready" })
|
|
21
|
+
* ```
|
|
22
|
+
* @since 1.0.0
|
|
23
|
+
* @category components
|
|
24
|
+
*/
|
|
25
|
+
export function Role(options, host) {
|
|
26
|
+
return Dom.renderHost()(options, host, internalProps, options.content, (props, content) => html `<div ...${props}>${content}</div>`);
|
|
27
|
+
}
|