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.
- package/README.md +23 -21
- package/dist/attributes.d.mts +1 -1
- package/dist/await.d.mts +6 -5
- package/dist/await.mjs +1 -37
- package/dist/{types-CUvFIgPa.d.mts → children-s3nFjpLA.d.mts} +124 -226
- package/dist/custom-elements-CdpilMDu.d.mts +87 -0
- package/dist/custom-elements.d.mts +2 -2
- package/dist/{element-D3om9yA6.mjs → element-Di0PYFX1.mjs} +15 -38
- package/dist/environment-CTAGxqz_.d.mts +19 -0
- package/dist/for.d.mts +9 -4
- package/dist/for.mjs +1 -1
- package/dist/{fragment-ROPRBJQd.mjs → fragment-Bvs1sGu1.mjs} +3 -3
- package/dist/hydrate/index.mjs +1 -1
- package/dist/{hydrate-6Qx4n4Su.mjs → hydrate-DvWdnV-e.mjs} +5 -5
- package/dist/integrations/astro-client.mjs +2 -2
- package/dist/integrations/astro-server.mjs +2 -2
- package/dist/integrations/astro-slots.d.mts +6 -5
- package/dist/integrations/astro-slots.mjs +9 -8
- package/dist/integrations/react.d.mts +1 -1
- package/dist/integrations/react.mjs +1 -1
- package/dist/jsx-runtime/index.d.mts +2 -2
- package/dist/jsx-runtime/index.mjs +2 -2
- package/dist/polyfill-BVNd6ogU.d.mts +9 -0
- package/dist/render.mjs +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/{server-iFSng50i.mjs → server-CTkyXTV6.mjs} +2 -2
- package/dist/signals/index.d.mts +1 -1
- package/dist/slot.d.mts +83 -2
- package/dist/slot.mjs +179 -2
- package/dist/ui/marketing/marketing.css +5 -3
- package/dist/ui/otp-input/index.d.mts +6 -5
- package/dist/ui/otp-input/index.mjs +5 -5
- package/dist/ui/styles/index.css +174 -172
- package/dist/ui/styles/unset.css +212 -210
- package/dist/utilities/active-element.d.mts +1 -1
- package/dist/utilities/async.d.mts +2 -2
- package/dist/utilities/async.mjs +13 -5
- package/dist/utilities/debounced.d.mts +1 -1
- package/dist/utilities/dom-lifecycle.bench.mjs +2 -2
- package/dist/utilities/element-rect.d.mts +1 -1
- package/dist/utilities/element-scroll.d.mts +1 -1
- package/dist/utilities/environment.d.mts +2 -7
- package/dist/utilities/environment.mjs +13 -1
- package/dist/utilities/event-driven.d.mts +1 -1
- package/dist/utilities/event-listener.d.mts +1 -1
- package/dist/utilities/focus-within.d.mts +1 -1
- package/dist/utilities/hover.d.mts +1 -1
- package/dist/utilities/interval.d.mts +1 -1
- package/dist/utilities/location.d.mts +1 -1
- package/dist/utilities/media-devices.d.mts +1 -1
- package/dist/utilities/media-player.d.mts +1 -1
- package/dist/utilities/media-query.d.mts +1 -1
- package/dist/utilities/network.d.mts +1 -1
- package/dist/utilities/orientation.d.mts +1 -1
- package/dist/utilities/previous.d.mts +1 -1
- package/dist/utilities/promise.d.mts +1 -1
- package/dist/utilities/routing.d.mts +1 -1
- package/dist/utilities/search-params.d.mts +1 -1
- package/dist/utilities/storage.d.mts +1 -1
- package/dist/utilities/throttled.d.mts +1 -1
- package/dist/utilities/timeout.d.mts +1 -1
- package/dist/utilities/window-focus.d.mts +1 -1
- package/dist/utilities/window-size.d.mts +1 -1
- package/package.json +3 -1
- package/dist/custom-elements-BGcU6ldL.d.mts +0 -57
- package/dist/slot-BFWXeFRl.d.mts +0 -77
- package/dist/slot-Dvf30O0B.mjs +0 -138
- /package/dist/{attributes-3r7Diua4.d.mts → attributes-DILeh3-s.d.mts} +0 -0
- /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 {
|
|
8
|
+
import type { Props } from "elements-kit/jsx-runtime";
|
|
9
9
|
|
|
10
|
-
function Counter(props:
|
|
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
|
|
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 (`
|
|
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
|
|
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
|
-
|
|
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
|
-
| `
|
|
420
|
-
| `Props<
|
|
421
|
-
| `
|
|
422
|
-
| `
|
|
423
|
-
| `ReactiveProps<P>` | Component-facing — every prop becomes a `Computed<T>` getter (what function components receive) |
|
|
420
|
+
| `PropsOf<C>` | Unified — fn/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
|
-
|
|
427
|
+
Callers never wrap anything by hand — at 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 {
|
|
432
|
+
import type { Props } from "elements-kit/jsx-runtime";
|
|
431
433
|
|
|
432
|
-
function Greeting(props:
|
|
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
|
|
477
|
+
For named slots, declare `@slot()` properties — reading places the region in your template, assigning fills it (from any framework, or none):
|
|
476
478
|
|
|
477
479
|
```ts
|
|
478
|
-
import {
|
|
480
|
+
import { slot } from "elements-kit/slot";
|
|
479
481
|
|
|
480
482
|
class Card extends HTMLElement {
|
|
481
|
-
|
|
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
|
-
//
|
|
494
|
+
// PropsOf<typeof XPicker> now includes `on:commit`
|
|
493
495
|
```
|
|
494
496
|
|
|
495
497
|
## Roadmap
|
package/dist/attributes.d.mts
CHANGED
|
@@ -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-
|
|
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
|
|
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
|
-
|
|
48
|
-
|
|
47
|
+
type AwaitChildren = Children | PromiseLike<Children> | (Children | PromiseLike<Children>)[];
|
|
48
|
+
declare function Await(props: Props<{
|
|
49
|
+
fallback?: Children;
|
|
49
50
|
when?: unknown;
|
|
50
|
-
children?:
|
|
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
|
|
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,
|