@typed/ui 1.0.0-beta.1 → 1.0.0-beta.10

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 (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -10
  3. package/dist/Alert.d.ts +72 -0
  4. package/dist/Alert.d.ts.map +1 -0
  5. package/dist/Alert.js +40 -0
  6. package/dist/Button.d.ts +100 -0
  7. package/dist/Button.d.ts.map +1 -0
  8. package/dist/Button.js +42 -0
  9. package/dist/Carousel.d.ts +346 -0
  10. package/dist/Carousel.d.ts.map +1 -0
  11. package/dist/Carousel.js +264 -0
  12. package/dist/Checkbox.d.ts +168 -0
  13. package/dist/Checkbox.d.ts.map +1 -0
  14. package/dist/Checkbox.js +146 -0
  15. package/dist/Collection.d.ts +254 -0
  16. package/dist/Collection.d.ts.map +1 -0
  17. package/dist/Collection.js +218 -0
  18. package/dist/Combobox.d.ts +367 -0
  19. package/dist/Combobox.d.ts.map +1 -0
  20. package/dist/Combobox.js +300 -0
  21. package/dist/Composite.d.ts +823 -0
  22. package/dist/Composite.d.ts.map +1 -0
  23. package/dist/Composite.js +615 -0
  24. package/dist/Dialog.d.ts +544 -0
  25. package/dist/Dialog.d.ts.map +1 -0
  26. package/dist/Dialog.js +357 -0
  27. package/dist/Disclosure.d.ts +219 -0
  28. package/dist/Disclosure.d.ts.map +1 -0
  29. package/dist/Disclosure.js +128 -0
  30. package/dist/Dom/Events.d.ts +122 -0
  31. package/dist/Dom/Events.d.ts.map +1 -0
  32. package/dist/Dom/Events.js +192 -0
  33. package/dist/Dom/Props.d.ts +161 -0
  34. package/dist/Dom/Props.d.ts.map +1 -0
  35. package/dist/Dom/Props.js +110 -0
  36. package/dist/Dom/Refs.d.ts +58 -0
  37. package/dist/Dom/Refs.d.ts.map +1 -0
  38. package/dist/Dom/Refs.js +61 -0
  39. package/dist/Dom/Render.d.ts +59 -0
  40. package/dist/Dom/Render.d.ts.map +1 -0
  41. package/dist/Dom/Render.js +71 -0
  42. package/dist/Dom/Types.d.ts +570 -0
  43. package/dist/Dom/Types.d.ts.map +1 -0
  44. package/dist/Dom/Types.js +1 -0
  45. package/dist/Dom/index.d.ts +20 -0
  46. package/dist/Dom/index.d.ts.map +1 -0
  47. package/dist/Dom/index.js +8 -0
  48. package/dist/Dom.d.ts +14 -0
  49. package/dist/Dom.d.ts.map +1 -0
  50. package/dist/Dom.js +13 -0
  51. package/dist/Focusable.d.ts +85 -0
  52. package/dist/Focusable.d.ts.map +1 -0
  53. package/dist/Focusable.js +35 -0
  54. package/dist/Form.d.ts +1727 -0
  55. package/dist/Form.d.ts.map +1 -0
  56. package/dist/Form.js +1142 -0
  57. package/dist/Grid.d.ts +388 -0
  58. package/dist/Grid.d.ts.map +1 -0
  59. package/dist/Grid.js +284 -0
  60. package/dist/Group.d.ts +128 -0
  61. package/dist/Group.d.ts.map +1 -0
  62. package/dist/Group.js +71 -0
  63. package/dist/Heading.d.ts +87 -0
  64. package/dist/Heading.d.ts.map +1 -0
  65. package/dist/Heading.js +58 -0
  66. package/dist/Hovercard.d.ts +297 -0
  67. package/dist/Hovercard.d.ts.map +1 -0
  68. package/dist/Hovercard.js +188 -0
  69. package/dist/HttpRouter.d.ts +129 -6
  70. package/dist/HttpRouter.d.ts.map +1 -1
  71. package/dist/HttpRouter.js +198 -55
  72. package/dist/Link.d.ts +63 -28
  73. package/dist/Link.d.ts.map +1 -1
  74. package/dist/Link.js +84 -37
  75. package/dist/Listbox.d.ts +305 -0
  76. package/dist/Listbox.d.ts.map +1 -0
  77. package/dist/Listbox.js +245 -0
  78. package/dist/Menu.d.ts +663 -0
  79. package/dist/Menu.d.ts.map +1 -0
  80. package/dist/Menu.js +569 -0
  81. package/dist/Menubar.d.ts +249 -0
  82. package/dist/Menubar.d.ts.map +1 -0
  83. package/dist/Menubar.js +207 -0
  84. package/dist/Meter.d.ts +157 -0
  85. package/dist/Meter.d.ts.map +1 -0
  86. package/dist/Meter.js +87 -0
  87. package/dist/NativeDetails.d.ts +41 -0
  88. package/dist/NativeDetails.d.ts.map +1 -0
  89. package/dist/NativeDetails.js +40 -0
  90. package/dist/NativeDialog.d.ts +66 -0
  91. package/dist/NativeDialog.d.ts.map +1 -0
  92. package/dist/NativeDialog.js +88 -0
  93. package/dist/NativePopover.d.ts +43 -0
  94. package/dist/NativePopover.d.ts.map +1 -0
  95. package/dist/NativePopover.js +84 -0
  96. package/dist/Popover.d.ts +240 -0
  97. package/dist/Popover.d.ts.map +1 -0
  98. package/dist/Popover.js +140 -0
  99. package/dist/RadioGroup.d.ts +330 -0
  100. package/dist/RadioGroup.d.ts.map +1 -0
  101. package/dist/RadioGroup.js +241 -0
  102. package/dist/Role.d.ts +64 -0
  103. package/dist/Role.d.ts.map +1 -0
  104. package/dist/Role.js +27 -0
  105. package/dist/Select.d.ts +418 -0
  106. package/dist/Select.d.ts.map +1 -0
  107. package/dist/Select.js +357 -0
  108. package/dist/Separator.d.ts +58 -0
  109. package/dist/Separator.d.ts.map +1 -0
  110. package/dist/Separator.js +32 -0
  111. package/dist/Slider.d.ts +141 -0
  112. package/dist/Slider.d.ts.map +1 -0
  113. package/dist/Slider.js +101 -0
  114. package/dist/SpinButton.d.ts +141 -0
  115. package/dist/SpinButton.d.ts.map +1 -0
  116. package/dist/SpinButton.js +101 -0
  117. package/dist/Storybook.d.ts +76 -0
  118. package/dist/Storybook.d.ts.map +1 -0
  119. package/dist/Storybook.js +102 -0
  120. package/dist/Switch.d.ts +148 -0
  121. package/dist/Switch.d.ts.map +1 -0
  122. package/dist/Switch.js +110 -0
  123. package/dist/Tab.d.ts +26 -0
  124. package/dist/Tab.d.ts.map +1 -0
  125. package/dist/Tab.js +25 -0
  126. package/dist/Tabs.d.ts +411 -0
  127. package/dist/Tabs.d.ts.map +1 -0
  128. package/dist/Tabs.js +262 -0
  129. package/dist/Toolbar.d.ts +248 -0
  130. package/dist/Toolbar.d.ts.map +1 -0
  131. package/dist/Toolbar.js +187 -0
  132. package/dist/Tooltip.d.ts +296 -0
  133. package/dist/Tooltip.d.ts.map +1 -0
  134. package/dist/Tooltip.js +172 -0
  135. package/dist/Tree.d.ts +405 -0
  136. package/dist/Tree.d.ts.map +1 -0
  137. package/dist/Tree.js +333 -0
  138. package/dist/TreeGrid.d.ts +426 -0
  139. package/dist/TreeGrid.d.ts.map +1 -0
  140. package/dist/TreeGrid.js +308 -0
  141. package/dist/VisuallyHidden.d.ts +68 -0
  142. package/dist/VisuallyHidden.d.ts.map +1 -0
  143. package/dist/VisuallyHidden.js +44 -0
  144. package/dist/WindowSplitter.d.ts +336 -0
  145. package/dist/WindowSplitter.d.ts.map +1 -0
  146. package/dist/WindowSplitter.js +305 -0
  147. package/dist/index.d.ts +48 -0
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +48 -0
  150. package/package.json +48 -20
  151. package/src/HttpRouter.test.ts +0 -294
  152. package/src/HttpRouter.ts +0 -168
  153. package/src/Link.test.ts +0 -84
  154. package/src/Link.ts +0 -107
  155. package/src/index.ts +0 -2
@@ -0,0 +1,168 @@
1
+ /**
2
+ * A native checkbox synchronized with boolean or mixed state.
3
+ * The checked and indeterminate properties are separate; mixed is not a submitted third value.
4
+ *
5
+ * Read the [Checkbox guide](/explore/ui-checkbox) for a complete example.
6
+ *
7
+ * [APG interaction reference](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/).
8
+ * @since 1.0.0
9
+ * @category Overview
10
+ * @packageDocumentation
11
+ */
12
+ import * as Effect from "effect/Effect";
13
+ import * as Schema from "effect/Schema";
14
+ import { RefSubject } from "@typed/fx";
15
+ import { EventHandler } from "@typed/template";
16
+ import * as Dom from "./Dom.js";
17
+ import type { HostResult } from "./Dom/Types.js";
18
+ /**
19
+ */
20
+ export type Checked = boolean | "mixed";
21
+ /**
22
+ * Current renderer-independent checkbox state.
23
+ * @remarks
24
+ * State can be updated and tested through RefSubject before any input mounts.
25
+ * The value is plain data; the hydrated RefSubject returned by `makeState`
26
+ * owns observation for its Effect Scope.
27
+ * @since 1.0.0
28
+ * @category State models
29
+ */
30
+ export interface State {
31
+ /**
32
+ */
33
+ readonly checked: Checked;
34
+ }
35
+ /**
36
+ */
37
+ export interface InitialState {
38
+ /**
39
+ */
40
+ readonly checked?: Checked;
41
+ }
42
+ /**
43
+ */
44
+ export declare const StateSchema: Schema.Struct<{
45
+ readonly checked: Schema.Literals<readonly [true, false, "mixed"]>;
46
+ }>;
47
+ /**
48
+ * Creates hydrated, renderer-independent checkbox state.
49
+ * @remarks
50
+ * State transitions remain testable without rendering and can be consumed by
51
+ * any UI producer.
52
+ * The caller's Effect Scope owns the hydrated RefSubject and its subscriptions.
53
+ * @example
54
+ * ```ts
55
+ * import { Effect } from "effect"
56
+ * import * as Checkbox from "@typed/ui/Checkbox"
57
+ *
58
+ * const program = Effect.gen(function* () {
59
+ * return yield* Checkbox.makeState({ checked: "mixed" })
60
+ * })
61
+ * ```
62
+ * @since 1.0.0
63
+ * @category State construction
64
+ */
65
+ export declare function makeState(initial?: InitialState): Effect.Effect<RefSubject.HydratedRefSubject<{
66
+ readonly checked: "mixed" | boolean;
67
+ }, Schema.SchemaError, never, never>, never, import("effect/Scope").Scope>;
68
+ /**
69
+ * Sets the checkbox state to a boolean or mixed value.
70
+ * @remarks
71
+ * A single atomic RefSubject update keeps DOM properties and ARIA state aligned.
72
+ * The Effect uses the existing subject lifetime and acquires no new resource.
73
+ * @example
74
+ * ```ts
75
+ * import { Effect } from "effect"
76
+ * import * as Checkbox from "@typed/ui/Checkbox"
77
+ *
78
+ * const program = Effect.gen(function* () {
79
+ * const state = yield* Checkbox.makeState()
80
+ * yield* Checkbox.setChecked(state, true)
81
+ * })
82
+ * ```
83
+ * @since 1.0.0
84
+ * @category State transitions
85
+ */
86
+ export declare function setChecked<E, R>(state: RefSubject.RefSubject<State, E, R>, checked: Checked): Effect.Effect<State, E, R>;
87
+ /**
88
+ * Toggles checked state, treating the mixed state as unchecked.
89
+ * @example
90
+ * ```ts
91
+ * import { Effect } from "effect"
92
+ * import * as Checkbox from "@typed/ui/Checkbox"
93
+ *
94
+ * const program = Effect.gen(function* () {
95
+ * const state = yield* Checkbox.makeState({ checked: "mixed" })
96
+ * yield* Checkbox.toggle(state)
97
+ * })
98
+ * ```
99
+ * @since 1.0.0
100
+ * @category State transitions
101
+ */
102
+ export declare function toggle<E, R>(state: RefSubject.RefSubject<State, E, R>): Effect.Effect<State, E, R>;
103
+ /**
104
+ */
105
+ export interface InputOptions extends Dom.HostOptions<HTMLInputElement> {
106
+ /**
107
+ * Hydrated state synchronized with the input.
108
+ * @since 1.0.0
109
+ * @category State connection
110
+ */
111
+ readonly state: RefSubject.HydratedRefSubject<State, Schema.SchemaError>;
112
+ }
113
+ declare function internalProps<const Options extends InputOptions>(options: Options): ({ property }: Dom.InternalPropsHelpers<Options>) => {
114
+ type: string;
115
+ "aria-checked": RefSubject.Computed<Checked, Schema.SchemaError, never>;
116
+ "?checked": RefSubject.Computed<boolean, Schema.SchemaError, never>;
117
+ ".checked": RefSubject.Computed<boolean, Schema.SchemaError, never>;
118
+ "?disabled": false | Exclude<Dom.Property<Options, "disabled">, Dom.Nullish>;
119
+ "?required": false | Exclude<Dom.Property<Options, "required">, Dom.Nullish>;
120
+ ".indeterminate": RefSubject.Computed<boolean, Schema.SchemaError, never>;
121
+ onchange: EventHandler.EventHandler<Event, Schema.SchemaError, never>;
122
+ ref: RefSubject.HydratedRefSubject<State, Schema.SchemaError, never, never>;
123
+ };
124
+ type InputInternalProps<Options extends InputOptions> = ReturnType<ReturnType<typeof internalProps<Options>>>;
125
+ /**
126
+ * Renders a native checkbox input synchronized with hydrated state.
127
+ * @remarks
128
+ * Native keyboard, form, disabled, required, and accessibility behavior remain
129
+ * available while state is exposed through RefSubject.
130
+ * Running the Fx installs native listeners and state subscriptions in its
131
+ * Scope. A custom host must apply `type`, checked, indeterminate, ARIA, and ref
132
+ * props; only one hydration owner may be composed for the element.
133
+ * @example
134
+ * ```ts
135
+ * import { RefSubject } from "@typed/fx";
136
+ * import { html } from "@typed/template";
137
+ * import * as Checkbox from "@typed/ui/Checkbox";
138
+ * import { component } from "@typed/template";
139
+ *
140
+ * export const UpdatePreference = component(function* () {
141
+ * const state = yield* Checkbox.makeState({ checked: false });
142
+ * const message = RefSubject.map(state, ({ checked }) =>
143
+ * checked === true ? "Product updates enabled" : "Product updates disabled",
144
+ * );
145
+ * return html`<div class="preference">
146
+ * <label>
147
+ * ${Checkbox.Input({ state, props: { name: "updates", value: "yes" } })}
148
+ * Receive product updates
149
+ * </label>
150
+ * <p>${message}</p>
151
+ * </div>`;
152
+ * });
153
+ * ```
154
+ * @since 1.0.0
155
+ * @category Native controls
156
+ */
157
+ export declare function Input<const Options extends InputOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, InputInternalProps<Options>>, "", Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
158
+ /**
159
+ * Canonical component alias for `Input`.
160
+ * @remarks
161
+ * The alias provides the widget name while retaining the explicit input API.
162
+ * It has exactly the same Scope and native-element ownership as `Input`.
163
+ * @since 1.0.0
164
+ * @category Native controls
165
+ */
166
+ export declare const Checkbox: typeof Input;
167
+ export {};
168
+ //# sourceMappingURL=Checkbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../src/Checkbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,YAAY,EAAQ,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;GACG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAExC;;;;;;;;GAQG;AACH,MAAM,WAAW,KAAK;IACpB;OACG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;GACG;AACH,MAAM,WAAW,YAAY;IAC3B;OACG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;GACG;AACH,eAAO,MAAM,WAAW;;EAEtB,CAAC;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,YAAiB;;2EAEnD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EACzC,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAE5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,EACzB,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,GACxC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAK5B;AAED;GACG;AACH,MAAM,WAAW,YAAa,SAAQ,GAAG,CAAC,WAAW,CAAC,gBAAgB,CAAC;IACrE;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;CAC1E;AAED,iBAAS,aAAa,CAAC,KAAK,CAAC,OAAO,SAAS,YAAY,EAAE,OAAO,EAAE,OAAO,kBASnD,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC;IACrD,IAAI;IACJ,cAAc;IACd,UAAU;IACV,UAAU;IACV,WAAW;IACX,WAAW;IACX,gBAAgB;IAChB,QAAQ;IACR,GAAG;EAEN;AAED,KAAK,kBAAkB,CAAC,OAAO,SAAS,YAAY,IAAI,UAAU,CAChE,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,CAC1C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;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,EAAE,EAAE,IAAI,CAAC,0DAW7F;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,cAAQ,CAAC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * A native checkbox synchronized with boolean or mixed state.
3
+ * The checked and indeterminate properties are separate; mixed is not a submitted third value.
4
+ *
5
+ * Read the [Checkbox guide](/explore/ui-checkbox) for a complete example.
6
+ *
7
+ * [APG interaction reference](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/).
8
+ * @since 1.0.0
9
+ * @category Overview
10
+ * @packageDocumentation
11
+ */
12
+ import * as Effect from "effect/Effect";
13
+ import * as Schema from "effect/Schema";
14
+ import { RefSubject } from "@typed/fx";
15
+ import { EventHandler, html } from "@typed/template";
16
+ import * as Dom from "./Dom.js";
17
+ /**
18
+ */
19
+ export const StateSchema = Schema.Struct({
20
+ checked: Schema.Literals([true, false, "mixed"]),
21
+ });
22
+ /**
23
+ * Creates hydrated, renderer-independent checkbox state.
24
+ * @remarks
25
+ * State transitions remain testable without rendering and can be consumed by
26
+ * any UI producer.
27
+ * The caller's Effect Scope owns the hydrated RefSubject and its subscriptions.
28
+ * @example
29
+ * ```ts
30
+ * import { Effect } from "effect"
31
+ * import * as Checkbox from "@typed/ui/Checkbox"
32
+ *
33
+ * const program = Effect.gen(function* () {
34
+ * return yield* Checkbox.makeState({ checked: "mixed" })
35
+ * })
36
+ * ```
37
+ * @since 1.0.0
38
+ * @category State construction
39
+ */
40
+ export function makeState(initial = {}) {
41
+ return RefSubject.hydrate(StateSchema, { checked: initial.checked ?? false });
42
+ }
43
+ /**
44
+ * Sets the checkbox state to a boolean or mixed value.
45
+ * @remarks
46
+ * A single atomic RefSubject update keeps DOM properties and ARIA state aligned.
47
+ * The Effect uses the existing subject lifetime and acquires no new resource.
48
+ * @example
49
+ * ```ts
50
+ * import { Effect } from "effect"
51
+ * import * as Checkbox from "@typed/ui/Checkbox"
52
+ *
53
+ * const program = Effect.gen(function* () {
54
+ * const state = yield* Checkbox.makeState()
55
+ * yield* Checkbox.setChecked(state, true)
56
+ * })
57
+ * ```
58
+ * @since 1.0.0
59
+ * @category State transitions
60
+ */
61
+ export function setChecked(state, checked) {
62
+ return RefSubject.update(state, (current) => ({ ...current, checked }));
63
+ }
64
+ /**
65
+ * Toggles checked state, treating the mixed state as unchecked.
66
+ * @example
67
+ * ```ts
68
+ * import { Effect } from "effect"
69
+ * import * as Checkbox from "@typed/ui/Checkbox"
70
+ *
71
+ * const program = Effect.gen(function* () {
72
+ * const state = yield* Checkbox.makeState({ checked: "mixed" })
73
+ * yield* Checkbox.toggle(state)
74
+ * })
75
+ * ```
76
+ * @since 1.0.0
77
+ * @category State transitions
78
+ */
79
+ export function toggle(state) {
80
+ return RefSubject.update(state, (current) => ({
81
+ ...current,
82
+ checked: current.checked === true ? false : true,
83
+ }));
84
+ }
85
+ function internalProps(options) {
86
+ const checked = RefSubject.map(options.state, (state) => state.checked === true);
87
+ const indeterminate = RefSubject.map(options.state, (state) => state.checked === "mixed");
88
+ const onChange = EventHandler.make(Effect.fn((event) => setChecked(options.state, Dom.currentTarget(event).checked)));
89
+ return ({ property }) => ({
90
+ type: "checkbox",
91
+ "aria-checked": RefSubject.map(options.state, (state) => state.checked),
92
+ "?checked": checked,
93
+ ".checked": checked,
94
+ "?disabled": property("disabled", false),
95
+ "?required": property("required", false),
96
+ ".indeterminate": indeterminate,
97
+ onchange: onChange,
98
+ ref: options.state,
99
+ });
100
+ }
101
+ /**
102
+ * Renders a native checkbox input synchronized with hydrated state.
103
+ * @remarks
104
+ * Native keyboard, form, disabled, required, and accessibility behavior remain
105
+ * available while state is exposed through RefSubject.
106
+ * Running the Fx installs native listeners and state subscriptions in its
107
+ * Scope. A custom host must apply `type`, checked, indeterminate, ARIA, and ref
108
+ * props; only one hydration owner may be composed for the element.
109
+ * @example
110
+ * ```ts
111
+ * import { RefSubject } from "@typed/fx";
112
+ * import { html } from "@typed/template";
113
+ * import * as Checkbox from "@typed/ui/Checkbox";
114
+ * import { component } from "@typed/template";
115
+ *
116
+ * export const UpdatePreference = component(function* () {
117
+ * const state = yield* Checkbox.makeState({ checked: false });
118
+ * const message = RefSubject.map(state, ({ checked }) =>
119
+ * checked === true ? "Product updates enabled" : "Product updates disabled",
120
+ * );
121
+ * return html`<div class="preference">
122
+ * <label>
123
+ * ${Checkbox.Input({ state, props: { name: "updates", value: "yes" } })}
124
+ * Receive product updates
125
+ * </label>
126
+ * <p>${message}</p>
127
+ * </div>`;
128
+ * });
129
+ * ```
130
+ * @since 1.0.0
131
+ * @category Native controls
132
+ */
133
+ export function Input(options, host) {
134
+ return Dom.renderHost()(options, host, internalProps(options), "", (i) => {
135
+ return html `<input ...${i} />`;
136
+ });
137
+ }
138
+ /**
139
+ * Canonical component alias for `Input`.
140
+ * @remarks
141
+ * The alias provides the widget name while retaining the explicit input API.
142
+ * It has exactly the same Scope and native-element ownership as `Input`.
143
+ * @since 1.0.0
144
+ * @category Native controls
145
+ */
146
+ export const Checkbox = Input;
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Collection is the scoped registry shared by composite widgets. Registration order is not
3
+ * navigation order: byDomOrder reads the mounted nodes with compareDocumentPosition, and each
4
+ * register Effect removes its own item when that Effect's Scope closes.
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 Architecture overview
13
+ * @packageDocumentation
14
+ */
15
+ import * as Effect from "effect/Effect";
16
+ import * as Scope from "effect/Scope";
17
+ import { RefSubject } from "@typed/fx";
18
+ /**
19
+ * Public Collection.Item behavioral model.
20
+ *
21
+ * @remarks
22
+ * ## Why
23
+ *
24
+ * The public model lets custom composites reuse Collection's deterministic policy without copying
25
+ * an internal shape.
26
+ *
27
+ * ## Ownership and lifetime
28
+ *
29
+ * This declaration is data or schema metadata and acquires no resources.
30
+ *
31
+ * ## Example
32
+ *
33
+ * Import with `import type { Item } from "@typed/ui/Collection";` Extend the [Collection.makeState
34
+ * runnable setup](/reference/%40typed%2Fui%2FCollection%23makeState). A registered value can retain
35
+ * its real DOM identity:
36
+ * `const item: Item<string> = { id: "save", value: "save", element: document.createElement("button") }`.
37
+ * @since 1.0.0
38
+ * @category Item metadata
39
+ */
40
+ export interface Item<Value = unknown, Element extends object = globalThis.Element> {
41
+ /**
42
+ * Stable id used for collection identity and ARIA relationships.
43
+ * @since 1.0.0
44
+ * @category Identity and relationships
45
+ */
46
+ readonly id: string;
47
+ /**
48
+ * Mounted element handle used for DOM ordering, focus, and scrolling.
49
+ * @since 1.0.0
50
+ * @category Item registration
51
+ */
52
+ readonly element?: Element;
53
+ /**
54
+ * Flag used by collection movement and widget handlers to skip activation by default.
55
+ * @since 1.0.0
56
+ * @category Availability
57
+ */
58
+ readonly disabled?: boolean;
59
+ /**
60
+ * Whether the item participates as a submenu entry.
61
+ * @since 1.0.0
62
+ * @category Nested menus
63
+ */
64
+ readonly submenu?: boolean;
65
+ /**
66
+ * Search text used by typeahead independently of rendered markup.
67
+ * @since 1.0.0
68
+ * @category Typeahead
69
+ */
70
+ readonly textValue?: string;
71
+ /**
72
+ * Current semantic value selected or edited by the widget.
73
+ * @since 1.0.0
74
+ * @category Item metadata
75
+ */
76
+ readonly value?: Value;
77
+ }
78
+ /**
79
+ * Complete renderer-independent state for Collection.
80
+ *
81
+ * @remarks
82
+ * ## Why
83
+ *
84
+ * Applications can inspect, update, and test Collection behavior without mounting or coupling the
85
+ * state to a renderer.
86
+ *
87
+ * ## Ownership and lifetime
88
+ *
89
+ * This declaration is data or schema metadata and acquires no resources.
90
+ *
91
+ * ## Example
92
+ *
93
+ * Import with `import type { State } from "@typed/ui/Collection";` Extend the [Collection.makeState
94
+ * runnable setup](/reference/%40typed%2Fui%2FCollection%23makeState). Collection state is an
95
+ * immutable sequence: `const snapshot: State<string> = [{ id: "save", value: "save" }]`.
96
+ * @since 1.0.0
97
+ * @category Collection state
98
+ */
99
+ export type State<Value = unknown, Element extends object = globalThis.Element> = readonly Item<Value, Element>[];
100
+ /**
101
+ * Creates hydrated Collection state. The collection starts with the supplied immutable item array,
102
+ * or empty.
103
+ *
104
+ * @remarks
105
+ * ## Why
106
+ *
107
+ * State and collection ownership can be composed and tested independently from any renderer.
108
+ *
109
+ * ## Ownership and lifetime
110
+ *
111
+ * The returned Effect creates the RefSubject when run. That state is renderer-independent;
112
+ * collection registrations belong to the separate Scope that runs register or ref, not to state
113
+ * creation.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * import * as Effect from "effect/Effect";
118
+ * import * as Collection from "@typed/ui/Collection";
119
+ *
120
+ * const program = Effect.scoped(
121
+ * Effect.gen(function* () {
122
+ * const collection = yield* Collection.makeState<string>();
123
+ * return yield* collection;
124
+ * }),
125
+ * );
126
+ * ```
127
+ * @since 1.0.0
128
+ * @category Collection state
129
+ */
130
+ export declare function makeState<Value = unknown, Element extends object = globalThis.Element>(initial?: State<Value, Element>): Effect.Effect<RefSubject.RefSubject<State<Value, Element>>, never, Scope.Scope>;
131
+ /**
132
+ * Upserts an item immediately and installs a finalizer in the Scope that runs this Effect; the
133
+ * finalizer removes only that exact registration.
134
+ *
135
+ * @remarks
136
+ * ## Why
137
+ *
138
+ * The operation exposes Collection's transition directly so callers can compose it in Effect
139
+ * programs and native event handlers.
140
+ *
141
+ * ## Ownership and lifetime
142
+ *
143
+ * Registration is owned by the Scope in which the registration Effect runs. Closing that Scope
144
+ * removes the exact registered item; creating the collection or state does not own this cleanup.
145
+ *
146
+ * ## Example
147
+ *
148
+ * Import with `import { register } from "@typed/ui/Collection";` Extend the [Collection.makeState
149
+ * runnable setup](/reference/%40typed%2Fui%2FCollection%23makeState). Inside the linked Effect
150
+ * program invoke `yield* register(collection, { id: "save", value: "save" })`, then read the
151
+ * collection to observe the inserted item.
152
+ * @since 1.0.0
153
+ * @category Item registration
154
+ */
155
+ export declare function register<Value, Element extends object, E, R>(collection: RefSubject.RefSubject<State<Value, Element>, E, R>, item: Item<Value, Element>): Effect.Effect<void, E, R | Scope.Scope>;
156
+ /**
157
+ * Registers a mounted element and removes it automatically with the Scope in which the returned
158
+ * Effect is run.
159
+ *
160
+ * @remarks
161
+ * ## Why
162
+ *
163
+ * The operation exposes Collection's transition directly so callers can compose it in Effect
164
+ * programs and native event handlers.
165
+ *
166
+ * ## Ownership and lifetime
167
+ *
168
+ * Registration is owned by the Scope in which the registration Effect runs. Closing that Scope
169
+ * removes the exact registered item; creating the collection or state does not own this cleanup.
170
+ *
171
+ * ## Example
172
+ *
173
+ * Import with `import { ref } from "@typed/ui/Collection";` Extend the [Collection.makeState
174
+ * runnable setup](/reference/%40typed%2Fui%2FCollection%23makeState). Inside the linked Effect
175
+ * program create `const attach = ref(collection, { id: "save", value: "save" })`, then run `yield*
176
+ * attach(document.createElement("button"))` and read the collection before Scope close.
177
+ * @since 1.0.0
178
+ * @category Item registration
179
+ */
180
+ export declare function ref<Value, Element extends object, E, R>(collection: RefSubject.RefSubject<State<Value, Element>, E, R>, item: Omit<Item<Value, Element>, "element">): (element: Element) => Effect.Effect<void, E, R | Scope.Scope>;
181
+ /**
182
+ * Removes every registered item with the supplied id and retains the remaining order.
183
+ *
184
+ * @remarks
185
+ * ## Why
186
+ *
187
+ * The operation exposes Collection's transition directly so callers can compose it in Effect
188
+ * programs and native event handlers.
189
+ *
190
+ * ## Ownership and lifetime
191
+ *
192
+ * The returned Effect performs the update or DOM side effect only when run, preserves the declared
193
+ * error and service channels, and retains no resources after completion.
194
+ *
195
+ * ## Example
196
+ *
197
+ * Import with `import { unregister } from "@typed/ui/Collection";` Extend the [Collection.makeState
198
+ * runnable setup](/reference/%40typed%2Fui%2FCollection%23makeState). Inside the linked Effect
199
+ * program first register `"save"`, run `yield* unregister(collection, "save")`, then read the
200
+ * collection to observe that only the matching id was removed.
201
+ * @since 1.0.0
202
+ * @category Item registration
203
+ */
204
+ export declare function unregister<Value, Element extends object, E, R>(collection: RefSubject.RefSubject<State<Value, Element>, E, R>, id: string): Effect.Effect<void, E, R>;
205
+ /**
206
+ * Returns a new array excluding only items whose disabled flag is exactly true.
207
+ *
208
+ * @remarks
209
+ * ## Why
210
+ *
211
+ * Separating this deterministic policy from event wiring lets applications test it directly and
212
+ * reuse it in custom composites.
213
+ *
214
+ * ## Ownership and lifetime
215
+ *
216
+ * This is a synchronous calculation. It acquires no resources and does not mutate the input array,
217
+ * state, event, or DOM.
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * import * as Collection from "@typed/ui/Collection";
222
+ *
223
+ * const enabled = Collection.enabledItems([{ id: "a" }, { id: "b", disabled: true }]);
224
+ * ```
225
+ * @since 1.0.0
226
+ * @category Collection ordering
227
+ */
228
+ export declare function enabledItems<ItemType extends Item<unknown, object>>(items: readonly ItemType[]): readonly ItemType[];
229
+ /**
230
+ * Returns a sorted copy using compareDocumentPosition; items without comparable mounted elements
231
+ * retain an equivalent ordering position.
232
+ *
233
+ * @remarks
234
+ * ## Why
235
+ *
236
+ * Separating this deterministic policy from event wiring lets applications test it directly and
237
+ * reuse it in custom composites.
238
+ *
239
+ * ## Ownership and lifetime
240
+ *
241
+ * This is a synchronous calculation. It acquires no resources and does not mutate the input array,
242
+ * state, event, or DOM.
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * import * as Collection from "@typed/ui/Collection";
247
+ *
248
+ * const ordered = Collection.byDomOrder([{ id: "body", element: document.body }]);
249
+ * ```
250
+ * @since 1.0.0
251
+ * @category Collection ordering
252
+ */
253
+ export declare function byDomOrder<ItemType extends Item<unknown, object>>(items: readonly ItemType[]): readonly ItemType[];
254
+ //# sourceMappingURL=Collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collection.d.ts","sourceRoot":"","sources":["../src/Collection.ts"],"names":[],"mappings":"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"}