elements-kit 0.21.0 → 0.22.1

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 (69) hide show
  1. package/README.md +23 -21
  2. package/dist/attributes.d.mts +1 -1
  3. package/dist/await.d.mts +6 -5
  4. package/dist/await.mjs +1 -37
  5. package/dist/{types-CUvFIgPa.d.mts → children-s3nFjpLA.d.mts} +124 -226
  6. package/dist/custom-elements-CdpilMDu.d.mts +87 -0
  7. package/dist/custom-elements.d.mts +2 -2
  8. package/dist/{element-D3om9yA6.mjs → element-Di0PYFX1.mjs} +15 -38
  9. package/dist/environment-CTAGxqz_.d.mts +19 -0
  10. package/dist/for.d.mts +9 -4
  11. package/dist/for.mjs +1 -1
  12. package/dist/{fragment-ROPRBJQd.mjs → fragment-Bvs1sGu1.mjs} +3 -3
  13. package/dist/hydrate/index.mjs +1 -1
  14. package/dist/{hydrate-6Qx4n4Su.mjs → hydrate-DvWdnV-e.mjs} +5 -5
  15. package/dist/integrations/astro-client.mjs +2 -2
  16. package/dist/integrations/astro-server.mjs +2 -2
  17. package/dist/integrations/astro-slots.d.mts +6 -5
  18. package/dist/integrations/astro-slots.mjs +9 -8
  19. package/dist/integrations/react.d.mts +1 -1
  20. package/dist/integrations/react.mjs +1 -1
  21. package/dist/jsx-runtime/index.d.mts +2 -2
  22. package/dist/jsx-runtime/index.mjs +2 -2
  23. package/dist/polyfill-BVNd6ogU.d.mts +9 -0
  24. package/dist/render.mjs +1 -1
  25. package/dist/server/index.mjs +1 -1
  26. package/dist/{server-iFSng50i.mjs → server-CTkyXTV6.mjs} +2 -2
  27. package/dist/signals/index.d.mts +1 -1
  28. package/dist/slot.d.mts +83 -2
  29. package/dist/slot.mjs +179 -2
  30. package/dist/ui/marketing/marketing.css +5 -3
  31. package/dist/ui/otp-input/index.d.mts +6 -5
  32. package/dist/ui/otp-input/index.mjs +5 -5
  33. package/dist/ui/styles/index.css +174 -172
  34. package/dist/ui/styles/unset.css +212 -210
  35. package/dist/utilities/active-element.d.mts +1 -1
  36. package/dist/utilities/async.d.mts +2 -2
  37. package/dist/utilities/async.mjs +13 -5
  38. package/dist/utilities/debounced.d.mts +1 -1
  39. package/dist/utilities/dom-lifecycle.bench.mjs +2 -2
  40. package/dist/utilities/element-rect.d.mts +1 -1
  41. package/dist/utilities/element-scroll.d.mts +1 -1
  42. package/dist/utilities/environment.d.mts +2 -7
  43. package/dist/utilities/environment.mjs +13 -1
  44. package/dist/utilities/event-driven.d.mts +1 -1
  45. package/dist/utilities/event-listener.d.mts +1 -1
  46. package/dist/utilities/focus-within.d.mts +1 -1
  47. package/dist/utilities/hover.d.mts +1 -1
  48. package/dist/utilities/interval.d.mts +1 -1
  49. package/dist/utilities/location.d.mts +1 -1
  50. package/dist/utilities/media-devices.d.mts +1 -1
  51. package/dist/utilities/media-player.d.mts +1 -1
  52. package/dist/utilities/media-query.d.mts +1 -1
  53. package/dist/utilities/network.d.mts +1 -1
  54. package/dist/utilities/orientation.d.mts +1 -1
  55. package/dist/utilities/previous.d.mts +1 -1
  56. package/dist/utilities/promise.d.mts +1 -1
  57. package/dist/utilities/routing.d.mts +1 -1
  58. package/dist/utilities/search-params.d.mts +1 -1
  59. package/dist/utilities/storage.d.mts +1 -1
  60. package/dist/utilities/throttled.d.mts +1 -1
  61. package/dist/utilities/timeout.d.mts +1 -1
  62. package/dist/utilities/window-focus.d.mts +1 -1
  63. package/dist/utilities/window-size.d.mts +1 -1
  64. package/package.json +3 -1
  65. package/dist/custom-elements-BGcU6ldL.d.mts +0 -57
  66. package/dist/slot-BFWXeFRl.d.mts +0 -77
  67. package/dist/slot-Dvf30O0B.mjs +0 -138
  68. /package/dist/{attributes-3r7Diua4.d.mts → attributes-DILeh3-s.d.mts} +0 -0
  69. /package/dist/{scope-zbEG299F.mjs → scope-C1vELXqP.mjs} +0 -0
