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

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 (157) hide show
  1. package/README.md +53 -9
  2. package/dist/Alert.d.ts +78 -0
  3. package/dist/Alert.d.ts.map +1 -0
  4. package/dist/Alert.js +37 -0
  5. package/dist/Button.d.ts +144 -0
  6. package/dist/Button.d.ts.map +1 -0
  7. package/dist/Button.js +38 -0
  8. package/dist/Carousel.d.ts +547 -0
  9. package/dist/Carousel.d.ts.map +1 -0
  10. package/dist/Carousel.js +387 -0
  11. package/dist/Checkbox.d.ts +203 -0
  12. package/dist/Checkbox.d.ts.map +1 -0
  13. package/dist/Checkbox.js +140 -0
  14. package/dist/Collection.d.ts +254 -0
  15. package/dist/Collection.d.ts.map +1 -0
  16. package/dist/Collection.js +218 -0
  17. package/dist/Combobox.d.ts +516 -0
  18. package/dist/Combobox.d.ts.map +1 -0
  19. package/dist/Combobox.js +371 -0
  20. package/dist/Component.d.ts +127 -0
  21. package/dist/Component.d.ts.map +1 -0
  22. package/dist/Component.js +60 -0
  23. package/dist/Composite.d.ts +823 -0
  24. package/dist/Composite.d.ts.map +1 -0
  25. package/dist/Composite.js +615 -0
  26. package/dist/Dialog.d.ts +544 -0
  27. package/dist/Dialog.d.ts.map +1 -0
  28. package/dist/Dialog.js +355 -0
  29. package/dist/Disclosure.d.ts +219 -0
  30. package/dist/Disclosure.d.ts.map +1 -0
  31. package/dist/Disclosure.js +128 -0
  32. package/dist/Dom/Events.d.ts +122 -0
  33. package/dist/Dom/Events.d.ts.map +1 -0
  34. package/dist/Dom/Events.js +192 -0
  35. package/dist/Dom/Props.d.ts +161 -0
  36. package/dist/Dom/Props.d.ts.map +1 -0
  37. package/dist/Dom/Props.js +110 -0
  38. package/dist/Dom/Refs.d.ts +58 -0
  39. package/dist/Dom/Refs.d.ts.map +1 -0
  40. package/dist/Dom/Refs.js +61 -0
  41. package/dist/Dom/Render.d.ts +59 -0
  42. package/dist/Dom/Render.d.ts.map +1 -0
  43. package/dist/Dom/Render.js +71 -0
  44. package/dist/Dom/Types.d.ts +570 -0
  45. package/dist/Dom/Types.d.ts.map +1 -0
  46. package/dist/Dom/Types.js +1 -0
  47. package/dist/Dom/index.d.ts +20 -0
  48. package/dist/Dom/index.d.ts.map +1 -0
  49. package/dist/Dom/index.js +8 -0
  50. package/dist/Dom.d.ts +14 -0
  51. package/dist/Dom.d.ts.map +1 -0
  52. package/dist/Dom.js +13 -0
  53. package/dist/Focusable.d.ts +85 -0
  54. package/dist/Focusable.d.ts.map +1 -0
  55. package/dist/Focusable.js +35 -0
  56. package/dist/Form.d.ts +1695 -0
  57. package/dist/Form.d.ts.map +1 -0
  58. package/dist/Form.js +987 -0
  59. package/dist/Grid.d.ts +569 -0
  60. package/dist/Grid.d.ts.map +1 -0
  61. package/dist/Grid.js +379 -0
  62. package/dist/Group.d.ts +147 -0
  63. package/dist/Group.d.ts.map +1 -0
  64. package/dist/Group.js +63 -0
  65. package/dist/Heading.d.ts +86 -0
  66. package/dist/Heading.d.ts.map +1 -0
  67. package/dist/Heading.js +48 -0
  68. package/dist/Hovercard.d.ts +297 -0
  69. package/dist/Hovercard.d.ts.map +1 -0
  70. package/dist/Hovercard.js +188 -0
  71. package/dist/HttpRouter.d.ts +129 -6
  72. package/dist/HttpRouter.d.ts.map +1 -1
  73. package/dist/HttpRouter.js +196 -53
  74. package/dist/Link.d.ts +67 -28
  75. package/dist/Link.d.ts.map +1 -1
  76. package/dist/Link.js +91 -37
  77. package/dist/Listbox.d.ts +437 -0
  78. package/dist/Listbox.d.ts.map +1 -0
  79. package/dist/Listbox.js +316 -0
  80. package/dist/Menu.d.ts +972 -0
  81. package/dist/Menu.d.ts.map +1 -0
  82. package/dist/Menu.js +731 -0
  83. package/dist/Menubar.d.ts +367 -0
  84. package/dist/Menubar.d.ts.map +1 -0
  85. package/dist/Menubar.js +265 -0
  86. package/dist/Meter.d.ts +217 -0
  87. package/dist/Meter.d.ts.map +1 -0
  88. package/dist/Meter.js +94 -0
  89. package/dist/NativeDetails.d.ts +41 -0
  90. package/dist/NativeDetails.d.ts.map +1 -0
  91. package/dist/NativeDetails.js +40 -0
  92. package/dist/NativeDialog.d.ts +64 -0
  93. package/dist/NativeDialog.d.ts.map +1 -0
  94. package/dist/NativeDialog.js +50 -0
  95. package/dist/NativePopover.d.ts +41 -0
  96. package/dist/NativePopover.d.ts.map +1 -0
  97. package/dist/NativePopover.js +46 -0
  98. package/dist/Popover.d.ts +241 -0
  99. package/dist/Popover.d.ts.map +1 -0
  100. package/dist/Popover.js +141 -0
  101. package/dist/RadioGroup.d.ts +432 -0
  102. package/dist/RadioGroup.d.ts.map +1 -0
  103. package/dist/RadioGroup.js +291 -0
  104. package/dist/Role.d.ts +64 -0
  105. package/dist/Role.d.ts.map +1 -0
  106. package/dist/Role.js +27 -0
  107. package/dist/Select.d.ts +529 -0
  108. package/dist/Select.d.ts.map +1 -0
  109. package/dist/Select.js +407 -0
  110. package/dist/Separator.d.ts +54 -0
  111. package/dist/Separator.d.ts.map +1 -0
  112. package/dist/Separator.js +26 -0
  113. package/dist/Slider.d.ts +188 -0
  114. package/dist/Slider.d.ts.map +1 -0
  115. package/dist/Slider.js +96 -0
  116. package/dist/SpinButton.d.ts +188 -0
  117. package/dist/SpinButton.d.ts.map +1 -0
  118. package/dist/SpinButton.js +96 -0
  119. package/dist/Storybook.d.ts +76 -0
  120. package/dist/Storybook.d.ts.map +1 -0
  121. package/dist/Storybook.js +102 -0
  122. package/dist/Switch.d.ts +187 -0
  123. package/dist/Switch.d.ts.map +1 -0
  124. package/dist/Switch.js +116 -0
  125. package/dist/Tab.d.ts +26 -0
  126. package/dist/Tab.d.ts.map +1 -0
  127. package/dist/Tab.js +25 -0
  128. package/dist/Tabs.d.ts +591 -0
  129. package/dist/Tabs.d.ts.map +1 -0
  130. package/dist/Tabs.js +346 -0
  131. package/dist/Toolbar.d.ts +366 -0
  132. package/dist/Toolbar.d.ts.map +1 -0
  133. package/dist/Toolbar.js +245 -0
  134. package/dist/Tooltip.d.ts +296 -0
  135. package/dist/Tooltip.d.ts.map +1 -0
  136. package/dist/Tooltip.js +172 -0
  137. package/dist/Tree.d.ts +591 -0
  138. package/dist/Tree.d.ts.map +1 -0
  139. package/dist/Tree.js +434 -0
  140. package/dist/TreeGrid.d.ts +645 -0
  141. package/dist/TreeGrid.d.ts.map +1 -0
  142. package/dist/TreeGrid.js +420 -0
  143. package/dist/VisuallyHidden.d.ts +54 -0
  144. package/dist/VisuallyHidden.d.ts.map +1 -0
  145. package/dist/VisuallyHidden.js +27 -0
  146. package/dist/WindowSplitter.d.ts +376 -0
  147. package/dist/WindowSplitter.d.ts.map +1 -0
  148. package/dist/WindowSplitter.js +222 -0
  149. package/dist/index.d.ts +49 -0
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +49 -0
  152. package/package.json +45 -18
  153. package/src/HttpRouter.test.ts +0 -256
  154. package/src/HttpRouter.ts +0 -165
  155. package/src/Link.test.ts +0 -84
  156. package/src/Link.ts +0 -107
  157. package/src/index.ts +0 -2
@@ -0,0 +1,371 @@
1
+ /**
2
+ * Combobox keeps focus on its native input and exposes the active option through
3
+ * aria-activedescendant. Input, a manual native popover, and options share explicit value, open,
4
+ * and active 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
+ import * as NativePopover from "./NativePopover.js";
23
+ /**
24
+ * Effect Schema used by makeState to encode, decode, and hydrate Combobox state.
25
+ *
26
+ * @remarks
27
+ * ## Why
28
+ *
29
+ * A public schema makes hydration and serialized state use the same runtime validation as direct
30
+ * construction.
31
+ *
32
+ * ## Ownership and lifetime
33
+ *
34
+ * This declaration is data or schema metadata and acquires no resources.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import * as Schema from "effect/Schema";
39
+ * import * as Combobox from "@typed/ui/Combobox";
40
+ *
41
+ * const decodeState = Schema.decodeUnknownEffect(Combobox.StateSchema);
42
+ * ```
43
+ * @since 1.0.0
44
+ * @category schemas
45
+ */
46
+ export const StateSchema = Schema.Struct({
47
+ id: Schema.String,
48
+ value: Schema.String,
49
+ open: Schema.Boolean,
50
+ activeId: Schema.NullOr(Schema.String),
51
+ orientation: Schema.Literals(["vertical"]),
52
+ loop: Schema.Boolean,
53
+ rtl: Schema.Boolean,
54
+ virtualFocus: Schema.Boolean,
55
+ });
56
+ /**
57
+ * Creates hydrated Combobox state. value defaults to an empty string, open to false, activeId to
58
+ * null, loop to true, and virtual focus is enabled.
59
+ *
60
+ * @remarks
61
+ * ## Why
62
+ *
63
+ * State and collection ownership can be composed and tested independently from any renderer.
64
+ *
65
+ * ## Ownership and lifetime
66
+ *
67
+ * The returned Effect creates the RefSubject when run. That state is renderer-independent;
68
+ * collection registrations belong to the separate Scope that runs register or ref, not to state
69
+ * creation.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * import * as Effect from "effect/Effect";
74
+ * import * as Combobox from "@typed/ui/Combobox";
75
+ *
76
+ * const program = Effect.scoped(
77
+ * Effect.gen(function* () {
78
+ * const state = yield* Combobox.makeState({ id: "city" });
79
+ * const collection = yield* Combobox.makeCollection();
80
+ * return { state: yield* state, collection: yield* collection };
81
+ * }),
82
+ * );
83
+ * ```
84
+ * @since 1.0.0
85
+ * @category constructors
86
+ */
87
+ export function makeState(initial) {
88
+ return RefSubject.hydrate(StateSchema, {
89
+ id: initial.id,
90
+ value: initial.value ?? "",
91
+ open: initial.open ?? false,
92
+ activeId: initial.activeId ?? null,
93
+ orientation: "vertical",
94
+ loop: initial.loop ?? true,
95
+ rtl: false,
96
+ virtualFocus: true,
97
+ });
98
+ }
99
+ /**
100
+ * Creates a scoped Collection for Combobox items.
101
+ *
102
+ * @remarks
103
+ * ## Why
104
+ *
105
+ * State and collection ownership can be composed and tested independently from any renderer.
106
+ *
107
+ * ## Ownership and lifetime
108
+ *
109
+ * The returned Effect allocates the RefSubject in the caller's Scope. Each later registration is
110
+ * owned by the Scope that runs register, independently of this construction Effect.
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * import * as Effect from "effect/Effect";
115
+ * import * as Combobox from "@typed/ui/Combobox";
116
+ *
117
+ * const program = Effect.scoped(
118
+ * Effect.gen(function* () {
119
+ * const collection = yield* Combobox.makeCollection();
120
+ * return yield* collection;
121
+ * }),
122
+ * );
123
+ * ```
124
+ * @since 1.0.0
125
+ * @category constructors
126
+ */
127
+ export const makeCollection = Collection.makeState;
128
+ /**
129
+ * Stores the input value, clears activeId, and opens the popup in one state update.
130
+ *
131
+ * @remarks
132
+ * ## Why
133
+ *
134
+ * The operation exposes Combobox's transition directly so callers can compose it in Effect
135
+ * programs and native event handlers.
136
+ *
137
+ * ## Ownership and lifetime
138
+ *
139
+ * The returned Effect performs the update or DOM side effect only when run, preserves the declared
140
+ * error and service channels, and retains no resources after completion.
141
+ *
142
+ * ## Example
143
+ *
144
+ * Import with `import { setValue } from "@typed/ui/Combobox";` Extend the [Combobox.makeState
145
+ * runnable setup](/reference/%40typed%2Fui%2FCombobox%23makeState). Inside the linked Effect
146
+ * program invoke `yield* setValue(state, "New York")`, then read state to observe that value,
147
+ * `activeId: null`, and `open: true`.
148
+ * @since 1.0.0
149
+ * @category combinators
150
+ */
151
+ export function setValue(state, value) {
152
+ return RefSubject.update(state, (current) => ({ ...current, value, activeId: null, open: true }));
153
+ }
154
+ function openPopover(state, collection) {
155
+ return Effect.gen(function* () {
156
+ const current = yield* state;
157
+ const item = collection === undefined
158
+ ? undefined
159
+ : visibleItems(yield* collection).find((item) => item.value === current.value);
160
+ const next = yield* RefSubject.update(state, (value) => ({
161
+ ...value,
162
+ activeId: item?.id ?? value.activeId,
163
+ open: true,
164
+ }));
165
+ if (item !== undefined && collection !== undefined) {
166
+ yield* Composite.scrollActive({ state, collection });
167
+ }
168
+ return next;
169
+ });
170
+ }
171
+ function move(state, collection, direction) {
172
+ return Effect.gen(function* () {
173
+ const next = Composite.moveActiveId(visibleItems(yield* collection), yield* state, direction);
174
+ if (next === null)
175
+ return yield* state;
176
+ return yield* RefSubject.update(state, (current) => ({ ...current, activeId: next }));
177
+ });
178
+ }
179
+ function select(state, id, value) {
180
+ return RefSubject.update(state, (current) => ({ ...current, activeId: id, value, open: false }));
181
+ }
182
+ function selectActive(state, collection) {
183
+ return Effect.gen(function* () {
184
+ const activeId = (yield* state).activeId;
185
+ const item = activeId === null ? undefined : (yield* collection).find((item) => item.id === activeId);
186
+ return item?.value === undefined ? yield* state : yield* select(state, item.id, item.value);
187
+ });
188
+ }
189
+ function inputProps(options) {
190
+ const id = RefSubject.map(options.state, (state) => state.id);
191
+ const inputId = RefSubject.map(options.state, (state) => `${state.id}-input`);
192
+ const open = RefSubject.map(options.state, (state) => state.open);
193
+ const onkeydown = options.collection === undefined
194
+ ? undefined
195
+ : EventHandler.make(Effect.fn(function* (event) {
196
+ const direction = event.key === "ArrowDown" ? "next" : event.key === "ArrowUp" ? "previous" : undefined;
197
+ if (direction !== undefined) {
198
+ event.preventDefault();
199
+ if (!(yield* options.state).open) {
200
+ yield* openPopover(options.state, options.collection);
201
+ }
202
+ yield* move(options.state, options.collection, direction);
203
+ yield* Composite.scrollActive({
204
+ state: options.state,
205
+ collection: options.collection,
206
+ });
207
+ return;
208
+ }
209
+ if (event.key === "Enter") {
210
+ if ((yield* options.state).activeId === null)
211
+ return;
212
+ event.preventDefault();
213
+ yield* selectActive(options.state, options.collection);
214
+ return;
215
+ }
216
+ if (event.key === "Escape") {
217
+ yield* RefSubject.update(options.state, (state) => ({ ...state, open: false }));
218
+ }
219
+ }));
220
+ return () => ({
221
+ id: inputId,
222
+ role: "combobox",
223
+ "aria-autocomplete": "list",
224
+ "aria-controls": id,
225
+ "aria-expanded": open,
226
+ "aria-activedescendant": Composite.activeDescendant(options.state),
227
+ placeholder: options.placeholder,
228
+ ".value": RefSubject.map(options.state, (state) => state.value),
229
+ oninput: EventHandler.make(Effect.fn((event) => setValue(options.state, Dom.currentTarget(event).value))),
230
+ onfocus: openPopover(options.state, options.collection),
231
+ onkeydown,
232
+ });
233
+ }
234
+ function visibleItems(collection) {
235
+ return Collection.byDomOrder(collection).filter((item) => item.element === undefined || item.element.closest("[hidden]") === null);
236
+ }
237
+ /**
238
+ * Renders the native combobox input, keeps its value property synchronized, opens on focus, and
239
+ * handles Arrow, Enter, and Escape when a collection is supplied.
240
+ *
241
+ * @remarks
242
+ * ## Why
243
+ *
244
+ * The component applies the family behavior while leaving callers free to supply a custom host
245
+ * through the shared DOM boundary.
246
+ *
247
+ * ## Ownership and lifetime
248
+ *
249
+ * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
250
+ * collection registrations only when rendered. The rendering Scope removes those resources;
251
+ * unrelated nodes and attributes remain caller-owned.
252
+ *
253
+ * ## Example
254
+ *
255
+ * Import with `import { Input } from "@typed/ui/Combobox";` Extend the [Combobox.makeState runnable
256
+ * setup](/reference/%40typed%2Fui%2FCombobox%23makeState). Replace the linked program's final
257
+ * snapshot read with `Input({ state, placeholder: "Choose a city" })`; render that Fx before the
258
+ * same Scope closes.
259
+ * @since 1.0.0
260
+ * @category components
261
+ */
262
+ export function Input(options, host) {
263
+ return Dom.renderHost()(options, host, inputProps(options), "", (props) => html `<input ...${props} />`);
264
+ }
265
+ function popoverProps(options) {
266
+ const id = RefSubject.map(options.state, (state) => state.id);
267
+ const inputId = RefSubject.map(options.state, (state) => `${state.id}-input`);
268
+ return () => ({
269
+ id,
270
+ role: "listbox",
271
+ "aria-labelledby": inputId,
272
+ popover: "manual",
273
+ ontoggle: EventHandler.make(Effect.fn(function* (event) {
274
+ const open = Dom.toggleState(event) === "open";
275
+ const current = yield* options.state;
276
+ if (current.open === open)
277
+ return current;
278
+ const next = yield* RefSubject.update(options.state, (state) => ({ ...state, open }));
279
+ if (!open || options.collection === undefined)
280
+ return next;
281
+ const item = (yield* options.collection).find((item) => item.value === next.value);
282
+ if (item === undefined)
283
+ return next;
284
+ const selected = yield* RefSubject.update(options.state, (state) => ({
285
+ ...state,
286
+ activeId: item.id,
287
+ }));
288
+ yield* Composite.scrollActive({ state: options.state, collection: options.collection });
289
+ return selected;
290
+ })),
291
+ ref: Dom.composeRefs(options.state, NativePopover.ref(options.state)),
292
+ });
293
+ }
294
+ /**
295
+ * Renders manual-popover listbox content, mirrors native toggle events into open state, and
296
+ * scrolls the selected option when opened.
297
+ *
298
+ * @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
+ * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
307
+ * collection registrations only when rendered. The rendering Scope removes those resources;
308
+ * unrelated nodes and attributes remain caller-owned.
309
+ *
310
+ * ## Example
311
+ *
312
+ * Import with `import { Popover } from "@typed/ui/Combobox";` Extend the [Combobox.makeState
313
+ * runnable setup](/reference/%40typed%2Fui%2FCombobox%23makeState). Replace the linked program's
314
+ * final snapshot read with `Popover({ state, content: "Cities" })`; render that Fx before the same
315
+ * Scope closes.
316
+ * @since 1.0.0
317
+ * @category components
318
+ */
319
+ export function Popover(options, host) {
320
+ return Dom.renderHost()(options, host, popoverProps(options), options.content, (props, content) => {
321
+ return html `<div ...${props}>${content}</div>`;
322
+ });
323
+ }
324
+ function itemProps(options) {
325
+ const selected = RefSubject.map(options.state, (state) => state.value === options.value);
326
+ const register = options.collection === undefined
327
+ ? undefined
328
+ : Collection.ref(options.collection, {
329
+ id: options.id,
330
+ value: options.value,
331
+ textValue: options.textValue ?? options.value,
332
+ disabled: options.disabled,
333
+ });
334
+ return () => ({
335
+ id: options.id,
336
+ role: "option",
337
+ "aria-selected": selected,
338
+ "aria-disabled": options.disabled ?? false,
339
+ tabindex: Composite.tabIndex(options.state, options.id),
340
+ onclick: options.disabled === true ? Effect.void : select(options.state, options.id, options.value),
341
+ ref: Dom.composeRefs(register, options.ref),
342
+ });
343
+ }
344
+ /**
345
+ * Renders and optionally registers one option; disabled options expose aria-disabled and do not
346
+ * select on click.
347
+ *
348
+ * @remarks
349
+ * ## Why
350
+ *
351
+ * The component applies the family behavior while leaving callers free to supply a custom host
352
+ * through the shared DOM boundary.
353
+ *
354
+ * ## Ownership and lifetime
355
+ *
356
+ * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
357
+ * collection registrations only when rendered. The rendering Scope removes those resources;
358
+ * unrelated nodes and attributes remain caller-owned.
359
+ *
360
+ * ## Example
361
+ *
362
+ * Import with `import { Item } from "@typed/ui/Combobox";` Extend the [Combobox.makeState runnable
363
+ * setup](/reference/%40typed%2Fui%2FCombobox%23makeState). Replace the linked program's final
364
+ * snapshot read with `Item({ state, id: "nyc", value: "New York", content: "New York" })`; render
365
+ * that Fx before the same Scope closes.
366
+ * @since 1.0.0
367
+ * @category components
368
+ */
369
+ export function Item(options, host) {
370
+ return Dom.renderHost()(options, host, itemProps(options), options.content, (props, content) => html `<div ...${props}>${content}</div>`);
371
+ }
@@ -0,0 +1,127 @@
1
+ import type * as Effect from "effect/Effect";
2
+ import { Fx } from "@typed/fx";
3
+ import { type Renderable } from "@typed/template";
4
+ type ComponentFx<Yield extends Effect.Effect<any, any, any>, Result extends Renderable.Any> = [
5
+ Fx.Fx<Renderable.Success<Result>, Effect.Error<Yield> | Renderable.Error<Result>, Effect.Services<Yield> | Renderable.Services<Result>>
6
+ ] extends [Fx.Fx<infer Success, infer Error, infer Services>] ? Fx.Fx<Success, Error, Services> : never;
7
+ type ComponentResult<Args extends ReadonlyArray<any>, Result> = Args extends readonly [] ? Result : (...args: Args) => Result;
8
+ /**
9
+ * Type-level contracts used by the `component` constructor.
10
+ *
11
+ * @remarks
12
+ * ## Why
13
+ *
14
+ * The namespace keeps the overload-rich generator contract attached to the
15
+ * callable constructor while still making it available to library authors who
16
+ * wrap `component`.
17
+ *
18
+ * ## Ownership and lifetime
19
+ *
20
+ * These types acquire nothing. The `Fx` produced by `component` is lazy; its
21
+ * running Effect `Scope` owns yielded effects, subscriptions, and cleanup.
22
+ *
23
+ * @since 1.0.0
24
+ * @category models
25
+ */
26
+ export declare namespace component {
27
+ /**
28
+ * The overloaded callable type of `component`.
29
+ *
30
+ * @remarks
31
+ * ## Why
32
+ *
33
+ * `Gen` preserves argument, error, and service inference across generator
34
+ * components and optional post-construction pipe functions. A zero-argument
35
+ * body returns an `Fx`; a body with arguments returns a component function.
36
+ *
37
+ * ## Ownership and lifetime
38
+ *
39
+ * Calling a `Gen` value constructs a lazy `Fx` and starts no work. Resources
40
+ * yielded by the generator belong to the Scope that eventually runs that Fx.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { component } from "@typed/ui/Component"
45
+ * import { html } from "@typed/template"
46
+ *
47
+ * const define: component.Gen = component
48
+ * const Greeting = define(function* (name: string) {
49
+ * return html`<p>Hello ${name}</p>`
50
+ * })
51
+ * ```
52
+ *
53
+ * @since 1.0.0
54
+ * @category models
55
+ */
56
+ type Gen = {
57
+ /** Creates a component directly for a zero-argument body. @since 1.0.0 @category constructors */
58
+ <Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any>(body: () => Generator<Yield, Result, any>): ComponentFx<Yield, Result>;
59
+ /** Creates a component function while preserving the generator's parameters. @since 1.0.0 @category constructors */
60
+ <Args extends readonly [any, ...ReadonlyArray<any>], Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any>(body: (...args: Args) => Generator<Yield, Result, any>): (...args: Args) => ComponentFx<Yield, Result>;
61
+ /** Applies one argument-aware transformation to the generated Fx. @since 1.0.0 @category constructors */
62
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A): ComponentResult<Args, A>;
63
+ /** Applies two ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
64
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B): ComponentResult<Args, B>;
65
+ /** Applies three ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
66
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C): ComponentResult<Args, C>;
67
+ /** Applies four ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
68
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C, D>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D): ComponentResult<Args, D>;
69
+ /** Applies five ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
70
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C, D, E>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E): ComponentResult<Args, E>;
71
+ /** Applies six ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
72
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C, D, E, F>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F): ComponentResult<Args, F>;
73
+ /** Applies seven ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
74
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C, D, E, F, G>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G): ComponentResult<Args, G>;
75
+ /** Applies eight ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
76
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C, D, E, F, G, H>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H): ComponentResult<Args, H>;
77
+ /** Applies nine ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
78
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C, D, E, F, G, H, I>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I): ComponentResult<Args, I>;
79
+ /** Applies ten ordered argument-aware transformations to the generated Fx. @since 1.0.0 @category constructors */
80
+ <Args extends ReadonlyArray<any>, Yield extends Effect.Effect<any, any, any>, const Result extends Renderable.Any, A, B, C, D, E, F, G, H, I, J>(body: (...args: Args) => Generator<Yield, Result, any>, a: (_: ComponentFx<Yield, Result>, ...args: Args) => A, b: (_: A, ...args: Args) => B, c: (_: B, ...args: Args) => C, d: (_: C, ...args: Args) => D, e: (_: D, ...args: Args) => E, f: (_: E, ...args: Args) => F, g: (_: F, ...args: Args) => G, h: (_: G, ...args: Args) => H, i: (_: H, ...args: Args) => I, j: (_: I, ...args: Args) => J): ComponentResult<Args, J>;
81
+ };
82
+ }
83
+ /**
84
+ * Creates an Fx component from a generator that may return any Renderable. A
85
+ * zero-arity generator creates an Fx directly; generators with parameters
86
+ * create an Fx function. Additional functions are piped over the generated Fx
87
+ * using the same argument-forwarding behavior as Fx.fn.
88
+ *
89
+ * @remarks
90
+ * ## Why
91
+ *
92
+ * Components often need Effect services before they can return a template,
93
+ * DOM node, render event, or other `Renderable`. This constructor turns that
94
+ * generator into a single `Fx<RenderEvent, E, R>` boundary without introducing
95
+ * a component tree or a second runtime beside Effect.
96
+ *
97
+ * ## Ownership and lifetime
98
+ *
99
+ * Construction is lazy. Each run evaluates the generator inside the running
100
+ * Fx's Effect lifetime; interruption and Scope finalization release everything
101
+ * acquired by yielded effects and by the returned renderable. The constructor
102
+ * does not own DOM outside the render events emitted by that renderable.
103
+ *
104
+ * ## Composition
105
+ *
106
+ * A parameterless generator returns an Fx directly. A generator with
107
+ * parameters returns a function, and optional pipe functions receive the
108
+ * generated Fx followed by the original arguments, matching `Fx.fn`.
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * import { component } from "@typed/ui/Component"
113
+ * import { html } from "@typed/template"
114
+ * import { Effect } from "effect"
115
+ *
116
+ * const Greeting = component(function* (name: string) {
117
+ * const greeting = yield* Effect.succeed("Hello")
118
+ * return html`<p>${greeting} ${name}</p>`
119
+ * })
120
+ * ```
121
+ *
122
+ * @since 1.0.0
123
+ * @category constructors
124
+ */
125
+ export declare const component: component.Gen;
126
+ export {};
127
+ //# sourceMappingURL=Component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Component.d.ts","sourceRoot":"","sources":["../src/Component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEtE,KAAK,WAAW,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,SAAS,UAAU,CAAC,GAAG,IAAI;IAC5F,EAAE,CAAC,EAAE,CACH,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAC1B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,EAC9C,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CACrD;CACF,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,OAAO,EAAE,MAAM,KAAK,EAAE,MAAM,QAAQ,CAAC,CAAC,GACzD,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,GAC/B,KAAK,CAAC;AAEV,KAAK,eAAe,CAAC,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,IAAI,SAAS,SAAS,EAAE,GACpF,MAAM,GACN,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;AAE9B;;;;;;;;;;;;;;;;;GAiBG;AACH,yBAAiB,SAAS,CAAC;IACzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,KAAY,GAAG,GAAG;QAChB,iGAAiG;QACjG,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EAC9E,IAAI,EAAE,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,GACxC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAE9B,oHAAoH;QACpH,CACE,IAAI,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,EAClD,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EAEnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,GACrD,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAEjD,yGAAyG;QACzG,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GACrD,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,kHAAkH;QAClH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,oHAAoH;QACpH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,mHAAmH;QACnH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,mHAAmH;QACnH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,kHAAkH;QAClH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,oHAAoH;QACpH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,oHAAoH;QACpH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,mHAAmH;QACnH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE5B,kHAAkH;QAClH,CACE,IAAI,SAAS,aAAa,CAAC,GAAG,CAAC,EAC/B,KAAK,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1C,KAAK,CAAC,MAAM,SAAS,UAAU,CAAC,GAAG,EACnC,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EAED,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EACtD,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,EAC7B,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,CAAC,GAC5B,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;KAC7B,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,GA0BjC,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { Fx } from "@typed/fx";
2
+ import { liftRenderableToFx } from "@typed/template";
3
+ /**
4
+ * Creates an Fx component from a generator that may return any Renderable. A
5
+ * zero-arity generator creates an Fx directly; generators with parameters
6
+ * create an Fx function. Additional functions are piped over the generated Fx
7
+ * using the same argument-forwarding behavior as Fx.fn.
8
+ *
9
+ * @remarks
10
+ * ## Why
11
+ *
12
+ * Components often need Effect services before they can return a template,
13
+ * DOM node, render event, or other `Renderable`. This constructor turns that
14
+ * generator into a single `Fx<RenderEvent, E, R>` boundary without introducing
15
+ * a component tree or a second runtime beside Effect.
16
+ *
17
+ * ## Ownership and lifetime
18
+ *
19
+ * Construction is lazy. Each run evaluates the generator inside the running
20
+ * Fx's Effect lifetime; interruption and Scope finalization release everything
21
+ * acquired by yielded effects and by the returned renderable. The constructor
22
+ * does not own DOM outside the render events emitted by that renderable.
23
+ *
24
+ * ## Composition
25
+ *
26
+ * A parameterless generator returns an Fx directly. A generator with
27
+ * parameters returns a function, and optional pipe functions receive the
28
+ * generated Fx followed by the original arguments, matching `Fx.fn`.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * import { component } from "@typed/ui/Component"
33
+ * import { html } from "@typed/template"
34
+ * import { Effect } from "effect"
35
+ *
36
+ * const Greeting = component(function* (name: string) {
37
+ * const greeting = yield* Effect.succeed("Hello")
38
+ * return html`<p>${greeting} ${name}</p>`
39
+ * })
40
+ * ```
41
+ *
42
+ * @since 1.0.0
43
+ * @category constructors
44
+ */
45
+ export const component = function (body, ...pipeables) {
46
+ if (body.length === 0) {
47
+ let result = Fx.gen(function* () {
48
+ const renderable = yield* body();
49
+ return liftRenderableToFx(renderable);
50
+ });
51
+ for (const pipeable of pipeables) {
52
+ result = pipeable(result);
53
+ }
54
+ return result;
55
+ }
56
+ return Fx.fn(function* (...args) {
57
+ const renderable = yield* body(...args);
58
+ return liftRenderableToFx(renderable);
59
+ }, ...pipeables);
60
+ };