elements-kit 0.0.15 → 0.0.17

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 (112) hide show
  1. package/README.md +138 -31
  2. package/dist/attributes-Dtn68R1u.d.mts +94 -0
  3. package/dist/attributes.d.mts +1 -93
  4. package/dist/custom-elements.d.mts +74 -0
  5. package/dist/custom-elements.mjs +100 -0
  6. package/dist/define-CjbTZ3VG.d.mts +23 -0
  7. package/dist/{element-ChF24-2z.mjs → element-CGVy_8TW.mjs} +11 -12
  8. package/dist/for.d.mts +45 -0
  9. package/dist/for.mjs +136 -0
  10. package/dist/{index-DUshSQ_6.d.mts → index-DydGTqZU.d.mts} +60 -10
  11. package/dist/index.d.mts +1 -36
  12. package/dist/index.mjs +1 -144
  13. package/dist/infer-BfzRJoCn.d.mts +203 -0
  14. package/dist/integrations/react.d.mts +1 -1
  15. package/dist/integrations/react.mjs +1 -1
  16. package/dist/jsx-runtime/index.d.mts +11 -20
  17. package/dist/jsx-runtime/index.mjs +2 -2
  18. package/dist/signals/index.d.mts +2 -2
  19. package/dist/signals/index.mjs +2 -2
  20. package/dist/{signals-BHmWX6ox.mjs → signals-J8dK_rA4.mjs} +57 -17
  21. package/dist/slot-C7GQZe-r.d.mts +104 -0
  22. package/dist/{slot-Cydy7-0L.mjs → slot-Kb61AcgW.mjs} +21 -2
  23. package/dist/slot.d.mts +2 -84
  24. package/dist/slot.mjs +2 -2
  25. package/dist/{test.BmQO5GaM-ANkhHvbr.mjs → test.BmQO5GaM-DfGStnii.mjs} +1 -1
  26. package/dist/utilities/_observe.d.mts +11 -0
  27. package/dist/utilities/_observe.mjs +15 -0
  28. package/dist/utilities/active-element.d.mts +1 -1
  29. package/dist/utilities/active-element.mjs +6 -2
  30. package/dist/utilities/active-element.test.mjs +1 -1
  31. package/dist/utilities/async.d.mts +1 -1
  32. package/dist/utilities/async.mjs +1 -1
  33. package/dist/utilities/async.test.mjs +2 -2
  34. package/dist/utilities/debounced.d.mts +1 -1
  35. package/dist/utilities/debounced.mjs +1 -1
  36. package/dist/utilities/debounced.test.mjs +2 -2
  37. package/dist/utilities/element-rect.d.mts +1 -1
  38. package/dist/utilities/element-rect.mjs +1 -1
  39. package/dist/utilities/element-rect.test.mjs +2 -2
  40. package/dist/utilities/element-scroll.d.mts +1 -1
  41. package/dist/utilities/element-scroll.mjs +7 -34
  42. package/dist/utilities/element-scroll.test.mjs +2 -2
  43. package/dist/utilities/environment.d.mts +5 -0
  44. package/dist/utilities/environment.mjs +5 -0
  45. package/dist/utilities/event-driven.d.mts +1 -1
  46. package/dist/utilities/event-driven.mjs +2 -2
  47. package/dist/utilities/event-listener.d.mts +1 -1
  48. package/dist/utilities/event-listener.mjs +1 -1
  49. package/dist/utilities/event-listener.test.mjs +2 -2
  50. package/dist/utilities/focus-within.d.mts +1 -1
  51. package/dist/utilities/focus-within.mjs +1 -1
  52. package/dist/utilities/focus-within.test.mjs +2 -2
  53. package/dist/utilities/hover.d.mts +1 -1
  54. package/dist/utilities/hover.mjs +1 -1
  55. package/dist/utilities/hover.test.mjs +2 -2
  56. package/dist/utilities/intersection-observer.mjs +4 -6
  57. package/dist/utilities/intersection-observer.test.mjs +2 -2
  58. package/dist/utilities/interval.d.mts +1 -1
  59. package/dist/utilities/interval.mjs +1 -1
  60. package/dist/utilities/interval.test.mjs +2 -2
  61. package/dist/utilities/location.d.mts +2 -14
  62. package/dist/utilities/location.mjs +12 -3
  63. package/dist/utilities/location.test.mjs +5 -5
  64. package/dist/utilities/long-press.mjs +1 -1
  65. package/dist/utilities/long-press.test.mjs +2 -2
  66. package/dist/utilities/media-devices.d.mts +1 -1
  67. package/dist/utilities/media-devices.mjs +1 -1
  68. package/dist/utilities/media-devices.test.mjs +2 -2
  69. package/dist/utilities/media-player.d.mts +1 -1
  70. package/dist/utilities/media-player.test.mjs +2 -2
  71. package/dist/utilities/media-query.d.mts +2 -3
  72. package/dist/utilities/media-query.mjs +3 -3
  73. package/dist/utilities/mutation-observer.mjs +4 -7
  74. package/dist/utilities/mutation-observer.test.mjs +2 -2
  75. package/dist/utilities/network.d.mts +2 -2
  76. package/dist/utilities/network.mjs +5 -3
  77. package/dist/utilities/network.test.mjs +1 -1
  78. package/dist/utilities/on-click-outside.test.mjs +2 -2
  79. package/dist/utilities/orientation.d.mts +1 -1
  80. package/dist/utilities/orientation.mjs +9 -1
  81. package/dist/utilities/previous.d.mts +1 -1
  82. package/dist/utilities/previous.mjs +1 -1
  83. package/dist/utilities/previous.test.mjs +2 -2
  84. package/dist/utilities/promise.d.mts +1 -1
  85. package/dist/utilities/promise.mjs +1 -1
  86. package/dist/utilities/promise.test.mjs +2 -2
  87. package/dist/utilities/resize-observer.mjs +4 -6
  88. package/dist/utilities/retry.mjs +1 -1
  89. package/dist/utilities/retry.test.mjs +2 -2
  90. package/dist/utilities/routing.d.mts +1 -1
  91. package/dist/utilities/routing.mjs +1 -1
  92. package/dist/utilities/routing.test.mjs +1 -1
  93. package/dist/utilities/search-params.d.mts +1 -1
  94. package/dist/utilities/search-params.test.mjs +2 -2
  95. package/dist/utilities/ssr.test.d.mts +1 -0
  96. package/dist/utilities/ssr.test.mjs +64 -0
  97. package/dist/utilities/storage.d.mts +1 -1
  98. package/dist/utilities/storage.test.mjs +2 -2
  99. package/dist/utilities/throttled.d.mts +1 -1
  100. package/dist/utilities/throttled.mjs +1 -1
  101. package/dist/utilities/throttled.test.mjs +2 -2
  102. package/dist/utilities/timeout.d.mts +1 -1
  103. package/dist/utilities/timeout.mjs +1 -1
  104. package/dist/utilities/timeout.test.mjs +2 -2
  105. package/dist/utilities/window-focus.d.mts +2 -2
  106. package/dist/utilities/window-focus.mjs +5 -3
  107. package/dist/utilities/window-size.d.mts +1 -1
  108. package/dist/utilities/window-size.mjs +10 -5
  109. package/dist/utilities/window-size.test.mjs +1 -1
  110. package/package.json +20 -10
  111. package/dist/lib-JA05lzCN.d.mts +0 -4
  112. /package/dist/{polyfill-DR5XVnh_.d.mts → polyfill-BVNd6ogU.d.mts} +0 -0