package/README.md CHANGED
@@ -5,9 +5,9 @@
5
5
  ```tsx
6
6
  import { signal, computed } from "elements-kit/signals";
7
7
  import { render } from "elements-kit/render";
8
- import type { ReactiveProps } from "elements-kit/jsx-runtime";
8
+ import type { Props } from "elements-kit/jsx-runtime";
9
9
 
10
- function Counter(props: ReactiveProps<{ initial?: number }>) {
10
+ function Counter(props: Props<{ initial?: number }>) {
11
11
  const count = signal(props.initial() ?? 0);
12
12
  const doubled = computed(() => count() * 2);
13
13
 
@@ -52,7 +52,7 @@ ElementsKit is a library of reactive primitives, not a framework. Each piece is
52
52
 
53
53
  - **Designed for the AI age.** Code is cheap; maintenance still isn't. Primitives compose into higher-level blocks. Swap one block at a time instead of maintaining long lines of code.
54
54
 
55
- - **Bundler-friendly.** Every primitive is its own subpath — `elements-kit/signals`, `elements-kit/utilities/*`, `elements-kit/integrations/*`. Import only what you need.
55
+ - **Bundler-friendly.** Every primitive is its own subpath — `elements-kit/signals`, `elements-kit/utilities/*`, `elements-kit/ui/*`, `elements-kit/integrations/*`. Import only what you need.
56
56
 
57
57
  ## Packages
58
58
 
@@ -63,16 +63,17 @@ Every feature is a separate subpath export — import only what you use.
63
63
  | `elements-kit/signals` | `signal`, `computed`, `effect`, `effectScope`, `batch`, `untracked`, `trigger`, `onCleanup`, `MaybeReactive`, `resolve`, `resolveProps`, `@reactive` |
64
64
  | `elements-kit/render` | `render(target, setup)` — mount a node with a scoped lifetime; returns `unmount` |
65
65
  | `elements-kit/attributes` | `@attributes` decorator + `ATTRIBUTES` symbol |
66
- | `elements-kit/slot` | `Slot`, `Slots`, `SLOTS` symbol — comment-marker DOM regions |
67
- | `elements-kit/custom-elements` | `defineElement`, `CustomElementRegistry` |
66
+ | `elements-kit/slot` | `Slot` class + `@slot()` decorator + `SlotContent` type — comment-marker DOM regions as plain properties |
67
+ | `elements-kit/custom-elements` | `defineElement`, `CustomElementRegistry`, `PropertiesOf`, `AttributesOf`, `EventsOf`, `PublicPropKeys` — raw framework-agnostic extractors for a custom element's properties/attributes/events |
68
68
  | `elements-kit/for` | `For` keyed-list component |
69
- | `elements-kit/jsx-runtime` | JSX factory + type helpers (`ElementProps`, `Props`, `ComponentProps`, `MaybeReactiveProps`, `ReactiveProps`, `Require`) — configure via `jsxImportSource` |
69
+ | `elements-kit/jsx-runtime` | JSX factory + type helpers (`PropsOf`, `MaybeReactiveProps`, `RawProps`, `Props`, `Require`) — configure via `jsxImportSource` |
70
70
  | `elements-kit/server` | `renderToStream`, `renderToString` — streaming HTML rendering in any JS runtime (Node, edge/Workers), no DOM required *(experimental)* |
71
71
  | `elements-kit/hydrate` | `hydrate(container, () => <App/>)` — adopt server-rendered DOM and make it interactive *(experimental)* |
72
72
  | `elements-kit/await` | `Await` — loading boundary (Suspense equivalent); code splitting = `async` + dynamic import *(experimental)* |
73
73
  | `elements-kit/integrations/react` | `useSignal`, `useScope` React bridge hooks |
74
74
  | `elements-kit/integrations/astro` | `elementsKit()` Astro integration — elements-kit components as server-rendered, hydrated islands *(experimental)* |
75
75
  | `elements-kit/utilities/*` | Reactive browser-API utilities — see [src/utilities/README.md](src/utilities/README.md) |
76
+ | `elements-kit/ui/*` | Accessible UI component styles (CSS) + an optional base theme (`elements-kit/ui/styles.css`); plus the `otp-input` custom element and `overlay` positioning/interaction behaviors. Catalog in [src/ui/README.md](src/ui/README.md) |
76
77
 
77
78
  ## Signals
78
79
 
@@ -340,7 +341,7 @@ await op; // awaitable (delegates to .then/.catch/.finally via .raw)
340
341
  op.stop(); // halt reruns + fire registered cleanup
341
342
  ```
342
343
 
343
- Reactive state getters: `.state`, `.value`, `.reason`, `.result`, `.pending`, `.raw` (the underlying `ComputedPromise`).
344
+ Reactive state getters: `.state` (`"idle" | "pending" | "fulfilled" | "rejected"` — `idle` before the first run, so `.pending` is `false` until you trigger one), `.value`, `.reason`, `.result`, `.pending`, `.raw` (the underlying `ComputedPromise`).
344
345
 
345
346
  One-shot mutation (no tracking):
346
347
 
@@ -412,24 +413,25 @@ import { For } from "elements-kit/for";
412
413
 
413
414
  ## Prop types
414
415
 
415
- Six type helpers derive JSX prop shapes from your components — no parallel `declare global` block to maintain. Full guide at [docs/src/content/docs/elements/types.mdx](docs/src/content/docs/elements/types.mdx).
416
+ A small set of type helpers derives JSX prop shapes from your components — no parallel `declare global` block to maintain. Full guide at [docs/src/content/docs/elements/types.mdx](docs/src/content/docs/elements/types.mdx).
416
417
 
417
418
  | Helper | For |
418
419
  | ------ | --- |
419
- | `ElementProps<typeof Cls>` | `HTMLElement` subclass — full surface (attrs, events, slots, children) |
420
- | `Props<C>` | Class instance, constructor, or function component unified |
421
- | `ComponentProps<typeof Cls>` | Class components with `constructor(props: P)` |
422
- | `MaybeReactiveProps<P>` | Caller-facing wrap every prop in `MaybeReactive` (what parents pass) |
423
- | `ReactiveProps<P>` | Component-facing — every prop becomes a `Computed<T>` getter (what function components receive) |
420
+ | `PropsOf<C>` | Unifiedfn/class components give raw prop shapes; custom-element ctors give the full JSX surface (attrs, events, slots, children) |
421
+ | `Props<P>` | Component-facing every prop becomes a `Computed<T>` getter (what function components receive) |
422
+ | `MaybeReactiveProps<P>` | Caller-facing wrap every prop in `MaybeReactive` (e.g. a class component's constructor param) |
423
+ | `RawProps<R>` | Recover the raw `P` from a branded `Props<P>` |
424
424
  | `MaybeReactive<T>` | Scalar value-or-getter (from `elements-kit/signals`) |
425
425
  | `Require<P, K>` | Promote optional keys to required |
426
426
 
427
- The JSX runtime auto-wraps function-component propseach key arrives as a callable getter that subscribes on read. Pair the signature with `ReactiveProps<P>` and read `props.x()`:
427
+ Callers never wrap anything by handat every JSX call site the runtime's `LibraryManagedAttributes` automatically lets parents pass each prop as a static value *or* a signal/computed.
428
+
429
+ The JSX runtime auto-wraps function-component props — each key arrives as a callable getter that subscribes on read. Pair the signature with `Props<P>` and read `props.x()`:
428
430
 
429
431
  ```tsx
430
- import type { ReactiveProps } from "elements-kit/jsx-runtime";
432
+ import type { Props } from "elements-kit/jsx-runtime";
431
433
 
432
- function Greeting(props: ReactiveProps<{ name: string }>) {
434
+ function Greeting(props: Props<{ name: string }>) {
433
435
  return <p>Hello, {props.name}</p>;
434
436
  }
435
437
  ```
@@ -472,15 +474,15 @@ class MyElement extends HTMLElement {
472
474
  }
473
475
  ```
474
476
 
475
- For typed slots, attach a `[SLOTS]` instance field pass the key list with `as const` so TS can narrow:
477
+ For named slots, declare `@slot()` propertiesreading places the region in your template, assigning fills it (from any framework, or none):
476
478
 
477
479
  ```ts
478
- import { SLOTS, Slots } from "elements-kit/slot";
480
+ import { slot } from "elements-kit/slot";
479
481
 
480
482
  class Card extends HTMLElement {
481
- [SLOTS] = Slots.new(["header", "footer"] as const);
483
+ @slot() header!: Node
484
+ @slot() footer!: Node
482
485
  }
483
- // ElementProps<typeof Card> now includes `slot:header` / `slot:footer`
484
486
  ```
485
487
 
486
488
  For typed events, declare a `static events` map:
@@ -489,7 +491,7 @@ For typed events, declare a `static events` map:
489
491
  class XPicker extends HTMLElement {
490
492
  declare static events: { commit: CustomEvent<number> };
491
493
  }
492
- // ElementProps<typeof XPicker> now includes `on:commit`
494
+ // PropsOf<typeof XPicker> now includes `on:commit`
493
495
  ```
494
496
 
495
497
  ## Roadmap
@@ -1,2 +1,2 @@
1
- import { a as Attributes, c as observedAttributes, i as AttributeTarget, n as AttrChangeHandler, o as attributes, r as AttributeDecorated, s as dispatchAttrChange, t as ATTRIBUTES } from "./attributes-3r7Diua4.mjs";
1
+ import { a as Attributes, c as observedAttributes, i as AttributeTarget, n as AttrChangeHandler, o as attributes, r as AttributeDecorated, s as dispatchAttrChange, t as ATTRIBUTES } from "./attributes-DILeh3-s.mjs";
2
2
  export { ATTRIBUTES, AttrChangeHandler, AttributeDecorated, AttributeTarget, Attributes, attributes, dispatchAttrChange, observedAttributes };
package/dist/await.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as Child } from "./types-CUvFIgPa.mjs";
1
+ import { c as Props, t as Children } from "./children-s3nFjpLA.mjs";
2
2
 
3
3
  //#region src/await.d.ts
4
4
  /** @internal Metadata stamped on an Await region getter (see claim walk). */
