@rhi-zone/rainbow-ui 0.2.0-alpha.3 → 0.2.0-alpha.4

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/dist/index.js CHANGED
@@ -1,34 +1,34 @@
1
- import { h as g } from "./html-C8SnQjvU.js";
2
- import { above as l, beside as p, bindAttr as f, bindCheckbox as x, bindClass as S, bindInput as w, bindSelect as W, bindShow as v, bindText as y, checkboxWidget as k, concat as C, dynamic as E, each as F, eachKeyed as A, focus as I, foldWidget as K, inputWidget as L, map as N, match as B, mount as D, narrow as J, numberInputWidget as T, on as V, register as j, selectWidget as q, show as z, stack as G, subscribe as H, subscribeNow as M, template as O, textareaWidget as P, watchAll as Q, withScope as R } from "./widget.js";
3
- import { createForm as X, createFormState as Y, isDirty as Z, isFormValid as _, shouldShowError as $ } from "./form-state.js";
1
+ import { h as u } from "./html-C8SnQjvU.js";
2
+ import { above as l, beside as p, bindAttr as f, bindCheckbox as x, bindClass as S, bindInput as w, bindSelect as W, bindShow as v, bindText as y, checkboxWidget as k, concat as C, dynamic as E, each as F, eachKeyed as A, focus as I, foldWidget as K, h as L, inputWidget as N, map as B, match as D, mount as J, narrow as T, numberInputWidget as V, on as j, prop as q, register as z, selectWidget as G, show as H, slot as M, stack as O, subscribe as P, subscribeNow as Q, template as R, textareaWidget as U, watchAll as X, withScope as Y } from "./widget.js";
3
+ import { createForm as _, createFormState as $, isDirty as ee, isFormValid as te, shouldShowError as ne } from "./form-state.js";
4
4
  import { signal as a } from "@rhi-zone/rainbow";
5
- import { attrBoolean as te, attrJson as ne, attrNumber as ie, attrString as oe, attrsFrom as re, defineElement as se } from "./elements.js";
6
- function d(e, n, t, r, i) {
7
- const o = e(
5
+ import { attrBoolean as ie, attrJson as re, attrNumber as se, attrString as ae, attrsFrom as ce, defineElement as de } from "./elements.js";
6
+ function d(e, n, t, r, o) {
7
+ const i = e(
8
8
  n,
9
9
  () => r(t.get()),
10
- i
10
+ o
11
11
  ), s = t.subscribe(() => {
12
12
  });
13
13
  return () => {
14
- s(), o();
14
+ s(), i();
15
15
  };
16
16
  }
17
17
  function b(e) {
18
18
  const n = a(e.get());
19
- function t(i) {
20
- const o = i;
21
- n.set(o.detail.bindings);
19
+ function t(o) {
20
+ const i = o;
21
+ n.set(i.detail.bindings);
22
22
  }
23
23
  return e.addEventListener("change", t), [n, () => e.removeEventListener("change", t)];
24
24
  }
25
25
  export {
26
26
  l as above,
27
- te as attrBoolean,
28
- ne as attrJson,
29
- ie as attrNumber,
30
- oe as attrString,
31
- re as attrsFrom,
27
+ ie as attrBoolean,
28
+ re as attrJson,
29
+ se as attrNumber,
30
+ ae as attrString,
31
+ ce as attrsFrom,
32
32
  p as beside,
33
33
  f as bindAttr,
34
34
  x as bindCheckbox,
@@ -40,34 +40,37 @@ export {
40
40
  b as bindingsStoreSignal,
41
41
  k as checkboxWidget,
42
42
  C as concat,
43
- X as createForm,
44
- Y as createFormState,
45
- se as defineElement,
43
+ _ as createForm,
44
+ $ as createFormState,
45
+ de as defineElement,
46
46
  E as dynamic,
47
47
  F as each,
48
48
  A as eachKeyed,
49
49
  I as focus,
50
50
  K as foldWidget,
51
- g as html,
52
- L as inputWidget,
53
- Z as isDirty,
54
- _ as isFormValid,
51
+ L as h,
52
+ u as html,
53
+ N as inputWidget,
54
+ ee as isDirty,
55
+ te as isFormValid,
55
56
  d as keybindsContext,
56
- N as map,
57
- B as match,
58
- D as mount,
59
- J as narrow,
60
- T as numberInputWidget,
61
- V as on,
62
- j as register,
63
- q as selectWidget,
64
- $ as shouldShowError,
65
- z as show,
66
- G as stack,
67
- H as subscribe,
68
- M as subscribeNow,
69
- O as template,
70
- P as textareaWidget,
71
- Q as watchAll,
72
- R as withScope
57
+ B as map,
58
+ D as match,
59
+ J as mount,
60
+ T as narrow,
61
+ V as numberInputWidget,
62
+ j as on,
63
+ q as prop,
64
+ z as register,
65
+ G as selectWidget,
66
+ ne as shouldShowError,
67
+ H as show,
68
+ M as slot,
69
+ O as stack,
70
+ P as subscribe,
71
+ Q as subscribeNow,
72
+ R as template,
73
+ U as textareaWidget,
74
+ X as watchAll,
75
+ Y as withScope
73
76
  };
package/dist/widget.d.ts CHANGED
@@ -31,7 +31,7 @@
31
31
  * false and rebuild them when it becomes true again.
32
32
  */
33
33
  import { type Signal, type ReadonlySignal, type Lens, type Prism, type AsyncData } from "@rhi-zone/rainbow";
34
- import type { AnyEl, El, FlowContent, DivEl, InputEl, InputAttrs, TextareaEl, TextareaAttrs, SelectEl, SelectAttrs } from "./html.js";
34
+ import type { AnyEl, El, FlowContent, DivEl, InputEl, InputAttrs, TextareaEl, TextareaAttrs, SelectEl, SelectAttrs, GlobalAttrs } from "./html.js";
35
35
  /**
36
36
  * A widget is a pure function from a reactive signal to a typed DOM node.
37
37
  * Calling a widget subscribes it to the signal; the returned node is updated
@@ -91,6 +91,16 @@ export declare function mount<T, E extends AnyEl>(widget: Widget<T, E>, signal:
91
91
  * focus(opPicker, field('op'))
92
92
  */
93
93
  export declare function focus<A, B, E extends AnyEl>(w: Widget<B, E>, l: Lens<A, B>): Widget<A, E>;
94
+ /**
95
+ * Sugar for `focus(w, field(key))`. Zoom into a named property of the signal.
96
+ * The most common use of `focus` — use this instead when the lens is a simple
97
+ * field access.
98
+ *
99
+ * @example
100
+ * prop(each(rowWidget), 'items') // Widget<{ items: Row[] }>
101
+ * prop(nameWidget, 'name') // Widget<{ name: string }>
102
+ */
103
+ export declare function prop<T, K extends keyof T & string, E extends AnyEl>(w: Widget<T[K], E>, key: K): Widget<T, E>;
94
104
  /**
95
105
  * Zoom into a sum variant. The child widget renders when the prism matches;
96
106
  * renders an empty container when it doesn't. Container switches on match
@@ -199,14 +209,21 @@ export type RefsMap<R extends Record<string, keyof HTMLElementTagNameMap>> = {
199
209
  readonly [K in keyof R]: El<R[K] & string, HTMLElementTagNameMap[R[K]]>;
200
210
  };
201
211
  /**
202
- * Template combinator. Parses `innerHTML` once (at definition time), then for
203
- * each widget instantiation clones the template, queries out typed DOM refs via
204
- * `data-ref` attributes, and calls `bind` with the signal and those refs.
212
+ * **Performance escape hatch.** Prefer the reactive hyperscript factories
213
+ * (`h.div`, `h.span`, …) for normal widget authoring they are type-safe,
214
+ * compose naturally with slots and combinators, and avoid the `data-ref`
215
+ * indirection.
216
+ *
217
+ * Use `template` only when instantiation count is high and the clone-vs-create
218
+ * difference is measurable: it parses `innerHTML` once at definition time and
219
+ * calls `cloneNode(true)` on each instantiation, which is faster than N
220
+ * `createElement` calls for large identical subtrees (e.g. a `eachKeyed` row
221
+ * with many static nodes).
205
222
  *
206
223
  * Refs are queried as `tagName[data-ref="refName"]`, so `{ name: "span" }`
207
224
  * expects `<span data-ref="name">` in the template. Using `data-ref` rather
208
- * than `id` means the same template can be cloned many times (e.g. inside
209
- * `eachKeyed`) without duplicate-ID issues.
225
+ * than `id` means the same template can be cloned many times without
226
+ * duplicate-ID issues.
210
227
  *
211
228
  * `bind` is called inside the widget call context, so any `subscribe` calls
212
229
  * inside it are tracked and cleaned up by `mount` / parent combinators.
@@ -214,12 +231,11 @@ export type RefsMap<R extends Record<string, keyof HTMLElementTagNameMap>> = {
214
231
  * @throws if a declared ref is absent from the cloned template.
215
232
  *
216
233
  * @example
217
- * const cardWidget = template(
218
- * `<div class="card"><span data-ref="name"></span><b data-ref="score"></b></div>`,
219
- * { name: "span", score: "b" } as const,
234
+ * // High-volume row widget — justified use of template()
235
+ * const rowWidget = template(
236
+ * `<tr><td data-ref="name"></td><td data-ref="score"></td></tr>`,
237
+ * { name: "td", score: "td" } as const,
220
238
  * (s, { name, score }) => {
221
- * name.node.textContent = s.get().label
222
- * score.node.textContent = String(s.get().value)
223
239
  * subscribe(s, v => {
224
240
  * name.node.textContent = v.label
225
241
  * score.node.textContent = String(v.value)
@@ -441,4 +457,62 @@ export declare function selectWidget(options: {
441
457
  value: string;
442
458
  label: string;
443
459
  }[], attrs?: SelectAttrs): Widget<string, SelectEl>;
460
+ /**
461
+ * A reactive child: either a static element, a string, or a widget that
462
+ * accepts the same signal type `T` and returns any element.
463
+ */
464
+ export type RChild<T> = AnyEl | string | Widget<T, AnyEl>;
465
+ /**
466
+ * Reactive hyperscript factories — the same element tags as `html.ts` but
467
+ * returning `Widget<T, El>` instead of `El`. Import as:
468
+ *
469
+ * import { h } from '@rhi-zone/rainbow-ui/widget'
470
+ *
471
+ * Widget children receive the same signal as their parent. Static children
472
+ * (`AnyEl`) are deep-cloned on each widget invocation so that the same static
473
+ * node can be safely reused across multiple widget instances.
474
+ */
475
+ export declare const h: {
476
+ readonly div: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"div", HTMLDivElement>;
477
+ readonly section: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"section", HTMLElement>;
478
+ readonly article: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"article", HTMLElement>;
479
+ readonly header: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"header", HTMLElement>;
480
+ readonly footer: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"footer", HTMLElement>;
481
+ readonly main: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"main", HTMLElement>;
482
+ readonly nav: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"nav", HTMLElement>;
483
+ readonly h1: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"h1", HTMLHeadingElement>;
484
+ readonly h2: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"h2", HTMLHeadingElement>;
485
+ readonly h3: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"h3", HTMLHeadingElement>;
486
+ readonly h4: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"h4", HTMLHeadingElement>;
487
+ readonly h5: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"h5", HTMLHeadingElement>;
488
+ readonly h6: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"h6", HTMLHeadingElement>;
489
+ readonly p: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"p", HTMLParagraphElement>;
490
+ readonly span: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"span", HTMLSpanElement>;
491
+ readonly a: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"a", HTMLAnchorElement>;
492
+ readonly em: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"em", HTMLElement>;
493
+ readonly strong: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"strong", HTMLElement>;
494
+ readonly code: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"code", HTMLElement>;
495
+ readonly pre: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"pre", HTMLPreElement>;
496
+ readonly ul: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"ul", HTMLUListElement>;
497
+ readonly ol: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"ol", HTMLOListElement>;
498
+ readonly li: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"li", HTMLLIElement>;
499
+ readonly button: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"button", HTMLButtonElement>;
500
+ readonly label: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"label", HTMLLabelElement>;
501
+ readonly form: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"form", HTMLFormElement>;
502
+ readonly fieldset: <T>(attrs: GlobalAttrs, ...children: RChild<T>[]) => (s: Signal<T>) => El<"fieldset", HTMLFieldSetElement>;
503
+ };
504
+ /** A widget that takes no meaningful signal and renders flow content. */
505
+ export type Slot = Widget<void, FlowContent>;
506
+ /** A widget that takes a typed signal `T` and renders flow content. */
507
+ export type ScopedSlot<T> = Widget<T, FlowContent>;
508
+ /**
509
+ * Mount a slot widget by replacing a placeholder element.
510
+ * If no slot is provided, removes the placeholder.
511
+ * The slot signal defaults to `s` (cast) if `slotSignal` is omitted.
512
+ *
513
+ * @example
514
+ * slot(placeholder, s, v => v.actionsSlot) // slot signal = s
515
+ * slot(placeholder, s, v => v.rowSlot, s.focus(rowLens)) // slot signal = focused
516
+ */
517
+ export declare function slot<Props, T>(placeholder: HTMLElement, s: Signal<Props>, extract: (props: Props) => Widget<T, FlowContent> | undefined, slotSignal?: Signal<T>): void;
444
518
  export {};
package/dist/widget.js CHANGED
@@ -1,203 +1,206 @@
1
- import { index as C, stateful as S, lens as L, tagged as W, signal as B } from "@rhi-zone/rainbow";
2
- import { i as N, s as $, o as F, t as I } from "./html-C8SnQjvU.js";
3
- let k = null;
4
- function i(e) {
5
- k == null || k.push(e);
6
- }
7
- function h(e) {
8
- const n = k, o = [];
9
- k = o;
1
+ import { index as E, stateful as L, field as W, lens as B, tagged as $, signal as j } from "@rhi-zone/rainbow";
2
+ import { i as _, s as F, o as I, t as O } from "./html-C8SnQjvU.js";
3
+ let y = null;
4
+ function l(e) {
5
+ y == null || y.push(e);
6
+ }
7
+ function g(e) {
8
+ const n = y, o = [];
9
+ y = o;
10
10
  const t = e();
11
- return k = n, [t, () => {
11
+ return y = n, [t, () => {
12
12
  for (const c of o) c();
13
13
  }];
14
14
  }
15
- function M(e) {
16
- return h(e);
15
+ function V(e) {
16
+ return g(e);
17
17
  }
18
- function v(e, n) {
19
- i(e.subscribe(n));
18
+ function w(e, n) {
19
+ l(e.subscribe(n));
20
20
  }
21
- function O(e) {
22
- i(e);
21
+ function H(e) {
22
+ l(e);
23
23
  }
24
- function T(e, n, o) {
25
- const [t, c] = h(() => e(n));
24
+ function R(e, n, o) {
25
+ const [t, c] = g(() => e(n));
26
26
  return o.appendChild(t.node), () => {
27
27
  t.node.remove(), c();
28
28
  };
29
29
  }
30
- function V(e, n) {
30
+ function P(e, n) {
31
31
  return (o) => e(o.focus(n));
32
32
  }
33
- function H(e, n) {
33
+ function U(e, n) {
34
+ return P(e, W(n));
35
+ }
36
+ function z(e, n) {
34
37
  return (o) => {
35
38
  const t = document.createElement("div");
36
39
  t.dataset.narrow = "";
37
40
  let c = null, r = null;
38
- const u = o, d = () => {
39
- r = u.narrow(n);
40
- const [a, l] = h(() => e(r));
41
- c = l, t.appendChild(a.node);
41
+ const d = o, u = () => {
42
+ r = d.narrow(n);
43
+ const [a, f] = g(() => e(r));
44
+ c = f, t.appendChild(a.node);
42
45
  };
43
- return v(o, (a) => {
44
- const l = n.view(a);
45
- l !== void 0 && c === null ? d() : l === void 0 && c !== null && (c(), c = null, r = null, t.replaceChildren());
46
- }), n.view(o.get()) !== void 0 && d(), i(() => c == null ? void 0 : c()), { _tag: "div", node: t };
46
+ return w(o, (a) => {
47
+ const f = n.view(a);
48
+ f !== void 0 && c === null ? u() : f === void 0 && c !== null && (c(), c = null, r = null, t.replaceChildren());
49
+ }), n.view(o.get()) !== void 0 && u(), l(() => c == null ? void 0 : c()), { _tag: "div", node: t };
47
50
  };
48
51
  }
49
- function R(e) {
52
+ function D(e) {
50
53
  return (n) => {
51
54
  const o = n, t = document.createElement("div");
52
55
  t.dataset.each = "";
53
56
  let c = [];
54
- const r = (d) => {
57
+ const r = (u) => {
55
58
  for (const s of c) s();
56
59
  c = [], t.replaceChildren();
57
- for (let s = 0; s < d.length; s++) {
58
- const a = s, l = L(
59
- (f) => f[a],
60
- (f, p) => {
61
- const b = [...p];
62
- return b[a] = f, b;
60
+ for (let s = 0; s < u.length; s++) {
61
+ const a = s, f = B(
62
+ (p) => p[a],
63
+ (p, h) => {
64
+ const b = [...h];
65
+ return b[a] = p, b;
63
66
  }
64
- ), g = o.focus(l), [m, w] = h(() => e(g));
65
- c.push(w), t.appendChild(m.node);
67
+ ), m = o.focus(f), [v, C] = g(() => e(m));
68
+ c.push(C), t.appendChild(v.node);
66
69
  }
67
70
  };
68
71
  r(n.get());
69
- const u = n.map((d) => d.length);
70
- return v(u, () => r(n.get())), i(() => {
71
- for (const d of c) d();
72
+ const d = n.map((u) => u.length);
73
+ return w(d, () => r(n.get())), l(() => {
74
+ for (const u of c) u();
72
75
  }), { _tag: "div", node: t };
73
76
  };
74
77
  }
75
- function U(e, n) {
78
+ function G(e, n) {
76
79
  return (o) => {
77
80
  const t = o, c = document.createElement("div");
78
81
  c.dataset.beside = "";
79
- const r = t.focus(C(0)), u = t.focus(C(1)), [d, s] = h(() => e(r)), [a, l] = h(() => n(u));
80
- return c.appendChild(d.node), c.appendChild(a.node), i(s), i(l), { _tag: "div", node: c };
82
+ const r = t.focus(E(0)), d = t.focus(E(1)), [u, s] = g(() => e(r)), [a, f] = g(() => n(d));
83
+ return c.appendChild(u.node), c.appendChild(a.node), l(s), l(f), { _tag: "div", node: c };
81
84
  };
82
85
  }
83
- function z(e, n) {
86
+ function J(e, n) {
84
87
  return (o) => {
85
88
  const t = o, c = document.createElement("div");
86
89
  c.dataset.above = "";
87
- const r = t.focus(C(0)), u = t.focus(C(1)), [d, s] = h(() => e(r)), [a, l] = h(() => n(u));
88
- return c.appendChild(d.node), c.appendChild(a.node), i(s), i(l), { _tag: "div", node: c };
90
+ const r = t.focus(E(0)), d = t.focus(E(1)), [u, s] = g(() => e(r)), [a, f] = g(() => n(d));
91
+ return c.appendChild(u.node), c.appendChild(a.node), l(s), l(f), { _tag: "div", node: c };
89
92
  };
90
93
  }
91
- function D(e, n) {
94
+ function Q(e, n) {
92
95
  return (o) => {
93
- const t = S(e, o);
96
+ const t = L(e, o);
94
97
  return n(t);
95
98
  };
96
99
  }
97
- function G(e, n) {
100
+ function X(e, n) {
98
101
  return (o) => {
99
102
  const t = o.narrow(n);
100
103
  return e(t);
101
104
  };
102
105
  }
103
- function J(e, n) {
106
+ function Y(e, n) {
104
107
  return (o) => {
105
108
  const t = document.createElement("div");
106
109
  t.dataset.show = "";
107
- const [c, r] = h(() => e(o));
108
- t.appendChild(c.node), i(r);
109
- const u = (d) => {
110
- t.style.display = n(d) ? "" : "none";
110
+ const [c, r] = g(() => e(o));
111
+ t.appendChild(c.node), l(r);
112
+ const d = (u) => {
113
+ t.style.display = n(u) ? "" : "none";
111
114
  };
112
- return u(o.get()), v(o, u), { _tag: "div", node: t };
115
+ return d(o.get()), w(o, d), { _tag: "div", node: t };
113
116
  };
114
117
  }
115
- function Q(e, n) {
118
+ function Z(e, n) {
116
119
  return (o) => {
117
120
  const t = document.createElement("div");
118
121
  t.dataset.concat = "";
119
- const [c, r] = h(() => e(o)), [u, d] = h(() => n(o));
120
- return t.appendChild(c.node), t.appendChild(u.node), i(r), i(d), { _tag: "div", node: t };
122
+ const [c, r] = g(() => e(o)), [d, u] = g(() => n(o));
123
+ return t.appendChild(c.node), t.appendChild(d.node), l(r), l(u), { _tag: "div", node: t };
121
124
  };
122
125
  }
123
- function X(...e) {
126
+ function ee(...e) {
124
127
  return (n) => {
125
128
  const o = document.createElement("div");
126
129
  o.dataset.stack = "";
127
130
  for (const t of e) {
128
- const [c, r] = h(() => t(n));
129
- o.appendChild(c.node), i(r);
131
+ const [c, r] = g(() => t(n));
132
+ o.appendChild(c.node), l(r);
130
133
  }
131
134
  return { _tag: "div", node: o };
132
135
  };
133
136
  }
134
- function Y(e, n, o) {
137
+ function te(e, n, o) {
135
138
  const t = document.createElement("template");
136
139
  return t.innerHTML = e, (c) => {
137
140
  const r = document.createElement("div");
138
141
  r.dataset.templ = "", r.appendChild(t.content.cloneNode(!0));
139
- const u = {};
140
- for (const d of Object.keys(n)) {
141
- const s = n[d], a = r.querySelector(`${s}[data-ref="${d}"]`);
142
+ const d = {};
143
+ for (const u of Object.keys(n)) {
144
+ const s = n[u], a = r.querySelector(`${s}[data-ref="${u}"]`);
142
145
  if (a === null)
143
146
  throw new Error(
144
- `templ: ref "${d}" not found — expected <${s} data-ref="${d}"> in template`
147
+ `templ: ref "${u}" not found — expected <${s} data-ref="${u}"> in template`
145
148
  );
146
- u[d] = { _tag: s, node: a };
149
+ d[u] = { _tag: s, node: a };
147
150
  }
148
- return o(c, u), { _tag: "div", node: r };
151
+ return o(c, d), { _tag: "div", node: r };
149
152
  };
150
153
  }
151
- function Z(e, n, o, t) {
154
+ function ne(e, n, o, t) {
152
155
  const c = (t == null ? void 0 : t.container) ?? "div", r = document.createElement(c);
153
156
  r.dataset.eachKeyed = "";
154
- const u = /* @__PURE__ */ new Map(), d = (a, l) => {
155
- const g = B(l);
156
- let m = !1, w = () => {
157
+ const d = /* @__PURE__ */ new Map(), u = (a, f) => {
158
+ const m = j(f);
159
+ let v = !1, C = () => {
157
160
  };
158
- "set" in e && (w = g.subscribe((b) => {
159
- if (m) return;
160
- const E = e.get(), x = E.findIndex((y) => n(y) === a);
161
- if (x !== -1 && !Object.is(E[x], b)) {
162
- const y = [...E];
163
- y[x] = b, e.set(y);
161
+ "set" in e && (C = m.subscribe((b) => {
162
+ if (v) return;
163
+ const x = e.get(), N = x.findIndex((k) => n(k) === a);
164
+ if (N !== -1 && !Object.is(x[N], b)) {
165
+ const k = [...x];
166
+ k[N] = b, e.set(k);
164
167
  }
165
168
  }));
166
- const [f, p] = h(() => o(g));
169
+ const [p, h] = g(() => o(m));
167
170
  return {
168
- itemSignal: g,
169
- childNode: f.node,
171
+ itemSignal: m,
172
+ childNode: p.node,
170
173
  cleanup: () => {
171
- p(), w();
174
+ h(), C();
172
175
  },
173
176
  setFromParent: (b) => {
174
- m = !0, g.set(b), m = !1;
177
+ v = !0, m.set(b), v = !1;
175
178
  }
176
179
  };
177
180
  }, s = (a) => {
178
- var w;
179
- const l = a.map(n), g = new Set(l);
180
- for (const [f, p] of u)
181
- g.has(f) || (p.cleanup(), (w = p.childNode.parentNode) == null || w.removeChild(p.childNode), u.delete(f));
182
- for (let f = 0; f < a.length; f++) {
183
- const p = l[f], b = a[f];
184
- u.has(p) ? u.get(p).setFromParent(b) : u.set(p, d(p, b));
181
+ var C;
182
+ const f = a.map(n), m = new Set(f);
183
+ for (const [p, h] of d)
184
+ m.has(p) || (h.cleanup(), (C = h.childNode.parentNode) == null || C.removeChild(h.childNode), d.delete(p));
185
+ for (let p = 0; p < a.length; p++) {
186
+ const h = f[p], b = a[p];
187
+ d.has(h) ? d.get(h).setFromParent(b) : d.set(h, u(h, b));
185
188
  }
186
- let m = null;
187
- for (let f = a.length - 1; f >= 0; f--) {
188
- const p = u.get(l[f]);
189
- (p.childNode.parentNode !== r || p.childNode.nextSibling !== m) && r.insertBefore(p.childNode, m), m = p.childNode;
189
+ let v = null;
190
+ for (let p = a.length - 1; p >= 0; p--) {
191
+ const h = d.get(f[p]);
192
+ (h.childNode.parentNode !== r || h.childNode.nextSibling !== v) && r.insertBefore(h.childNode, v), v = h.childNode;
190
193
  }
191
194
  };
192
- return s(e.get()), v(e, s), i(() => {
193
- for (const a of u.values()) a.cleanup();
195
+ return s(e.get()), w(e, s), l(() => {
196
+ for (const a of d.values()) a.cleanup();
194
197
  }), { _tag: c, node: r };
195
198
  }
196
- function _(e, n, o) {
199
+ function A(e, n, o) {
197
200
  const t = o;
198
- e.addEventListener(n, t), i(() => e.removeEventListener(n, t));
201
+ e.addEventListener(n, t), l(() => e.removeEventListener(n, t));
199
202
  }
200
- function A(e, n) {
203
+ function S(e, n) {
201
204
  e.value = n.get();
202
205
  const o = () => n.set(e.value);
203
206
  e.addEventListener("input", o);
@@ -206,163 +209,219 @@ function A(e, n) {
206
209
  }), c = () => {
207
210
  e.removeEventListener("input", o), t();
208
211
  };
209
- return i(c), c;
212
+ return l(c), c;
210
213
  }
211
- function P(e, n) {
212
- _(e, "change", () => n.set(e.value)), v(n, (o) => {
214
+ function T(e, n) {
215
+ A(e, "change", () => n.set(e.value)), w(n, (o) => {
213
216
  e.value !== o && (e.value = o);
214
217
  });
215
218
  }
216
- function j(e, n) {
217
- _(e, "change", () => n.set(e.checked)), v(n, (o) => {
219
+ function q(e, n) {
220
+ A(e, "change", () => n.set(e.checked)), w(n, (o) => {
218
221
  e.checked !== o && (e.checked = o);
219
222
  });
220
223
  }
221
- function ee(e, n) {
222
- n(e.get()), i(e.subscribe(n));
224
+ function oe(e, n) {
225
+ n(e.get()), l(e.subscribe(n));
223
226
  }
224
- function te(e, n) {
225
- e.textContent = n.get(), i(n.subscribe((o) => {
227
+ function ce(e, n) {
228
+ e.textContent = n.get(), l(n.subscribe((o) => {
226
229
  e.textContent = o;
227
230
  }));
228
231
  }
229
- function ne(e, n, o) {
230
- e.setAttribute(n, o.get()), i(o.subscribe((t) => {
232
+ function re(e, n, o) {
233
+ e.setAttribute(n, o.get()), l(o.subscribe((t) => {
231
234
  e.setAttribute(n, t);
232
235
  }));
233
236
  }
234
- function oe(e, n, o) {
235
- e.classList.toggle(n, o.get()), i(o.subscribe((t) => {
237
+ function de(e, n, o) {
238
+ e.classList.toggle(n, o.get()), l(o.subscribe((t) => {
236
239
  e.classList.toggle(n, t);
237
240
  }));
238
241
  }
239
- function ce(e, n) {
242
+ function ue(e, n) {
240
243
  n();
241
244
  const o = e.map((t) => t.subscribe(n));
242
245
  return () => {
243
246
  for (const t of o) t();
244
247
  };
245
248
  }
246
- function re(e, n) {
249
+ function ie(e, n) {
247
250
  return e.style.display = n.get() ? "" : "none", n.subscribe((o) => {
248
251
  e.style.display = o ? "" : "none";
249
252
  });
250
253
  }
251
- function ue(e, n) {
254
+ function ae(e, n) {
252
255
  return (o) => {
253
256
  const t = document.createElement("div");
254
257
  t.dataset.match = "";
255
258
  let c = null, r = null;
256
- const u = (d) => {
257
- const s = d[e];
259
+ const d = (u) => {
260
+ const s = u[e];
258
261
  if (s === r) return;
259
262
  c == null || c(), c = null, t.replaceChildren(), r = s;
260
263
  const a = n[s];
261
264
  if (a == null) return;
262
- const l = o.narrow(W(e, s));
263
- let g;
264
- [g, c] = h(
265
- () => a(l)
266
- ), t.appendChild(g.node);
265
+ const f = o.narrow($(e, s));
266
+ let m;
267
+ [m, c] = g(
268
+ () => a(f)
269
+ ), t.appendChild(m.node);
267
270
  };
268
- return v(o, u), u(o.get()), i(() => c == null ? void 0 : c()), { _tag: "div", node: t };
271
+ return w(o, d), d(o.get()), l(() => c == null ? void 0 : c()), { _tag: "div", node: t };
269
272
  };
270
273
  }
271
- function de(e, n) {
274
+ function se(e, n) {
272
275
  const o = document.createElement("div");
273
276
  o.dataset.foldWidget = "";
274
277
  let t = null;
275
278
  const c = (r) => {
276
279
  t !== null && (t(), t = null), o.replaceChildren();
277
- let u = null;
280
+ let d = null;
278
281
  switch (r.status) {
279
282
  case "notAsked":
280
- u = n.notAsked ?? null;
283
+ d = n.notAsked ?? null;
281
284
  break;
282
285
  case "loading":
283
- u = n.loading ?? null;
286
+ d = n.loading ?? null;
284
287
  break;
285
288
  case "failure":
286
- u = n.failure ? () => n.failure(r.error) : null;
289
+ d = n.failure ? () => n.failure(r.error) : null;
287
290
  break;
288
291
  case "success":
289
- u = n.success ? () => n.success(r.value) : null;
292
+ d = n.success ? () => n.success(r.value) : null;
290
293
  break;
291
294
  }
292
- if (u !== null) {
293
- let d;
294
- [d, t] = h(u), o.appendChild(d.node);
295
+ if (d !== null) {
296
+ let u;
297
+ [u, t] = g(d), o.appendChild(u.node);
295
298
  }
296
299
  };
297
- return c(e.get()), i(e.subscribe(c)), i(() => t == null ? void 0 : t()), { _tag: "div", node: o };
300
+ return c(e.get()), l(e.subscribe(c)), l(() => t == null ? void 0 : t()), { _tag: "div", node: o };
298
301
  }
299
- function ae(e) {
302
+ function le(e) {
300
303
  return (n) => {
301
- const o = n, t = N(e ?? {});
302
- return t.node.value = o.get(), A(t.node, o), t;
304
+ const o = n, t = _(e ?? {});
305
+ return t.node.value = o.get(), S(t.node, o), t;
303
306
  };
304
307
  }
305
- function se(e) {
308
+ function fe(e) {
306
309
  return (n) => {
307
- const o = n, t = I(e ?? {});
308
- return t.node.value = o.get(), A(t.node, o), t;
310
+ const o = n, t = O(e ?? {});
311
+ return t.node.value = o.get(), S(t.node, o), t;
309
312
  };
310
313
  }
311
- function ie(e) {
314
+ function pe(e) {
312
315
  return (n) => {
313
- const o = n, t = N({ ...e, type: "checkbox" });
314
- return t.node.checked = o.get(), j(t.node, o), t;
316
+ const o = n, t = _({ ...e, type: "checkbox" });
317
+ return t.node.checked = o.get(), q(t.node, o), t;
315
318
  };
316
319
  }
317
- function le(e) {
320
+ function he(e) {
318
321
  return (n) => {
319
- const o = n, t = N({ ...e, type: "number" });
320
- return t.node.value = String(o.get()), _(t.node, "input", () => {
322
+ const o = n, t = _({ ...e, type: "number" });
323
+ return t.node.value = String(o.get()), A(t.node, "input", () => {
321
324
  const c = t.node.valueAsNumber;
322
325
  isNaN(c) || o.set(c);
323
- }), v(n, (c) => {
326
+ }), w(n, (c) => {
324
327
  t.node.valueAsNumber !== c && (t.node.value = String(c));
325
328
  }), t;
326
329
  };
327
330
  }
328
- function fe(e, n) {
331
+ function ge(e, n) {
329
332
  return (o) => {
330
- const t = o, c = $(n ?? {}, ...e.map((r) => F({ value: r.value }, r.label)));
331
- return c.node.value = t.get(), P(c.node, t), c;
333
+ const t = o, c = F(n ?? {}, ...e.map((r) => I({ value: r.value }, r.label)));
334
+ return c.node.value = t.get(), T(c.node, t), c;
335
+ };
336
+ }
337
+ function i(e) {
338
+ return (n, ...o) => (t) => {
339
+ const c = document.createElement(e);
340
+ for (const [r, d] of Object.entries(n))
341
+ d == null || d === !1 || c.setAttribute(r, d === !0 ? "" : String(d));
342
+ for (const r of o)
343
+ typeof r == "function" ? c.appendChild(r(t).node) : typeof r == "string" ? c.appendChild(document.createTextNode(r)) : c.appendChild(r.node.cloneNode(!0));
344
+ return { _tag: e, node: c };
332
345
  };
333
346
  }
347
+ const me = {
348
+ // Sectioning / flow
349
+ div: i("div"),
350
+ section: i("section"),
351
+ article: i("article"),
352
+ header: i("header"),
353
+ footer: i("footer"),
354
+ main: i("main"),
355
+ nav: i("nav"),
356
+ // Headings
357
+ h1: i("h1"),
358
+ h2: i("h2"),
359
+ h3: i("h3"),
360
+ h4: i("h4"),
361
+ h5: i("h5"),
362
+ h6: i("h6"),
363
+ // Phrasing
364
+ p: i("p"),
365
+ span: i("span"),
366
+ a: i("a"),
367
+ em: i("em"),
368
+ strong: i("strong"),
369
+ code: i("code"),
370
+ pre: i("pre"),
371
+ // Lists
372
+ ul: i("ul"),
373
+ ol: i("ol"),
374
+ li: i("li"),
375
+ // Forms
376
+ button: i("button"),
377
+ label: i("label"),
378
+ form: i("form"),
379
+ fieldset: i("fieldset")
380
+ };
381
+ function be(e, n, o, t) {
382
+ const c = o(n.get());
383
+ if (c === void 0) {
384
+ e.remove();
385
+ return;
386
+ }
387
+ const r = c(t ?? n);
388
+ e.replaceWith(r.node);
389
+ }
334
390
  export {
335
- z as above,
336
- U as beside,
337
- ne as bindAttr,
338
- j as bindCheckbox,
339
- oe as bindClass,
340
- A as bindInput,
341
- P as bindSelect,
342
- re as bindShow,
343
- te as bindText,
344
- ie as checkboxWidget,
345
- Q as concat,
346
- D as dynamic,
347
- R as each,
348
- Z as eachKeyed,
349
- V as focus,
350
- de as foldWidget,
351
- ae as inputWidget,
352
- G as map,
353
- ue as match,
354
- T as mount,
355
- H as narrow,
356
- le as numberInputWidget,
357
- _ as on,
358
- O as register,
359
- fe as selectWidget,
360
- J as show,
361
- X as stack,
362
- v as subscribe,
363
- ee as subscribeNow,
364
- Y as template,
365
- se as textareaWidget,
366
- ce as watchAll,
367
- M as withScope
391
+ J as above,
392
+ G as beside,
393
+ re as bindAttr,
394
+ q as bindCheckbox,
395
+ de as bindClass,
396
+ S as bindInput,
397
+ T as bindSelect,
398
+ ie as bindShow,
399
+ ce as bindText,
400
+ pe as checkboxWidget,
401
+ Z as concat,
402
+ Q as dynamic,
403
+ D as each,
404
+ ne as eachKeyed,
405
+ P as focus,
406
+ se as foldWidget,
407
+ me as h,
408
+ le as inputWidget,
409
+ X as map,
410
+ ae as match,
411
+ R as mount,
412
+ z as narrow,
413
+ he as numberInputWidget,
414
+ A as on,
415
+ U as prop,
416
+ H as register,
417
+ ge as selectWidget,
418
+ Y as show,
419
+ be as slot,
420
+ ee as stack,
421
+ w as subscribe,
422
+ oe as subscribeNow,
423
+ te as template,
424
+ fe as textareaWidget,
425
+ ue as watchAll,
426
+ V as withScope
368
427
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhi-zone/rainbow-ui",
3
- "version": "0.2.0-alpha.3",
3
+ "version": "0.2.0-alpha.4",
4
4
  "description": "Type-safe DOM factories and algebraic widget combinators for rainbow",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",