@@ -1,19 +1,8 @@
1
- import { t as PrimitiveNodeType } from "../lib-JA05lzCN.mjs";
1
+ import { t as CustomElementRegistry } from "../define-CjbTZ3VG.mjs";
2
+ import { a as Props, c as ComponentClass, i as MaybeReactiveProps, l as ComponentFn, n as ComponentProps, o as Require, r as ElementProps, s as Child, t as AnyElementCtor } from "../infer-BfzRJoCn.mjs";
3
+ import { n as MaybeReactive } from "../index-DydGTqZU.mjs";
2
4
  import { JSX as JSX$1 } from "dom-expressions/src/jsx-h";
3
5
 
4
- //#region src/jsx-runtime/types.d.ts
5
- /** An instance created by a component class — must expose `render()`. */
6
- interface ComponentInstance {
7
- render(): Element | DocumentFragment | null;
8
- }
9
- /** A class whose constructor returns a ComponentInstance. */
10
- type ComponentClass = new (...args: any[]) => ComponentInstance;
11
- type ComponentFn = (props: Record<string | symbol, unknown>) => null | Element | DocumentFragment;
12
- /** Anything that can appear as a JSX child. */
13
- type Child = PrimitiveNodeType | AnyFn | Child[];
14
- /** A function that renders props into an element or fragment. */
15
- type AnyFn = (...args: any[]) => any;
16
- //#endregion
17
6
  //#region src/jsx-runtime/element.d.ts