@@ -44,10 +44,11 @@ interface AsyncRegionMeta {
44
44
  * </Await>
45
45
  * ```
46
46
  */
47
- declare function Await(props: {
48
- fallback?: Child | (() => Child);
47
+ type AwaitChildren = Children | PromiseLike<Children> | (Children | PromiseLike<Children>)[];
48
+ declare function Await(props: Props<{
49
+ fallback?: Children;
49
50
  when?: unknown;
50
- children?: Child;
51
- }): Element;
51
+ children?: AwaitChildren;
52
+ }>): Element;
52
53
  //#endregion
53
54
  export { AsyncRegionMeta, Await };
package/dist/await.mjs CHANGED
@@ -13,42 +13,6 @@ function toAwaitables(value) {
13
13
  else if (isThenable(item)) out.push(promise(item));
14
14
  return out;
15
15
  }
16
- /**
17
- * Loading boundary for async children — elements-kit's `Suspense` equivalent.
18
- *
19
- * Direct async children (`promise`/`async` values — including the
20
- * code-splitting pattern `async(() => import("./chart"))`) are detected
21
- * automatically; pass `when` to gate on arbitrary awaitables instead. While
22
- * anything is pending the client renders `fallback`; once everything settles
23
- * the children show. The server never renders the fallback — the stream
24
- * awaits and emits the real content. During hydration the server content
25
- * stays visible while the region is pending (no fallback flash).
26
- *
27
- * Prefer a thunk fallback (`fallback={() => <Spinner/>}`) so it renders
28
- * fresh each time the boundary re-enters a pending state.
29
- *
30
- * @example Code splitting with `async` + dynamic import:
31
- * ```tsx
32
- * const chart = async(() => import("./chart").then((m) => m.default));
33
- *
34
- * function Panel() {
35
- * chart.run(); // server: awaited · hydration: deferred · client: import
36
- * return (
37
- * <Await fallback={() => <em>loading…</em>}>{chart}</Await>
38
- * );
39
- * }
40
- * ```
41
- *
42
- * @example Passing props to a code-split component:
43
- * ```tsx
44
- * const chart = async(() => import("./chart").then((m) => m.default));
45
- * chart.run();
46
- *
47
- * <Await fallback={() => <em>loading…</em>}>
48
- * {promise(chart.then((C) => () => <C data={data} />))}
49
- * </Await>
50
- * ```
51
- */
52
16
  function Await(props) {
53
17
  const read = (value) => typeof value === "function" && !isReactive(value) ? value() : value;
54
18
  const children = read(props.children);
@@ -58,7 +22,7 @@ function Await(props) {
58
22
  if (awaitables.length === 0) return children;
59
23
  if (effectsInert()) return promise(Promise.all(awaitables).then(() => () => children));
60
24
  const fallback = props.fallback;
61
- const pending = () => awaitables.some((a) => a.state === "pending");
25
+ const pending = () => awaitables.some((a) => a.state !== "fulfilled" && a.state !== "rejected");
62
26
  const region = () => pending() ? read(fallback) : children;
63
27
  region[ASYNC_REGION] = {
64
28
  ids: 1 + fromChildren.length,