elements-kit 0.18.2 → 0.20.0

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 (156) hide show
  1. package/README.md +14 -0
  2. package/dist/await.d.mts +53 -0
  3. package/dist/await.mjs +70 -0
  4. package/dist/custom-elements.d.mts +1 -1
  5. package/dist/{element-xQwq4ulc.mjs → element-D3om9yA6.mjs} +71 -4
  6. package/dist/for.d.mts +20 -26
  7. package/dist/for.mjs +29 -4
  8. package/dist/fragment-ROPRBJQd.mjs +61 -0
  9. package/dist/hydrate/index.d.mts +41 -0
  10. package/dist/hydrate/index.mjs +2 -0
  11. package/dist/hydrate-6Qx4n4Su.mjs +380 -0
  12. package/dist/integrations/astro-client.d.mts +17 -0
  13. package/dist/integrations/astro-client.mjs +23 -0
  14. package/dist/integrations/astro-server.d.mts +15 -0
  15. package/dist/integrations/astro-server.mjs +39 -0
  16. package/dist/integrations/astro-slots.d.mts +12 -0
  17. package/dist/integrations/astro-slots.mjs +30 -0
  18. package/dist/integrations/astro.d.mts +46 -0
  19. package/dist/integrations/astro.mjs +64 -0
  20. package/dist/integrations/react.d.mts +1 -1
  21. package/dist/integrations/react.mjs +2 -2
  22. package/dist/jsx-runtime/index.d.mts +1 -1
  23. package/dist/jsx-runtime/index.mjs +2 -20
  24. package/dist/{lib-Dkc7cV5F.mjs → lib-DYypKhxk.mjs} +63 -5
  25. package/dist/render.mjs +1 -1
  26. package/dist/{scope-CnEvL9Nd.mjs → scope-zbEG299F.mjs} +1 -1
  27. package/dist/server/index.d.mts +43 -0
  28. package/dist/server/index.mjs +2 -0
  29. package/dist/server-iFSng50i.mjs +385 -0
  30. package/dist/signals/index.d.mts +2 -2
  31. package/dist/signals/index.mjs +5 -3
  32. package/dist/{slot-B8y0aEoz.d.mts → slot-BFWXeFRl.d.mts} +6 -0
  33. package/dist/{slot-Cne__au7.mjs → slot-Dvf30O0B.mjs} +12 -1
  34. package/dist/slot.d.mts +1 -1
  35. package/dist/slot.mjs +1 -1
  36. package/dist/{infer-B7T5hi_D.d.mts → types-ncUK9rki.d.mts} +140 -141
  37. package/dist/ui/overlay/index.css +70 -0
  38. package/dist/ui/overlay/index.d.mts +209 -0
  39. package/dist/ui/overlay/index.mjs +1001 -0
  40. package/dist/ui/overlay/overlay.css +332 -0
  41. package/dist/utilities/_observe.mjs +1 -1
  42. package/dist/utilities/active-element.d.mts +1 -1
  43. package/dist/utilities/active-element.mjs +1 -1
  44. package/dist/utilities/async.d.mts +19 -2
  45. package/dist/utilities/async.mjs +49 -2
  46. package/dist/utilities/context.mjs +1 -1
  47. package/dist/utilities/debounced.d.mts +1 -1
  48. package/dist/utilities/debounced.mjs +1 -1
  49. package/dist/utilities/dom-lifecycle.bench.mjs +3255 -1
  50. package/dist/utilities/dom-lifecycle.mjs +1 -1
  51. package/dist/utilities/element-rect.d.mts +1 -1
  52. package/dist/utilities/element-rect.mjs +1 -1
  53. package/dist/utilities/element-scroll.d.mts +1 -1
  54. package/dist/utilities/event-driven.d.mts +1 -1
  55. package/dist/utilities/event-driven.mjs +1 -1
  56. package/dist/utilities/event-listener.d.mts +1 -1
  57. package/dist/utilities/event-listener.mjs +1 -1
  58. package/dist/utilities/focus-within.d.mts +1 -1
  59. package/dist/utilities/focus-within.mjs +1 -1
  60. package/dist/utilities/form-object.d.mts +96 -0
  61. package/dist/utilities/form-object.mjs +285 -0
  62. package/dist/utilities/hover.d.mts +1 -1
  63. package/dist/utilities/hover.mjs +1 -1
  64. package/dist/utilities/interval.d.mts +1 -1
  65. package/dist/utilities/interval.mjs +1 -1
  66. package/dist/utilities/location.d.mts +1 -1
  67. package/dist/utilities/location.mjs +1 -1
  68. package/dist/utilities/media-devices.d.mts +1 -1
  69. package/dist/utilities/media-devices.mjs +1 -1
  70. package/dist/utilities/media-player.d.mts +1 -1
  71. package/dist/utilities/media-query.d.mts +1 -1
  72. package/dist/utilities/media-query.mjs +1 -1
  73. package/dist/utilities/network.d.mts +1 -1
  74. package/dist/utilities/network.mjs +1 -1
  75. package/dist/utilities/orientation.d.mts +1 -1
  76. package/dist/utilities/orientation.mjs +1 -1
  77. package/dist/utilities/previous.d.mts +1 -1
  78. package/dist/utilities/previous.mjs +1 -1
  79. package/dist/utilities/promise.d.mts +19 -2
  80. package/dist/utilities/promise.mjs +33 -3
  81. package/dist/utilities/retry.mjs +1 -1
  82. package/dist/utilities/routing.d.mts +1 -1
  83. package/dist/utilities/routing.mjs +1 -1
  84. package/dist/utilities/search-params.d.mts +1 -1
  85. package/dist/utilities/storage.d.mts +1 -1
  86. package/dist/utilities/throttled.d.mts +1 -1
  87. package/dist/utilities/throttled.mjs +1 -1
  88. package/dist/utilities/timeout.d.mts +1 -1
  89. package/dist/utilities/timeout.mjs +1 -1
  90. package/dist/utilities/window-focus.d.mts +1 -1
  91. package/dist/utilities/window-focus.mjs +1 -1
  92. package/dist/utilities/window-size.d.mts +1 -1
  93. package/dist/utilities/window-size.mjs +1 -1
  94. package/package.json +20 -5
  95. package/dist/benchmark.CX_oY03V-CSLAXL5f.mjs +0 -5145
  96. package/dist/magic-string.es-CXefOmkB.mjs +0 -1011
  97. package/dist/test.BmQO5GaM-Ddz9cDxc.mjs +0 -8266
  98. package/dist/utilities/active-element.test.d.mts +0 -1
  99. package/dist/utilities/active-element.test.mjs +0 -25
  100. package/dist/utilities/async.test.d.mts +0 -1
  101. package/dist/utilities/async.test.mjs +0 -275
  102. package/dist/utilities/context.test.d.mts +0 -1
  103. package/dist/utilities/context.test.mjs +0 -171
  104. package/dist/utilities/debounced.test.d.mts +0 -1
  105. package/dist/utilities/debounced.test.mjs +0 -68
  106. package/dist/utilities/dom-lifecycle.test.d.mts +0 -1
  107. package/dist/utilities/dom-lifecycle.test.mjs +0 -228
  108. package/dist/utilities/element-rect.test.d.mts +0 -1
  109. package/dist/utilities/element-rect.test.mjs +0 -101
  110. package/dist/utilities/element-scroll.test.d.mts +0 -1
  111. package/dist/utilities/element-scroll.test.mjs +0 -27
  112. package/dist/utilities/event-listener.test.d.mts +0 -1
  113. package/dist/utilities/event-listener.test.mjs +0 -60
  114. package/dist/utilities/focus-within.test.d.mts +0 -1
  115. package/dist/utilities/focus-within.test.mjs +0 -51
  116. package/dist/utilities/hover.test.d.mts +0 -1
  117. package/dist/utilities/hover.test.mjs +0 -54
  118. package/dist/utilities/intersection-observer.test.d.mts +0 -1
  119. package/dist/utilities/intersection-observer.test.mjs +0 -46
  120. package/dist/utilities/interval.test.d.mts +0 -1
  121. package/dist/utilities/interval.test.mjs +0 -115
  122. package/dist/utilities/location.test.d.mts +0 -1
  123. package/dist/utilities/location.test.mjs +0 -61
  124. package/dist/utilities/long-press.test.d.mts +0 -1
  125. package/dist/utilities/long-press.test.mjs +0 -54
  126. package/dist/utilities/media-devices.test.d.mts +0 -1
  127. package/dist/utilities/media-devices.test.mjs +0 -44
  128. package/dist/utilities/media-player.test.d.mts +0 -1
  129. package/dist/utilities/media-player.test.mjs +0 -102
  130. package/dist/utilities/mutation-observer.test.d.mts +0 -1
  131. package/dist/utilities/mutation-observer.test.mjs +0 -48
  132. package/dist/utilities/network.test.d.mts +0 -1
  133. package/dist/utilities/network.test.mjs +0 -30
  134. package/dist/utilities/on-click-outside.test.d.mts +0 -1
  135. package/dist/utilities/on-click-outside.test.mjs +0 -45
  136. package/dist/utilities/previous.test.d.mts +0 -1
  137. package/dist/utilities/previous.test.mjs +0 -90
  138. package/dist/utilities/promise.test.d.mts +0 -1
  139. package/dist/utilities/promise.test.mjs +0 -158
  140. package/dist/utilities/retry.test.d.mts +0 -1
  141. package/dist/utilities/retry.test.mjs +0 -85
  142. package/dist/utilities/routing.test.d.mts +0 -1
  143. package/dist/utilities/routing.test.mjs +0 -129
  144. package/dist/utilities/search-params.test.d.mts +0 -1
  145. package/dist/utilities/search-params.test.mjs +0 -37
  146. package/dist/utilities/ssr.test.d.mts +0 -1
  147. package/dist/utilities/ssr.test.mjs +0 -65
  148. package/dist/utilities/storage.test.d.mts +0 -1
  149. package/dist/utilities/storage.test.mjs +0 -139
  150. package/dist/utilities/throttled.test.d.mts +0 -1
  151. package/dist/utilities/throttled.test.mjs +0 -58
  152. package/dist/utilities/timeout.test.d.mts +0 -1
  153. package/dist/utilities/timeout.test.mjs +0 -121
  154. package/dist/utilities/window-size.test.d.mts +0 -1
  155. package/dist/utilities/window-size.test.mjs +0 -43
  156. /package/dist/{custom-elements-D5CgfNKc.d.mts → custom-elements-DK5VUcWA.d.mts} +0 -0