18
7
  declare function createElement(type: string | Element | DocumentFragment | ComponentClass | ComponentFn, {
19
8
  ref,
@@ -69,14 +58,16 @@ type OurProps = {
69
58
  };
70
59
  type WithOurProps<T> = T & OurProps;
71
60
  declare namespace JSX {
72
- type Element = globalThis.Element | globalThis.DocumentFragment | null;
73
- type ElementType = Child | ComponentClass;
74
- interface ElementChildrenAttribute {
61
+ export type Element = globalThis.Element | globalThis.DocumentFragment | null;
62
+ export type ElementType = Child | ComponentClass;
63
+ export interface ElementChildrenAttribute {
75
64
  children: {};
76
65
  }
77
- type IntrinsicElements = { [K in keyof JSX$1.IntrinsicElements]: WithOurProps<JSX$1.IntrinsicElements[K]> } & {
78
- /** Custom elements (`x-foo`, `my-component`, …) get a loose typed fallback. */[customElement: `${string}-${string}`]: WithOurProps<JSX$1.DOMAttributes<HTMLElement>> & Record<string, unknown>;
66
+ type RegisteredElements = { [K in keyof CustomElementRegistry]: CustomElementRegistry[K] extends AnyElementCtor ? ElementProps<CustomElementRegistry[K]> : never };
67
+ export type IntrinsicElements = { [K in keyof JSX$1.IntrinsicElements]: WithOurProps<JSX$1.IntrinsicElements[K]> } & RegisteredElements & {
68
+ /** Unregistered custom elements (`x-foo`, `my-component`, …) — loose fallback. */[customElement: `${string}-${string}`]: WithOurProps<JSX$1.DOMAttributes<HTMLElement>> & Record<string, unknown>;
79
69
  };
70
+ export {};
80
71
  }
81
72
  //#endregion
82
- export { Attrs, Fragment, FunctionMaybe, JSX, SlotProps, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };
73
+ export { Attrs, type ComponentProps, type ElementProps, Fragment, FunctionMaybe, JSX, type MaybeReactive, type MaybeReactiveProps, type Props, type Require, SlotProps, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };
@@ -1,5 +1,5 @@
1
- import { t as createElement } from "../element-ChF24-2z.mjs";
2
- import { g as onCleanup } from "../signals-BHmWX6ox.mjs";
1
+ import { t as createElement } from "../element-CGVy_8TW.mjs";
2
+ import { _ as onCleanup } from "../signals-J8dK_rA4.mjs";
3
3
  //#region src/jsx-runtime/fragment.ts
4
4
  /**
5
5
  * Used by the JSX transform for `<>...</>` fragments.
@@ -1,2 +1,2 @@
1
- import { C as untracked, S as trigger, _ as isEffect, a as isReactive, b as onCleanup, c as $computed, d as $signal, f as batch, g as isComputed, h as effectScope, i as Updater, l as $effect, m as effect, n as MaybeReactive, o as reactive, p as computed, r as Signal, s as resolve, t as Computed, u as $effectScope, v as isEffectScope, x as signal, y as isSignal } from "../index-DUshSQ_6.mjs";
2
- export { $computed, $effect, $effectScope, $signal, Computed, MaybeReactive, Signal, Updater, batch, computed, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve, signal, trigger, untracked };
1
+ import { C as trigger, S as signal, _ as isComputed, a as isReactive, b as isSignal, c as resolveProps, d as EFFECT_SCOPE, f as SIGNAL, g as effectScope, h as effect, i as Updater, l as COMPUTED, m as computed, n as MaybeReactive, o as reactive, p as batch, r as Signal, s as resolve, t as Computed, u as EFFECT, v as isEffect, w as untracked, x as onCleanup, y as isEffectScope } from "../index-DydGTqZU.mjs";
2
+ export { COMPUTED, Computed, EFFECT, EFFECT_SCOPE, MaybeReactive, SIGNAL, Signal, Updater, batch, computed, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve, resolveProps, signal, trigger, untracked };
@@ -1,2 +1,2 @@
1
- import { _ as signal, a as $effect, c as batch, d as effectScope, f as isComputed, g as onCleanup, h as isSignal, i as $computed, l as computed, m as isEffectScope, n as reactive, o as $effectScope, p as isEffect, r as resolve, s as $signal, t as isReactive, u as effect, v as trigger, y as untracked } from "../signals-BHmWX6ox.mjs";
2
- export { $computed, $effect, $effectScope, $signal, batch, computed, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve, signal, trigger, untracked };
1
+ import { _ as onCleanup, a as COMPUTED, b as untracked, c as SIGNAL, d as effect, f as effectScope, g as isSignal, h as isEffectScope, i as resolveProps, l as batch, m as isEffect, n as reactive, o as EFFECT, p as isComputed, r as resolve, s as EFFECT_SCOPE, t as isReactive, u as computed, v as signal, y as trigger } from "../signals-J8dK_rA4.mjs";
2
+ export { COMPUTED, EFFECT, EFFECT_SCOPE, SIGNAL, batch, computed, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve, resolveProps, signal, trigger, untracked };
@@ -275,10 +275,10 @@ let activeSub;
275
275
  let activeOwner;
276
276
  /** Ring-buffer of effects waiting to be flushed. */
277
277
  const queued = [];
278
- const $signal = Symbol("signal");
279
- const $computed = Symbol("computed");
280
- const $effect = Symbol("effect");
281
- const $effectScope = Symbol("effectScope");
278
+ const SIGNAL = Symbol("signal");
279
+ const COMPUTED = Symbol("computed");
280
+ const EFFECT = Symbol("effect");
281
+ const EFFECT_SCOPE = Symbol("effectScope");
282
282
  const { link, unlink, propagate, checkDirty, shallowPropagate } = createReactiveSystem({
283
283
  update(node) {
284
284
  if (node.depsTail !== void 0) return updateComputed(node);
@@ -353,26 +353,26 @@ function endBatch() {
353
353
  /**
354
354
  * Returns `true` if `fn` is a signal handle created by {@link signal}.
355
355
  *
356
- * Relies on `$signal` matching the internal `signalOper` function name.
356
+ * Relies on the SIGNAL symbol.
357
357
  */
358
358
  function isSignal(fn) {
359
- return fn != null && fn[$signal] === true;
359
+ return fn != null && fn[SIGNAL] === true;
360
360
  }
361
361
  /**
362
362
  * Returns `true` if `fn` is a computed handle created by {@link computed}.
363
363
  *
364
- * Relies on `$computed` matching the internal `computedOper` function name.
364
+ * Relies on the COMPUTED symbol.
365
365
  */
366
366
  function isComputed(fn) {
367
- return fn != null && fn[$computed] === true;
367
+ return fn != null && fn[COMPUTED] === true;
368
368
  }
369
369
  /**
370
370
  * Returns `true` if `fn` is an effect cleanup handle created by {@link effect}.
371
371
  *
372
- * Relies on the $effect symbol branding.
372
+ * Relies on the EFFECT symbol.
373
373
  */
374
374
  function isEffect(fn) {
375
- return fn != null && fn[$effect] === true;
375
+ return fn != null && fn[EFFECT] === true;
376
376
  }
377
377
  /**
378
378
  * Returns `true` if `fn` is an effectScope cleanup handle created by
@@ -391,7 +391,7 @@ function signal(initialValue) {
391
391
  subsTail: void 0,
392
392
  flags: 1
393
393
  });
394
- Object.defineProperty(handle, $signal, { value: true });
394
+ Object.defineProperty(handle, SIGNAL, { value: true });
395
395
  return handle;
396
396
  }
397
397
  /**
@@ -427,7 +427,7 @@ function computed(getter) {
427
427
  flags: 0,
428
428
  getter
429
429
  });
430
- Object.defineProperty(handle, $computed, { value: true });
430
+ Object.defineProperty(handle, COMPUTED, { value: true });
431
431
  return handle;
432
432
  }
433
433
  /**
@@ -481,7 +481,7 @@ function effect(fn) {
481
481
  e.flags &= -5;
482
482
  }
483
483
  const handle = effectOper.bind(e);
484
- Object.defineProperty(handle, $effect, { value: true });
484
+ Object.defineProperty(handle, EFFECT, { value: true });
485
485
  return handle;
486
486
  }
487
487
  /**
@@ -527,7 +527,7 @@ function effectScope(fn) {
527
527
  activeOwner = prevOwner;
528
528
  }
529
529
  const handle = effectScopeOper.bind(e);
530
- Object.defineProperty(handle, $effectScope, { value: true });
530
+ Object.defineProperty(handle, EFFECT_SCOPE, { value: true });
531
531
  return handle;
532
532
  }
533
533
  /**
@@ -964,11 +964,51 @@ function reactive(source) {
964
964
  };
965
965
  }
966
966
  /**
967
- * Resolves a MaybeReactive<T> to its current value.
968
- * If the input is a function, calls it; otherwise returns as-is.
967
+ * Resolve a {@link MaybeReactive} to its current value. Calls the getter
968
+ * when reactive; returns the value as-is when static.
969
+ *
970
+ * @example
971
+ * ```ts
972
+ * resolve(5); // 5
973
+ * resolve(() => count()); // current count value
974
+ * ```
969
975
  */
970
976
  function resolve(value) {
971
977
  return isReactive(value) ? value() : value;
972
978
  }
979
+ /**
980
+ * Turn a reactive-props object into a bag of per-key getters. Callers may
981
+ * pass values or reactive sources (`signal`, `computed`); reading
982
+ * `props.name()` inside an effect or JSX getter subscribes to whatever
983
+ * drives it. Static values become stable thunks, signals and computed pass
984
+ * through unchanged — so identity is preserved (`props.name === props.name`).
985
+ *
986
+ * @example
987
+ * ```tsx
988
+ * import { resolveProps } from "elements-kit/signals";
989
+ *
990
+ * function Greeting(raw: MaybeReactiveProps<{ name: string; excited?: boolean }>) {
991
+ * const props = resolveProps(raw);
992
+ * return (
993
+ * <p>
994
+ * Hello, {props.name}
995
+ * {() => (props.excited() ? "!" : ".")}
996
+ * </p>
997
+ * );
998
+ * }
999
+ * ```
1000
+ */
1001
+ function resolveProps(raw) {
1002
+ const cache = /* @__PURE__ */ new Map();
1003
+ return new Proxy(raw, { get(target, key) {
1004
+ let getter = cache.get(key);
1005
+ if (!getter) {
1006
+ const v = target[key];
1007
+ getter = isReactive(v) ? v : () => v;
1008
+ cache.set(key, getter);
1009
+ }
1010
+ return getter;
1011
+ } });
1012
+ }
973
1013
  //#endregion
974
- export { signal as _, $effect as a, batch as c, effectScope as d, isComputed as f, onCleanup as g, isSignal as h, $computed as i, computed as l, isEffectScope as m, reactive as n, $effectScope as o, isEffect as p, resolve as r, $signal as s, isReactive as t, effect as u, trigger as v, untracked as y };
1014
+ export { onCleanup as _, COMPUTED as a, untracked as b, SIGNAL as c, effect as d, effectScope as f, isSignal as g, isEffectScope as h, resolveProps as i, batch as l, isEffect as m, reactive as n, EFFECT as o, isComputed as p, resolve as r, EFFECT_SCOPE as s, isReactive as t, computed as u, signal as v, trigger as y };
@@ -0,0 +1,104 @@
1
+ //#region src/lib.d.ts
2
+ type PrimitiveNodeType = Node | string | boolean | number | bigint | symbol | Date | RegExp | null | undefined;
3
+ //#endregion
4
+ //#region src/slot.d.ts
5
+ /**
6
+ * A lightweight slot that reserves a region in the DOM using comment markers.
7
+ * Content between the markers can be replaced dynamically without wrapper elements.
8
+ */
9
+ declare class Slot {
10
+ #private;
11
+ private readonly start;
12
+ private readonly end;
13
+ /**
14
+ * Render the slot as a DocumentFragment.
15
+ * If not yet mounted, inserts the comment markers and optional default content.
16
+ * If already mounted, extracts and returns the current content WITHOUT disposing
17
+ * it — the caller takes ownership of the returned nodes and is responsible for
18
+ * their disposal.
19
+ */
20
+ slot(defaultContent?: PrimitiveNodeType): DocumentFragment;
21
+ /** Dispose reactive children and remove all content between the markers. */
22
+ clear(): void;
23
+ /**
24
+ * Replace the slot's content with the given element.
25
+ * No-op if the slot is not mounted or the content is identical.
26
+ */
27
+ set(element: Node): void;
28
+ /**
29
+ * Extract and return the current slot content as a DocumentFragment.
30
+ * Returns `null` if the slot is not mounted.
31
+ * Content is NOT disposed — the caller takes ownership and is responsible
32
+ * for disposal.
33
+ */
34
+ get(): DocumentFragment | null;
35
+ /** Returns the parent node if the slot is mounted, otherwise `null`. */
36
+ parent(): ParentNode | null;
37
+ /** Whether the slot's comment markers are attached to the DOM. */
38
+ isMounted(): boolean;
39
+ private isSame;
40
+ /**
41
+ * Create a callable slot instance.
42
+ *
43
+ * The returned value is both a function and an object:
44
+ * - Call it to render the slot with optional default content.
45
+ * - Access `.set()`, `.parent()`, `.isMounted()` for slot management.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const slot = createSlot();
50
+ * el.append(slot("default text")); // mount with default
51
+ * slot.set(newElement); // replace content
52
+ * ```
53
+ */
54
+ static new(): Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment);
55
+ }
56
+ type SlotInstance = ReturnType<typeof Slot.new>;
57
+ /** A callable slot — invoke to render, or access `.set()` / `.isMounted()` / `.parent()` for management. */
58
+ /**
59
+ * Symbol key for attaching a `Slots` instance to a custom element instance.
60
+ * This prevent collisions with Element properties and are not meant to be treated as JSX children.
61
+ */
62
+ declare const SLOTS: unique symbol;
63
+ declare const $map: unique symbol;
64
+ declare const $keys: unique symbol;
65
+ declare const $has: unique symbol;
66
+ /**
67
+ * A keyed collection of slot instances.
68
+ * Slots are pre-created from the provided keys and lazily created on first access for unknown keys.
69
+ */
70
+ declare class Slots<K extends string> implements Iterable<[K, SlotInstance]> {
71
+ readonly [$map]: Map<K, Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment)>;
72
+ private constructor();
73
+ [Symbol.iterator](): MapIterator<[K, Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment)]>;
74
+ [Symbol.toStringTag](): string;
75
+ [Symbol.hasInstance](instance: unknown): instance is Slots<any>;
76
+ [$has](key: K): boolean;
77
+ /** Check whether a slot with the given key exists. */
78
+ static has<K extends string>(slots: Slots<K>, key: K): boolean;
79
+ [$keys](): MapIterator<K>;
80
+ /** Iterate over all registered slot keys. */
81
+ static keys<K extends string>(slots: Slots<K>): MapIterator<K>;
82
+ /**
83
+ * Create a typed `Slots` collection from a list of key names.
84
+ *
85
+ * Pass the keys with `as const` so TS narrows them to a literal union —
86
+ * this is what lets `ElementProps<typeof Cls>` synthesize `slot:${K}`
87
+ * entries. Without `as const`, the array type widens to `string[]` and
88
+ * the slot keys are lost.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * class Card extends HTMLElement {
93
+ * // ✅ literal keys flow through — "header" | "footer"
94
+ * [SLOTS] = Slots.new(["header", "footer"] as const);
95
+ * }
96
+ *
97
+ * // ❌ widens to string; no typed slot:* props
98
+ * // [SLOTS] = Slots.new(["header", "footer"]);
99
+ * ```
100
+ */
101
+ static new<K extends string>(keys: K[]): Slots<K> & { readonly [P in K]: SlotInstance };
102
+ }
103
+ //#endregion
104
+ export { PrimitiveNodeType as a, Slots as i, Slot as n, SlotInstance as r, SLOTS as t };
@@ -132,7 +132,7 @@ var Slot = class Slot {
132
132
  * Symbol key for attaching a `Slots` instance to a custom element instance.
133
133
  * This prevent collisions with Element properties and are not meant to be treated as JSX children.
134
134
  */
135
- const $slots = Symbol("slots");
135
+ const SLOTS = Symbol("slots");
136
136
  const $map = Symbol("map");
137
137
  const $keys = Symbol("keys");
138
138
  const $has = Symbol("has");
@@ -168,6 +168,25 @@ var Slots = class Slots {
168
168
  static keys(slots) {
169
169
  return slots[$keys]();
170
170
  }
171
+ /**
172
+ * Create a typed `Slots` collection from a list of key names.
173
+ *
174
+ * Pass the keys with `as const` so TS narrows them to a literal union —
175
+ * this is what lets `ElementProps<typeof Cls>` synthesize `slot:${K}`
176
+ * entries. Without `as const`, the array type widens to `string[]` and
177
+ * the slot keys are lost.
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * class Card extends HTMLElement {
182
+ * // ✅ literal keys flow through — "header" | "footer"
183
+ * [SLOTS] = Slots.new(["header", "footer"] as const);
184
+ * }
185
+ *
186
+ * // ❌ widens to string; no typed slot:* props
187
+ * // [SLOTS] = Slots.new(["header", "footer"]);
188
+ * ```
189
+ */
171
190
  static new(keys) {
172
191
  const instance = new Slots(keys);
173
192
  return new Proxy(instance, { get(target, prop, receiver) {
@@ -177,4 +196,4 @@ var Slots = class Slots {
177
196
  }
178
197
  };
179
198
  //#endregion
180
- export { resolveNode as i, Slot as n, Slots as r, $slots as t };
199
+ export { resolveNode as i, Slot as n, Slots as r, SLOTS as t };
package/dist/slot.d.mts CHANGED
@@ -1,84 +1,2 @@
1
- import { t as PrimitiveNodeType } from "./lib-JA05lzCN.mjs";
2
-
3
- //#region src/slot.d.ts
4
- /**
5
- * A lightweight slot that reserves a region in the DOM using comment markers.
6
- * Content between the markers can be replaced dynamically without wrapper elements.
7
- */
8
- declare class Slot {
9
- #private;
10
- private readonly start;
11
- private readonly end;
12
- /**
13
- * Render the slot as a DocumentFragment.
14
- * If not yet mounted, inserts the comment markers and optional default content.
15
- * If already mounted, extracts and returns the current content WITHOUT disposing
16
- * it — the caller takes ownership of the returned nodes and is responsible for
17
- * their disposal.
18
- */
19
- slot(defaultContent?: PrimitiveNodeType): DocumentFragment;
20
- /** Dispose reactive children and remove all content between the markers. */
21
- clear(): void;
22
- /**
23
- * Replace the slot's content with the given element.
24
- * No-op if the slot is not mounted or the content is identical.
25
- */
26
- set(element: Node): void;
27
- /**
28
- * Extract and return the current slot content as a DocumentFragment.
29
- * Returns `null` if the slot is not mounted.
30
- * Content is NOT disposed — the caller takes ownership and is responsible
31
- * for disposal.
32
- */
33
- get(): DocumentFragment | null;
34
- /** Returns the parent node if the slot is mounted, otherwise `null`. */
35
- parent(): ParentNode | null;
36
- /** Whether the slot's comment markers are attached to the DOM. */
37
- isMounted(): boolean;
38
- private isSame;
39
- /**
40
- * Create a callable slot instance.
41
- *
42
- * The returned value is both a function and an object:
43
- * - Call it to render the slot with optional default content.
44
- * - Access `.set()`, `.parent()`, `.isMounted()` for slot management.
45
- *
46
- * @example
47
- * ```ts
48
- * const slot = createSlot();
49
- * el.append(slot("default text")); // mount with default
50
- * slot.set(newElement); // replace content
51
- * ```
52
- */
53
- static new(): Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment);
54
- }
55
- type SlotInstance = ReturnType<typeof Slot.new>;
56
- /** A callable slot — invoke to render, or access `.set()` / `.isMounted()` / `.parent()` for management. */
57
- /**
58
- * Symbol key for attaching a `Slots` instance to a custom element instance.
59
- * This prevent collisions with Element properties and are not meant to be treated as JSX children.
60
- */
61
- declare const $slots: unique symbol;
62
- declare const $map: unique symbol;
63
- declare const $keys: unique symbol;
64
- declare const $has: unique symbol;
65
- /**
66
- * A keyed collection of slot instances.
67
- * Slots are pre-created from the provided keys and lazily created on first access for unknown keys.
68
- */
69
- declare class Slots<K extends string> implements Iterable<[K, SlotInstance]> {
70
- readonly [$map]: Map<K, Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment)>;
71
- private constructor();
72
- [Symbol.iterator](): MapIterator<[K, Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment)]>;
73
- [Symbol.toStringTag](): string;
74
- [Symbol.hasInstance](instance: unknown): instance is Slots<any>;
75
- [$has](key: K): boolean;
76
- /** Check whether a slot with the given key exists. */
77
- static has<K extends string>(slots: Slots<K>, key: K): boolean;
78
- [$keys](): MapIterator<K>;
79
- /** Iterate over all registered slot keys. */
80
- static keys<K extends string>(slots: Slots<K>): MapIterator<K>;
81
- static new<K extends string>(keys: K[]): Slots<K> & { readonly [P in K]: SlotInstance };
82
- }
83
- //#endregion
84
- export { $slots, Slot, SlotInstance, Slots };
1
+ import { i as Slots, n as Slot, r as SlotInstance, t as SLOTS } from "./slot-C7GQZe-r.mjs";
2
+ export { SLOTS, Slot, SlotInstance, Slots };
package/dist/slot.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { n as Slot, r as Slots, t as $slots } from "./slot-Cydy7-0L.mjs";
2
- export { $slots, Slot, Slots };
1
+ import { n as Slot, r as Slots, t as SLOTS } from "./slot-Kb61AcgW.mjs";
2
+ export { SLOTS, Slot, Slots };
@@ -13311,4 +13311,4 @@ Object.defineProperty(globalThis, GLOBAL_EXPECT, {
13311
13311
  configurable: true
13312
13312
  });
13313
13313
  //#endregion
13314
- export { beforeEach as a, beforeAll as i, vi as n, describe as o, afterEach as r, it as s, globalExpect as t };
13314
+ export { beforeEach as a, test$2 as c, beforeAll as i, vi as n, describe as o, afterEach as r, it as s, globalExpect as t };
@@ -0,0 +1,11 @@
1
+ //#region src/utilities/_observe.d.ts
2
+ /**
3
+ * Internal helper for observer wrappers (Intersection/Mutation/Resize).
4
+ * Runs `attach` to start observing, registers `disconnect` with the current
5
+ * scope, and returns a `Disposable`.
6
+ */
7
+ declare function observe<O extends {
8
+ disconnect(): void;
9
+ }>(obs: O, attach: (o: O) => void): Disposable;
10
+ //#endregion
11
+ export { observe };
@@ -0,0 +1,15 @@
1
+ import { _ as onCleanup } from "../signals-J8dK_rA4.mjs";
2
+ //#region src/utilities/_observe.ts
3
+ /**
4
+ * Internal helper for observer wrappers (Intersection/Mutation/Resize).
5
+ * Runs `attach` to start observing, registers `disconnect` with the current
6
+ * scope, and returns a `Disposable`.
7
+ */
8
+ function observe(obs, attach) {
9
+ attach(obs);
10
+ const cleanup = () => obs.disconnect();
11
+ onCleanup(cleanup);
12
+ return { [Symbol.dispose]: cleanup };
13
+ }
14
+ //#endregion
15
+ export { observe };
@@ -1,4 +1,4 @@
1
- import { t as Computed } from "../index-DUshSQ_6.mjs";
1
+ import { t as Computed } from "../index-DydGTqZU.mjs";
2
2
 
3
3
  //#region src/utilities/active-element.d.ts
4
4
  declare const activeElement: Computed<Element | null>;
@@ -1,11 +1,15 @@
1
+ import { u as computed } from "../signals-J8dK_rA4.mjs";
1
2
  import { fromEvent, sync } from "./event-driven.mjs";
3
+ import { isBrowser } from "./environment.mjs";
2
4
  //#region src/utilities/active-element.ts
3
5
  /**
4
6
  * Returns a read-only `Computed<Element | null>` bound to `document.activeElement`.
5
- * Reacts to `focusin` and `focusout` events on the document.
7
+ * Reacts to `focusin` and `focusout` events on the document. Outside a browser,
8
+ * always `null`.
6
9
  */
7
10
  function createActiveElement() {
8
- const [active] = sync(fromEvent(document, ["focusin", "focusout"]), () => typeof document !== "undefined" ? document.activeElement : null);
11
+ if (!isBrowser) return computed(() => null);
12
+ const [active] = sync(fromEvent(document, ["focusin", "focusout"]), () => document.activeElement);
9
13
  return active;
10
14
  }
11
15
  const activeElement = createActiveElement();
@@ -1,4 +1,4 @@
1
- import { o as describe, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
1
+ import { o as describe, s as it, t as globalExpect } from "../test.BmQO5GaM-DfGStnii.mjs";
2
2
  import { activeElement } from "./active-element.mjs";
3
3
  //#region src/utilities/active-element.test.ts
4
4
  describe("activeElement (singleton)", () => {
@@ -1,4 +1,4 @@
1
- import { n as MaybeReactive } from "../index-DUshSQ_6.mjs";
1
+ import { n as MaybeReactive } from "../index-DydGTqZU.mjs";
2
2
  import { ComputedPromise } from "./promise.mjs";
3
3
 
4
4
  //#region src/utilities/async.d.ts
@@ -1,4 +1,4 @@
1
- import { _ as signal, r as resolve, u as effect, y as untracked } from "../signals-BHmWX6ox.mjs";
1
+ import { b as untracked, d as effect, r as resolve, v as signal } from "../signals-J8dK_rA4.mjs";
2
2
  import { promise } from "./promise.mjs";
3
3
  //#region src/utilities/async.ts
4
4
  var Async = class {
@@ -1,5 +1,5 @@
1
- import { _ as signal, g as onCleanup, u as effect } from "../signals-BHmWX6ox.mjs";
2
- import { n as vi, o as describe, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
1
+ import { _ as onCleanup, d as effect, v as signal } from "../signals-J8dK_rA4.mjs";
2
+ import { n as vi, o as describe, s as it, t as globalExpect } from "../test.BmQO5GaM-DfGStnii.mjs";
3
3
  import { Async, async } from "./async.mjs";
4
4
  import { createInterval } from "./interval.mjs";
5
5
  //#region src/utilities/async.test.ts
@@ -1,4 +1,4 @@
1
- import { t as Computed } from "../index-DUshSQ_6.mjs";
1
+ import { t as Computed } from "../index-DydGTqZU.mjs";
2
2
 
3
3
  //#region src/utilities/debounced.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { _ as signal, u as effect } from "../signals-BHmWX6ox.mjs";
1
+ import { d as effect, v as signal } from "../signals-J8dK_rA4.mjs";
2
2
  import { createTimeout } from "./timeout.mjs";
3
3
  //#region src/utilities/debounced.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { _ as signal, d as effectScope } from "../signals-BHmWX6ox.mjs";
2
- import { a as beforeEach, n as vi, o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
1
+ import { f as effectScope, v as signal } from "../signals-J8dK_rA4.mjs";
2
+ import { a as beforeEach, n as vi, o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-DfGStnii.mjs";
3
3
  import { createDebounced } from "./debounced.mjs";
4
4
  //#region src/utilities/debounced.test.ts
5
5
  beforeEach(() => {
@@ -1,4 +1,4 @@
1
- import { t as Computed } from "../index-DUshSQ_6.mjs";
1
+ import { t as Computed } from "../index-DydGTqZU.mjs";
2
2
 
3
3
  //#region src/utilities/element-rect.d.ts
4
4
  type RectResult = {
@@ -1,4 +1,4 @@
1
- import { _ as signal } from "../signals-BHmWX6ox.mjs";
1
+ import { v as signal } from "../signals-J8dK_rA4.mjs";
2
2
  import { createResizeObserver } from "./resize-observer.mjs";
3
3
  //#region src/utilities/element-rect.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
- import { d as effectScope } from "../signals-BHmWX6ox.mjs";
2
- import { n as vi, o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-ANkhHvbr.mjs";
1
+ import { f as effectScope } from "../signals-J8dK_rA4.mjs";
2
+ import { n as vi, o as describe, r as afterEach, s as it, t as globalExpect } from "../test.BmQO5GaM-DfGStnii.mjs";
3
3
  import { createElementRect } from "./element-rect.mjs";
4
4
  //#region src/utilities/element-rect.test.ts
5
5
  afterEach(() => {
@@ -1,4 +1,4 @@
1
- import { r as Signal } from "../index-DUshSQ_6.mjs";
1
+ import { r as Signal } from "../index-DydGTqZU.mjs";
2
2
 
3
3
  //#region src/utilities/element-scroll.d.ts
4
4
  type ElementScrollResult = {