@@ -0,0 +1,380 @@
1
+ import { C as untracked, _ as onCleanup, d as effectScope, n as CLAIM, t as ASYNC_REGION, u as effect, v as setDeferAsyncRuns } from "./lib-DYypKhxk.mjs";
2
+ import { isReactive, resolveProps } from "./signals/index.mjs";
3
+ import { isReactivePromiseLike } from "./utilities/promise.mjs";
4
+ import { flushDeferredAsyncRuns, isAsyncLike } from "./utilities/async.mjs";
5
+ import { i as applyProps, o as resolveChild, r as setRenderer, t as createElement } from "./element-D3om9yA6.mjs";
6
+ import { n as Slot } from "./slot-Dvf30O0B.mjs";
7
+ import { For, isForComponent } from "./for.mjs";
8
+ import { n as isFragmentComponent, r as parseHtml, t as Fragment } from "./fragment-ROPRBJQd.mjs";
9
+ //#region src/hydrate/claim.ts
10
+ let hydrationContext = null;
11
+ function setHydrationContext(ctx) {
12
+ const prev = hydrationContext;
13
+ hydrationContext = ctx;
14
+ return prev;
15
+ }
16
+ const VNODE = Symbol.for("elements-kit.vnode");
17
+ function isVNode(value) {
18
+ return typeof value === "object" && value !== null && VNODE in value;
19
+ }
20
+ const claimRenderer = { jsx(type, props) {
21
+ if (typeof type === "string") return {
22
+ [VNODE]: true,
23
+ kind: "el",
24
+ tag: type,
25
+ props
26
+ };
27
+ if (isFragmentComponent(type)) return {
28
+ [VNODE]: true,
29
+ kind: "frag",
30
+ children: props.children,
31
+ html: props.html === true
32
+ };
33
+ if (isForComponent(type)) return {
34
+ [VNODE]: true,
35
+ kind: "for",
36
+ props
37
+ };
38
+ if (typeof type === "function" && !type.prototype?.render) return type(resolveProps(props));
39
+ const name = typeof type === "function" ? type.name ?? "anonymous" : String(type);
40
+ throw new Error(`Hydration does not support class components ("${name}"); v1 supports intrinsic elements, function components, Fragment and For.`);
41
+ } };
42
+ function withClaimRenderer(fn) {
43
+ setRenderer(claimRenderer);
44
+ try {
45
+ return fn();
46
+ } finally {
47
+ setRenderer(null);
48
+ }
49
+ }
50
+ /** Claim `container`'s existing children against the evaluated tree. */
51
+ function claimChildren(container, root, onMismatch) {
52
+ walkList({
53
+ node: container.firstChild,
54
+ parent: container
55
+ }, root, onMismatch);
56
+ }
57
+ function walkList(cur, raw, om) {
58
+ if (raw == null || typeof raw === "boolean") return;
59
+ if (Array.isArray(raw)) {
60
+ for (const c of raw.flat(Infinity)) walkChild(cur, c, om);
61
+ return;
62
+ }
63
+ walkChild(cur, raw, om);
64
+ }
65
+ function walkChild(cur, c, om) {
66
+ if (c == null || typeof c === "boolean") return;
67
+ if (isVNode(c)) {
68
+ if (c.kind === "frag") {
69
+ if (c.html) return claimRawRegion(cur, c.children, om);
70
+ return walkList(cur, c.children, om);
71
+ }
72
+ if (c.kind === "for") return claimFor(cur, c, om);
73
+ return claimElement(cur, c, om);
74
+ }
75
+ if (isReactivePromiseLike(c) || isAsyncLike(c)) return claimAsync(cur, c, om);
76
+ if (typeof c === "function") return claimDynamic(cur, c, om);
77
+ if (c instanceof Node) return fallback(cur, om, c.nodeName, () => c);
78
+ claimText(cur, String(c), om);
79
+ }
80
+ function claimText(cur, text, om) {
81
+ if (text === "") return;
82
+ const node = cur.node;
83
+ if (node && node.nodeType === Node.TEXT_NODE) {
84
+ const data = node.data;
85
+ if (data === text) {
86
+ cur.node = node.nextSibling;
87
+ return;
88
+ }
89
+ if (data.startsWith(text)) {
90
+ node.splitText(text.length);
91
+ cur.node = node.nextSibling;
92
+ return;
93
+ }
94
+ }
95
+ fallback(cur, om, text, () => document.createTextNode(text));
96
+ }
97
+ function claimElement(cur, v, om) {
98
+ const node = cur.node;
99
+ if (!(node !== null && node.nodeType === Node.ELEMENT_NODE && node.localName.toLowerCase() === v.tag.toLowerCase())) {
100
+ fallback(cur, om, `<${v.tag}>`, () => buildVNode(v));
101
+ return;
102
+ }
103
+ const el = node;
104
+ const { ref, children, live } = splitProps(v.props);
105
+ if (live) applyProps(el, live);
106
+ claimChildren(el, children, om);
107
+ if (typeof ref === "function") ref(el);
108
+ cur.node = el.nextSibling;
109
+ }
110
+ /**
111
+ * Split claimed-element props: static values are already in the server HTML
112
+ * and are skipped; `on:` handlers, reactive values and `prop:` assignments
113
+ * still need to run — they route through the normal `applyProps` path.
114
+ */
115
+ function splitProps(props) {
116
+ let ref;
117
+ let children;
118
+ let live = null;
119
+ for (const [key, value] of Object.entries(props)) {
120
+ if (key === "children") {
121
+ children = value;
122
+ continue;
123
+ }
124
+ if (key === "ref") {
125
+ ref = value;
126
+ continue;
127
+ }
128
+ if (key === "innerHTML") throw new Error("innerHTML is not supported in hydration — there is no raw HTML sink.");
129
+ const colonIdx = key.indexOf(":");
130
+ const ns = colonIdx > 0 ? key.slice(0, colonIdx) : "";
131
+ if (ns === "on" || ns === "prop" || isReactive(value)) (live ??= {})[key] = value;
132
+ }
133
+ return {
134
+ ref,
135
+ children,
136
+ live
137
+ };
138
+ }
139
+ function claimDynamic(cur, getter, om) {
140
+ const region = getter[ASYNC_REGION];
141
+ const claimed = cur.node?.nodeType === Node.COMMENT_NODE && cur.node.data === "{";
142
+ if (region && hydrationContext) hydrationContext.counter += region.ids;
143
+ const slot = claimSlot(cur, om);
144
+ const keepWhilePending = Boolean(region) && claimed;
145
+ effect(() => {
146
+ const value = getter();
147
+ if (keepWhilePending && region.pending()) return;
148
+ slot.set(resolveChild(value));
149
+ });
150
+ onCleanup(() => slot.clear());
151
+ }
152
+ function claimAsync(cur, p, om) {
153
+ const ctx = hydrationContext;
154
+ if (ctx) {
155
+ const record = ctx.data?.[String(ctx.counter++)];
156
+ const claim = p[CLAIM];
157
+ claim?.(record);
158
+ }
159
+ const slot = claimSlot(cur, om);
160
+ effect(() => {
161
+ if (p.state === "pending") return;
162
+ slot.set(resolveChild(p.result));
163
+ });
164
+ onCleanup(() => slot.clear());
165
+ }
166
+ function claimSlot(cur, om) {
167
+ const range = claimMarkerRange(cur, "{", "}");
168
+ if (range) return Slot.claim(range.start, range.end);
169
+ om?.({
170
+ expected: "<!--{-->",
171
+ found: cur.node
172
+ });
173
+ const slot = new Slot();
174
+ cur.parent.insertBefore(slot.render(), cur.node);
175
+ return slot;
176
+ }
177
+ function claimMarkerRange(cur, open, close) {
178
+ const start = cur.node;
179
+ if (!start || start.nodeType !== Node.COMMENT_NODE || start.data !== open) return null;
180
+ let depth = 0;
181
+ let node = start;
182
+ while (node) {
183
+ if (node.nodeType === Node.COMMENT_NODE) {
184
+ const data = node.data;
185
+ if (data === open) depth++;
186
+ else if (data === close && --depth === 0) {
187
+ cur.node = node.nextSibling;
188
+ return {
189
+ start,
190
+ end: node
191
+ };
192
+ }
193
+ }
194
+ node = node.nextSibling;
195
+ }
196
+ return null;
197
+ }
198
+ /** `<Fragment html>` region: adopt the server markup between the markers. */
199
+ function claimRawRegion(cur, source, om) {
200
+ const claimed = cur.node?.nodeType === Node.COMMENT_NODE && cur.node.data === "{";
201
+ const slot = claimSlot(cur, om);
202
+ if (typeof source !== "function") {
203
+ if (!claimed && source != null) slot.set(parseHtml(String(source)));
204
+ return;
205
+ }
206
+ let first = claimed;
207
+ effect(() => {
208
+ const value = source();
209
+ if (first) {
210
+ first = false;
211
+ return;
212
+ }
213
+ slot.set(parseHtml(value == null ? "" : String(value)));
214
+ });
215
+ onCleanup(() => slot.clear());
216
+ }
217
+ function claimFor(cur, v, om) {
218
+ const inst = new For();
219
+ applyProps(inst, v.props);
220
+ const range = claimMarkerRange(cur, "<For>", "</For>");
221
+ if (!range) {
222
+ om?.({
223
+ expected: "<!--<For>-->",
224
+ found: cur.node
225
+ });
226
+ cur.parent.insertBefore(inst.render(), cur.node);
227
+ return;
228
+ }
229
+ const items = untracked(() => inst.each);
230
+ const entries = /* @__PURE__ */ new Map();
231
+ const order = [];
232
+ let node = range.start.nextSibling;
233
+ let index = 0;
234
+ while (node && node !== range.end && index < items.length) {
235
+ if (node.nodeType === Node.COMMENT_NODE && /^\[(?!\/)/.test(node.data)) {
236
+ const startC = node;
237
+ const keyStr = startC.data.slice(1, -1);
238
+ const endC = findEntryEnd(startC, range.end, keyStr);
239
+ if (!endC) break;
240
+ const item = items[index];
241
+ const key = inst.by(item, index);
242
+ if (encodeURIComponent(String(key)) !== keyStr) break;
243
+ let dispose;
244
+ untracked(() => {
245
+ dispose = effectScope(() => {
246
+ const rendered = withClaimRenderer(() => inst.children(item, index));
247
+ walkList({
248
+ node: startC.nextSibling,
249
+ parent: startC.parentNode
250
+ }, rendered, om);
251
+ });
252
+ });
253
+ entries.set(key, {
254
+ start: startC,
255
+ end: endC,
256
+ dispose
257
+ });
258
+ order.push(key);
259
+ index++;
260
+ node = endC.nextSibling;
261
+ continue;
262
+ }
263
+ node = node.nextSibling;
264
+ }
265
+ const keep = /* @__PURE__ */ new Set();
266
+ for (const entry of entries.values()) {
267
+ let kept = entry.start;
268
+ while (kept) {
269
+ keep.add(kept);
270
+ if (kept === entry.end) break;
271
+ kept = kept.nextSibling;
272
+ }
273
+ }
274
+ let stray = range.start.nextSibling;
275
+ while (stray && stray !== range.end) {
276
+ const next = stray.nextSibling;
277
+ if (!keep.has(stray)) stray.remove();
278
+ stray = next;
279
+ }
280
+ inst.hydrateRange(range.start, range.end, entries, order);
281
+ }
282
+ function findEntryEnd(start, boundary, key) {
283
+ let node = start.nextSibling;
284
+ while (node && node !== boundary) {
285
+ if (node.nodeType === Node.COMMENT_NODE && node.data === `[/${key}]`) return node;
286
+ node = node.nextSibling;
287
+ }
288
+ return null;
289
+ }
290
+ function fallback(cur, om, expected, build) {
291
+ om?.({
292
+ expected,
293
+ found: cur.node
294
+ });
295
+ const stale = cur.node;
296
+ const fresh = build();
297
+ cur.parent.insertBefore(fresh, stale);
298
+ if (stale) {
299
+ cur.node = stale.nextSibling;
300
+ cur.parent.removeChild(stale);
301
+ }
302
+ }
303
+ function buildVNode(v) {
304
+ if (v.kind === "el") {
305
+ const props = { ...v.props };
306
+ if ("children" in props) props.children = buildChildValue(props.children);
307
+ return createElement(v.tag, props);
308
+ }
309
+ if (v.kind === "frag") return Fragment({ children: (() => buildChildValue(v.children)) });
310
+ return createElement(For, v.props);
311
+ }
312
+ function buildChildValue(c) {
313
+ if (Array.isArray(c)) return c.map(buildChildValue);
314
+ if (isVNode(c)) return buildVNode(c);
315
+ return c;
316
+ }
317
+ //#endregion
318
+ //#region src/hydrate/index.ts
319
+ /**
320
+ * Make server-rendered HTML interactive by re-executing the component tree
321
+ * in claim mode: existing DOM nodes are adopted instead of rebuilt, `on:`
322
+ * handlers attach to the claimed nodes, and dynamic children bind live to
323
+ * the server-emitted slot markers.
324
+ *
325
+ * The component code runs once on the client (closures are recreated by
326
+ * re-execution — no serialized handlers). Async children keep their
327
+ * server-rendered content visible until the client-side value settles.
328
+ *
329
+ * Server/client trees must match; on mismatch the affected subtree is
330
+ * rendered fresh and `options.onMismatch` is invoked.
331
+ *
332
+ * @example
333
+ * ```tsx
334
+ * const { dispose } = hydrate(document.getElementById("app")!, () => <App />);
335
+ * ```
336
+ */
337
+ function hydrate(container, app, options = {}) {
338
+ const data = readHydrationData(container);
339
+ let dispose;
340
+ untracked(() => {
341
+ dispose = effectScope(() => {
342
+ setRenderer(claimRenderer);
343
+ const prevDefer = setDeferAsyncRuns(true);
344
+ let root;
345
+ try {
346
+ root = app();
347
+ } finally {
348
+ setRenderer(null);
349
+ setDeferAsyncRuns(prevDefer);
350
+ }
351
+ const prevCtx = setHydrationContext({
352
+ counter: 0,
353
+ data
354
+ });
355
+ try {
356
+ claimChildren(container, root, options.onMismatch);
357
+ } finally {
358
+ setHydrationContext(prevCtx);
359
+ flushDeferredAsyncRuns();
360
+ }
361
+ });
362
+ });
363
+ return { dispose };
364
+ }
365
+ /**
366
+ * Locate and parse the server's ek-data script. Malformed or absent data
367
+ * degrades to no seeding — async values settle through their own client
368
+ * execution instead.
369
+ */
370
+ function readHydrationData(container) {
371
+ const script = container.querySelector("script[type=\"application/json\"]#ek-data") ?? container.ownerDocument?.getElementById("ek-data");
372
+ if (!script?.textContent) return null;
373
+ try {
374
+ return JSON.parse(script.textContent);
375
+ } catch {
376
+ return null;
377
+ }
378
+ }
379
+ //#endregion
380
+ export { hydrate as t };
@@ -0,0 +1,17 @@
1
+ //#region src/integrations/astro-client.d.ts
2
+ /**
3
+ * Astro client entrypoint: hydrate an elements-kit island.
4
+ *
5
+ * Astro calls this as `hydrator(element)(Component, props, slots, { client })`
6
+ * once the island's client directive fires. `client:only` mounts fresh via
7
+ * `render`; every other directive adopts the server DOM via `hydrate` —
8
+ * handlers attach to existing nodes, nothing is rebuilt. The island's
9
+ * `astro:unmount` event tears everything down.
10
+ */
11
+ declare const _default: (element: HTMLElement) => (Component: unknown, props: Record<string, unknown>, slots: Record<string, string>, {
12
+ client
13
+ }: {
14
+ client: string;
15
+ }) => Promise<void>;
16
+ //#endregion
17
+ export { _default as default };
@@ -0,0 +1,23 @@
1
+ import { t as createElement } from "../element-D3om9yA6.mjs";
2
+ import { render } from "../render.mjs";
3
+ import { t as hydrate } from "../hydrate-6Qx4n4Su.mjs";
4
+ import { withSlotProps } from "./astro-slots.mjs";
5
+ //#region src/integrations/astro-client.ts
6
+ /**
7
+ * Astro client entrypoint: hydrate an elements-kit island.
8
+ *
9
+ * Astro calls this as `hydrator(element)(Component, props, slots, { client })`
10
+ * once the island's client directive fires. `client:only` mounts fresh via
11
+ * `render`; every other directive adopts the server DOM via `hydrate` —
12
+ * handlers attach to existing nodes, nothing is rebuilt. The island's
13
+ * `astro:unmount` event tears everything down.
14
+ */
15
+ var astro_client_default = (element) => async (Component, props, slots, { client }) => {
16
+ if (!element.hasAttribute("ssr")) return;
17
+ const merged = withSlotProps(props, slots);
18
+ const app = () => createElement(Component, merged);
19
+ const dispose = client === "only" ? render(element, app) : hydrate(element, app).dispose;
20
+ element.addEventListener("astro:unmount", () => dispose(), { once: true });
21
+ };
22
+ //#endregion
23
+ export { astro_client_default as default };
@@ -0,0 +1,15 @@
1
+ //#region src/integrations/astro-server.d.ts
2
+ type RendererFn<T> = (Component: unknown, props: Record<string, unknown> | null | undefined, slots: Record<string, string>, metadata?: {
3
+ astroStaticSlot?: boolean;
4
+ }) => Promise<T>;
5
+ interface ElementsKitSSRRenderer {
6
+ name: string;
7
+ check: RendererFn<boolean>;
8
+ renderToStaticMarkup: RendererFn<{
9
+ html: string;
10
+ }>;
11
+ supportsAstroStaticSlot: boolean;
12
+ }
13
+ declare const renderer: ElementsKitSSRRenderer;
14
+ //#endregion
15
+ export { renderer as default };
@@ -0,0 +1,39 @@
1
+ import { y as setInertEffects } from "../lib-DYypKhxk.mjs";
2
+ import { resolveProps } from "../signals/index.mjs";
3
+ import { r as setRenderer, t as createElement } from "../element-D3om9yA6.mjs";
4
+ import { withSlotProps } from "./astro-slots.mjs";
5
+ import { i as serverJsx, n as renderToString, r as SNode } from "../server-iFSng50i.mjs";
6
+ //#region src/integrations/astro-server.ts
7
+ /**
8
+ * Decide whether `Component` is an elements-kit component. Invoked by Astro
9
+ * for every candidate renderer, so this must reject foreign components: the
10
+ * component body runs under the server renderer, and only elements-kit JSX
11
+ * dispatches to it — the result is an `SNode`. A React component returns a
12
+ * React element object (never `SNode`); components that throw (hooks outside
13
+ * their framework, class components) are rejected by the catch.
14
+ */
15
+ const check = async (Component, props) => {
16
+ if (typeof Component !== "function") return false;
17
+ const prevInert = setInertEffects(true);
18
+ setRenderer({ jsx: serverJsx });
19
+ try {
20
+ return Component(resolveProps(props ?? {})) instanceof SNode;
21
+ } catch {
22
+ return false;
23
+ } finally {
24
+ setRenderer(null);
25
+ setInertEffects(prevInert);
26
+ }
27
+ };
28
+ const renderToStaticMarkup = async (Component, props, slots, metadata) => {
29
+ const merged = withSlotProps(props, slots, metadata?.astroStaticSlot === true);
30
+ return { html: await renderToString(() => createElement(Component, merged)) };
31
+ };
32
+ const renderer = {
33
+ name: "elements-kit",
34
+ check,
35
+ renderToStaticMarkup,
36
+ supportsAstroStaticSlot: true
37
+ };
38
+ //#endregion
39
+ export { renderer as default };
@@ -0,0 +1,12 @@
1
+ //#region src/integrations/astro-slots.d.ts
2
+ /**
3
+ * @internal Map Astro's pre-rendered slot HTML (`Record<name, html>`) into
4
+ * elements-kit props: the `default` slot becomes `children`, named slots
5
+ * become `slot:<name>` props. Each value is a thunk building Astro's slot
6
+ * wrapper element around a `<Fragment html>` region — deferred so the jsx
7
+ * dispatches to whichever renderer is active when the component reads the
8
+ * prop (string emission on the server, DOM on the client).
9
+ */
10
+ declare function withSlotProps(props: Record<string, unknown> | null | undefined, slots: Record<string, string> | null | undefined, staticSlot?: boolean): Record<string, unknown>;
11
+ //#endregion
12
+ export { withSlotProps };
@@ -0,0 +1,30 @@
1
+ import { t as createElement } from "../element-D3om9yA6.mjs";
2
+ import { t as Fragment } from "../fragment-ROPRBJQd.mjs";
3
+ //#region src/integrations/astro-slots.ts
4
+ /**
5
+ * @internal Map Astro's pre-rendered slot HTML (`Record<name, html>`) into
6
+ * elements-kit props: the `default` slot becomes `children`, named slots
7
+ * become `slot:<name>` props. Each value is a thunk building Astro's slot
8
+ * wrapper element around a `<Fragment html>` region — deferred so the jsx
9
+ * dispatches to whichever renderer is active when the component reads the
10
+ * prop (string emission on the server, DOM on the client).
11
+ */
12
+ function withSlotProps(props, slots, staticSlot = false) {
13
+ const base = { ...props ?? {} };
14
+ if (!slots) return base;
15
+ const tag = staticSlot ? "astro-static-slot" : "astro-slot";
16
+ for (const [name, html] of Object.entries(slots)) {
17
+ const slot = () => createElement(tag, {
18
+ ...name === "default" ? {} : { name },
19
+ children: createElement(Fragment, {
20
+ html: true,
21
+ children: html
22
+ })
23
+ });
24
+ if (name === "default") base.children = slot;
25
+ else base[`slot:${name}`] = slot;
26
+ }
27
+ return base;
28
+ }
29
+ //#endregion
30
+ export { withSlotProps };
@@ -0,0 +1,46 @@
1
+ //#region src/integrations/astro.d.ts
2
+ interface AstroRendererConfig {
3
+ name: string;
4
+ clientEntrypoint: string;
5
+ serverEntrypoint: string;
6
+ }
7
+ interface AstroConfigSetupApi {
8
+ addRenderer(renderer: AstroRendererConfig): void;
9
+ updateConfig(config: Record<string, unknown>): unknown;
10
+ }
11
+ interface ElementsKitAstroIntegration {
12
+ name: string;
13
+ hooks: {
14
+ "astro:config:setup": (api: AstroConfigSetupApi) => void;
15
+ };
16
+ }
17
+ /**
18
+ * Astro integration: use elements-kit components as Astro islands.
19
+ *
20
+ * Registers the elements-kit renderer pair — server rendering via
21
+ * `elements-kit/server`, client hydration via `elements-kit/hydrate` — and
22
+ * points Vite's JSX transform at `elements-kit`, so `.tsx` island components
23
+ * need no per-file pragma.
24
+ *
25
+ * ```tsx
26
+ * <Counter client:load /> // server-rendered, hydrated on load
27
+ * <Widget client:only="elements-kit" /> // client-rendered only
28
+ * ```
29
+ *
30
+ * Coexists with other framework renderers (React, etc.); scope their JSX
31
+ * transform with the framework integration's `include` option.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * // astro.config.mjs
36
+ * import { defineConfig } from "astro/config";
37
+ * import elementsKit from "elements-kit/integrations/astro";
38
+ *
39
+ * export default defineConfig({
40
+ * integrations: [elementsKit()],
41
+ * });
42
+ * ```
43
+ */
44
+ declare function elementsKit(): ElementsKitAstroIntegration;
45
+ //#endregion
46
+ export { ElementsKitAstroIntegration, elementsKit as default };
@@ -0,0 +1,64 @@
1
+ //#region src/integrations/astro.ts
2
+ /**
3
+ * Astro integration: use elements-kit components as Astro islands.
4
+ *
5
+ * Registers the elements-kit renderer pair — server rendering via
6
+ * `elements-kit/server`, client hydration via `elements-kit/hydrate` — and
7
+ * points Vite's JSX transform at `elements-kit`, so `.tsx` island components
8
+ * need no per-file pragma.
9
+ *
10
+ * ```tsx
11
+ * <Counter client:load /> // server-rendered, hydrated on load
12
+ * <Widget client:only="elements-kit" /> // client-rendered only
13
+ * ```
14
+ *
15
+ * Coexists with other framework renderers (React, etc.); scope their JSX
16
+ * transform with the framework integration's `include` option.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * // astro.config.mjs
21
+ * import { defineConfig } from "astro/config";
22
+ * import elementsKit from "elements-kit/integrations/astro";
23
+ *
24
+ * export default defineConfig({
25
+ * integrations: [elementsKit()],
26
+ * });
27
+ * ```
28
+ */
29
+ function elementsKit() {
30
+ return {
31
+ name: "elements-kit",
32
+ hooks: { "astro:config:setup": ({ addRenderer, updateConfig }) => {
33
+ addRenderer({
34
+ name: "elements-kit",
35
+ clientEntrypoint: "elements-kit/integrations/astro-client",
36
+ serverEntrypoint: "elements-kit/integrations/astro-server"
37
+ });
38
+ updateConfig({ vite: {
39
+ esbuild: {
40
+ jsx: "automatic",
41
+ jsxImportSource: "elements-kit"
42
+ },
43
+ optimizeDeps: { include: [
44
+ "elements-kit",
45
+ "elements-kit/jsx-runtime",
46
+ "elements-kit/jsx-dev-runtime",
47
+ "elements-kit/signals",
48
+ "elements-kit/for",
49
+ "elements-kit/slot",
50
+ "elements-kit/render",
51
+ "elements-kit/hydrate",
52
+ "elements-kit/await",
53
+ "elements-kit/custom-elements",
54
+ "elements-kit/attributes",
55
+ "elements-kit/integrations/astro-client",
56
+ "elements-kit/utilities/*"
57
+ ] },
58
+ resolve: { dedupe: ["elements-kit"] }
59
+ } });
60
+ } }
61
+ };
62
+ }
63
+ //#endregion
64
+ export { elementsKit as default };
@@ -1,4 +1,4 @@
1
- import { y as Computed } from "../infer-B7T5hi_D.mjs";
1
+ import { y as Computed } from "../types-ncUK9rki.mjs";
2
2
 
3
3
  //#region src/integrations/react.d.ts
4
4
  /**
@@ -1,6 +1,6 @@
1
- import { m as signal, s as effect } from "../lib-Dkc7cV5F.mjs";
1
+ import { u as effect, x as signal } from "../lib-DYypKhxk.mjs";
2
2
  import "../signals/index.mjs";
3
- import { t as scope } from "../scope-CnEvL9Nd.mjs";
3
+ import { t as scope } from "../scope-zbEG299F.mjs";
4
4
  import { useEffect, useMemo, useRef, useSyncExternalStore } from "react";
5
5
  //#region src/integrations/react.ts
6
6
  /**
@@ -1,2 +1,2 @@
1
- import { U as createElement, _ as SlotProps, a as RawProps, b as MaybeReactive, c as ResolveProps, d as ComponentClass, f as ComponentFn, g as JSX, h as Attrs, i as Props, l as Child, m as PropsTarget, n as ElementProps, o as ReactiveProps, p as ComponentInstance, r as MaybeReactiveProps, s as Require, t as ComponentProps, u as Component, v as Fragment } from "../infer-B7T5hi_D.mjs";
1
+ import { G as createElement, _ as Require, a as ComponentInstance, b as MaybeReactive, c as JSX, d as ComponentProps, f as ElementProps, g as ReactiveProps, h as RawProps, i as ComponentFn, l as SlotProps, m as Props, n as Component, o as PropsTarget, p as MaybeReactiveProps, r as ComponentClass, s as Attrs, t as Child, u as Fragment, v as ResolveProps } from "../types-ncUK9rki.mjs";
2
2
  export { Attrs, type Child, type Component, type ComponentClass, type ComponentFn, type ComponentInstance, type ComponentProps, type ElementProps, Fragment, JSX, type MaybeReactive, type MaybeReactiveProps, type Props, type PropsTarget, type RawProps, type ReactiveProps, type Require, type ResolveProps, SlotProps, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };
@@ -1,21 +1,3 @@
1
- import { r as mountChild, t as createElement } from "../element-xQwq4ulc.mjs";
2
- //#region src/jsx-runtime/fragment.ts
3
- /**
4
- * Used by the JSX transform for `<>...</>` fragments.
5
- *
6
- * Each child is routed through `mountChild`, which handles Nodes, strings,
7
- * numbers, arrays, and reactive getters — matching the behavior of any other
8
- * JSX container. `mountChild` also wires each child's cleanup via its own
9
- * `effectScope`, which links to the enclosing `effectScope` created by
10
- * `createElement(Fragment, ...)` for disposal propagation.
11
- */
12
- function Fragment(props) {
13
- const fragment = document.createDocumentFragment();
14
- const raw = props.children?.();
15
- if (raw == null) return fragment;
16
- const nodes = Array.isArray(raw) ? raw.flat(Infinity) : [raw];
17
- for (const child of nodes) mountChild(fragment, child);
18
- return fragment;
19
- }
20
- //#endregion
1
+ import { t as createElement } from "../element-D3om9yA6.mjs";
2
+ import { t as Fragment } from "../fragment-ROPRBJQd.mjs";
21
3
  export { Fragment, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };