elements-kit 0.0.17 → 0.0.19
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 +97 -19
- package/dist/attributes.d.mts +1 -1
- package/dist/{define-CjbTZ3VG.d.mts → custom-elements-bVYOkHKt.d.mts} +2 -2
- package/dist/custom-elements.d.mts +2 -74
- package/dist/custom-elements.mjs +2 -91
- package/dist/{element-CGVy_8TW.mjs → element-DxmInKJw.mjs} +32 -20
- package/dist/for.d.mts +1 -1
- package/dist/for.mjs +3 -2
- package/dist/infer-Dv5Wk-7E.d.mts +618 -0
- package/dist/integrations/react.d.mts +1 -1
- package/dist/integrations/react.mjs +6 -4
- package/dist/jsx-runtime/index.d.mts +2 -73
- package/dist/jsx-runtime/index.mjs +8 -14
- package/dist/{signals-J8dK_rA4.mjs → lib-D6duEs38.mjs} +1 -105
- package/dist/render.d.mts +21 -0
- package/dist/render.mjs +32 -0
- package/dist/scope-DM2gzOkb.mjs +45 -0
- package/dist/signals/index.d.mts +1 -1
- package/dist/signals/index.mjs +115 -1
- package/dist/{slot-C7GQZe-r.d.mts → slot-B5_VHB7E.d.mts} +10 -0
- package/dist/slot.d.mts +1 -1
- package/dist/{test.BmQO5GaM-DfGStnii.mjs → test.BmQO5GaM-BeO5pvCo.mjs} +1 -1
- package/dist/utilities/_observe.mjs +2 -1
- package/dist/utilities/active-element.d.mts +1 -1
- package/dist/utilities/active-element.mjs +2 -1
- package/dist/utilities/active-element.test.mjs +1 -1
- package/dist/utilities/async.d.mts +1 -1
- package/dist/utilities/async.mjs +2 -1
- package/dist/utilities/async.test.mjs +3 -2
- package/dist/utilities/debounced.d.mts +1 -1
- package/dist/utilities/debounced.mjs +2 -1
- package/dist/utilities/debounced.test.mjs +3 -2
- package/dist/utilities/element-rect.d.mts +1 -1
- package/dist/utilities/element-rect.mjs +2 -1
- package/dist/utilities/element-rect.test.mjs +3 -2
- package/dist/utilities/element-scroll.d.mts +1 -1
- package/dist/utilities/element-scroll.test.mjs +3 -2
- package/dist/utilities/event-driven.d.mts +1 -1
- package/dist/utilities/event-driven.mjs +2 -1
- package/dist/utilities/event-listener.d.mts +1 -1
- package/dist/utilities/event-listener.mjs +2 -1
- package/dist/utilities/event-listener.test.mjs +3 -2
- package/dist/utilities/focus-within.d.mts +1 -1
- package/dist/utilities/focus-within.mjs +2 -1
- package/dist/utilities/focus-within.test.mjs +3 -2
- package/dist/utilities/hover.d.mts +1 -1
- package/dist/utilities/hover.mjs +2 -1
- package/dist/utilities/hover.test.mjs +3 -2
- package/dist/utilities/intersection-observer.test.mjs +3 -2
- package/dist/utilities/interval.d.mts +1 -1
- package/dist/utilities/interval.mjs +2 -1
- package/dist/utilities/interval.test.mjs +3 -2
- package/dist/utilities/location.d.mts +1 -1
- package/dist/utilities/location.mjs +2 -1
- package/dist/utilities/location.test.mjs +1 -1
- package/dist/utilities/long-press.test.mjs +3 -2
- package/dist/utilities/media-devices.d.mts +1 -1
- package/dist/utilities/media-devices.mjs +2 -1
- package/dist/utilities/media-devices.test.mjs +3 -2
- package/dist/utilities/media-player.d.mts +1 -1
- package/dist/utilities/media-player.test.mjs +3 -2
- package/dist/utilities/media-query.d.mts +1 -1
- package/dist/utilities/media-query.mjs +2 -1
- package/dist/utilities/mutation-observer.test.mjs +3 -2
- package/dist/utilities/network.d.mts +1 -1
- package/dist/utilities/network.mjs +2 -1
- package/dist/utilities/network.test.mjs +1 -1
- package/dist/utilities/on-click-outside.test.mjs +3 -2
- package/dist/utilities/orientation.d.mts +1 -1
- package/dist/utilities/orientation.mjs +2 -1
- package/dist/utilities/previous.d.mts +1 -1
- package/dist/utilities/previous.mjs +2 -1
- package/dist/utilities/previous.test.mjs +3 -2
- package/dist/utilities/promise.d.mts +1 -1
- package/dist/utilities/promise.mjs +2 -1
- package/dist/utilities/promise.test.mjs +3 -2
- package/dist/utilities/retry.mjs +2 -1
- package/dist/utilities/retry.test.mjs +3 -2
- package/dist/utilities/routing.d.mts +1 -1
- package/dist/utilities/routing.mjs +2 -1
- package/dist/utilities/routing.test.mjs +1 -1
- package/dist/utilities/search-params.d.mts +1 -1
- package/dist/utilities/search-params.test.mjs +3 -2
- package/dist/utilities/ssr.test.mjs +1 -1
- package/dist/utilities/storage.d.mts +1 -1
- package/dist/utilities/storage.test.mjs +3 -2
- package/dist/utilities/throttled.d.mts +1 -1
- package/dist/utilities/throttled.mjs +2 -1
- package/dist/utilities/throttled.test.mjs +3 -2
- package/dist/utilities/timeout.d.mts +1 -1
- package/dist/utilities/timeout.mjs +2 -1
- package/dist/utilities/timeout.test.mjs +3 -2
- package/dist/utilities/window-focus.d.mts +1 -1
- package/dist/utilities/window-focus.mjs +2 -1
- package/dist/utilities/window-size.d.mts +1 -1
- package/dist/utilities/window-size.mjs +2 -1
- package/dist/utilities/window-size.test.mjs +1 -1
- package/package.json +6 -1
- package/dist/index-DydGTqZU.d.mts +0 -315
- package/dist/infer-BfzRJoCn.d.mts +0 -203
- package/dist/polyfill-BVNd6ogU.d.mts +0 -9
- /package/dist/{attributes-Dtn68R1u.d.mts → attributes-aiRoArZz.d.mts} +0 -0
- /package/dist/{magic-string.es-i62WTP6J.mjs → magic-string.es-cTgJnTCj.mjs} +0 -0
package/README.md
CHANGED
|
@@ -25,8 +25,8 @@ class CounterElement extends HTMLElement {
|
|
|
25
25
|
this.appendChild(
|
|
26
26
|
<section>
|
|
27
27
|
<p>Count: <strong>{() => this.count}</strong> — Doubled: <strong>{this.doubled}</strong></p>
|
|
28
|
-
<button
|
|
29
|
-
<button
|
|
28
|
+
<button on:click={() => this.count++}>+1</button>{" "}
|
|
29
|
+
<button on:click={() => this.count--}>−1</button>
|
|
30
30
|
</section> as Element,
|
|
31
31
|
);
|
|
32
32
|
}
|
|
@@ -43,11 +43,14 @@ Every feature is a separate subpath export — import only what you use.
|
|
|
43
43
|
|
|
44
44
|
| Entry | Purpose |
|
|
45
45
|
|-------|---------|
|
|
46
|
-
| `elements-kit` | `For` and core re-exports |
|
|
47
|
-
| `elements-kit/signals` | `signal`, `computed`, `effect`, `effectScope`, `batch`, `untracked`, `trigger`, `onCleanup`, `@reactive` |
|
|
48
|
-
| `elements-kit/
|
|
49
|
-
| `elements-kit/
|
|
50
|
-
| `elements-kit/
|
|
46
|
+
| `elements-kit` | `For` component and core re-exports |
|
|
47
|
+
| `elements-kit/signals` | `signal`, `computed`, `effect`, `effectScope`, `batch`, `untracked`, `trigger`, `onCleanup`, `MaybeReactive`, `resolve`, `resolveProps`, `@reactive` |
|
|
48
|
+
| `elements-kit/render` | `render(target, setup)` — mount a node with a scoped lifetime; returns `unmount` |
|
|
49
|
+
| `elements-kit/attributes` | `@attributes` decorator + `ATTRIBUTES` symbol |
|
|
50
|
+
| `elements-kit/slot` | `Slot`, `Slots`, `SLOTS` symbol — comment-marker DOM regions |
|
|
51
|
+
| `elements-kit/custom-elements` | `defineElement`, `CustomElementRegistry` |
|
|
52
|
+
| `elements-kit/for` | `For` keyed-list component |
|
|
53
|
+
| `elements-kit/jsx-runtime` | JSX factory + type helpers (`ElementProps`, `Props`, `ComponentProps`, `MaybeReactiveProps`, `ReactiveProps`, `Require`) — configure via `jsxImportSource` |
|
|
51
54
|
| `elements-kit/integrations/react` | `useSignal`, `useScope` React bridge hooks |
|
|
52
55
|
| `elements-kit/utilities/*` | Reactive browser-API utilities — see [src/utilities/README.md](src/utilities/README.md) |
|
|
53
56
|
|
|
@@ -166,7 +169,7 @@ JSX compiles directly to `document.createElement`. No virtual DOM, no diffing.
|
|
|
166
169
|
|
|
167
170
|
```tsx
|
|
168
171
|
// This:
|
|
169
|
-
const el = <button
|
|
172
|
+
const el = <button on:click={() => count(count() + 1)}>{count}</button>;
|
|
170
173
|
|
|
171
174
|
// Is equivalent to:
|
|
172
175
|
const el = document.createElement("button");
|
|
@@ -190,8 +193,7 @@ const name = signal("Alice");
|
|
|
190
193
|
| Syntax | Effect |
|
|
191
194
|
|--------|--------|
|
|
192
195
|
| `{signal}` / `{() => fn()}` | Live-bound reactive child |
|
|
193
|
-
| `
|
|
194
|
-
| `on:click={fn}` | Explicit event namespace |
|
|
196
|
+
| `on:click={fn}` | Event listener (case-preserving event name) |
|
|
195
197
|
| `class:active={bool}` | Reactive `classList.toggle` |
|
|
196
198
|
| `style:color={value}` | Reactive inline style property |
|
|
197
199
|
| `prop:foo={val}` | Force property assignment (skips `setAttribute`) |
|
|
@@ -204,6 +206,7 @@ Any class with a `render()` method returning an `Element` is a component. Compon
|
|
|
204
206
|
|
|
205
207
|
```tsx
|
|
206
208
|
import { reactive, computed } from "elements-kit/signals";
|
|
209
|
+
import { render } from "elements-kit/render";
|
|
207
210
|
|
|
208
211
|
class Counter {
|
|
209
212
|
@reactive() count = 0;
|
|
@@ -213,13 +216,13 @@ class Counter {
|
|
|
213
216
|
return (
|
|
214
217
|
<section>
|
|
215
218
|
<p>{() => this.count} × 2 = {this.doubled}</p>
|
|
216
|
-
<button
|
|
219
|
+
<button on:click={() => this.count++}>+1</button>
|
|
217
220
|
</section>
|
|
218
221
|
) as Element;
|
|
219
222
|
}
|
|
220
223
|
}
|
|
221
224
|
|
|
222
|
-
document.getElementById("app")
|
|
225
|
+
const unmount = render(document.getElementById("app")!, () => <Counter/>);
|
|
223
226
|
```
|
|
224
227
|
|
|
225
228
|
---
|
|
@@ -228,9 +231,10 @@ document.getElementById("app")!.appendChild(new Counter().render());
|
|
|
228
231
|
|
|
229
232
|
ElementsKit enhances native `HTMLElement` subclasses — start with the platform, add only what you need.
|
|
230
233
|
|
|
231
|
-
```
|
|
234
|
+
```tsx
|
|
232
235
|
import { reactive, computed } from "elements-kit/signals";
|
|
233
236
|
import { attributes, ATTRIBUTES as attr } from "elements-kit/attributes";
|
|
237
|
+
import { render } from "elements-kit/render";
|
|
234
238
|
|
|
235
239
|
@attributes
|
|
236
240
|
class CounterElement extends HTMLElement {
|
|
@@ -243,13 +247,20 @@ class CounterElement extends HTMLElement {
|
|
|
243
247
|
@reactive() count = 0;
|
|
244
248
|
doubled = computed(() => this.count * 2);
|
|
245
249
|
|
|
250
|
+
#unmount?: () => void;
|
|
251
|
+
|
|
246
252
|
connectedCallback() {
|
|
247
|
-
this
|
|
253
|
+
this.#unmount = render(this, () => (
|
|
248
254
|
<section>
|
|
249
255
|
<p>{() => this.count} × 2 = {this.doubled}</p>
|
|
250
|
-
<button
|
|
251
|
-
</section>
|
|
252
|
-
);
|
|
256
|
+
<button on:click={() => this.count++}>+1</button>
|
|
257
|
+
</section>
|
|
258
|
+
));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
disconnectedCallback() {
|
|
262
|
+
this.#unmount?.();
|
|
263
|
+
this.#unmount = undefined;
|
|
253
264
|
}
|
|
254
265
|
}
|
|
255
266
|
|
|
@@ -258,6 +269,26 @@ customElements.define("x-counter", CounterElement);
|
|
|
258
269
|
|
|
259
270
|
`<x-counter count="5" />` — attribute bound, reactive, works in any HTML context.
|
|
260
271
|
|
|
272
|
+
### Typed JSX for custom elements
|
|
273
|
+
|
|
274
|
+
Register the tag and augment the `CustomElementRegistry` interface — JSX infers the full prop shape (attributes, events, slots, children) from the class itself.
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
import { defineElement } from "elements-kit/custom-elements";
|
|
278
|
+
|
|
279
|
+
defineElement("x-counter", CounterElement);
|
|
280
|
+
|
|
281
|
+
declare module "elements-kit/custom-elements" {
|
|
282
|
+
interface CustomElementRegistry {
|
|
283
|
+
"x-counter": typeof CounterElement;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Now `<x-counter count={5} />` is fully typed — no hand-written `declare global` block.
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
See [Types](docs/src/content/docs/elements/types.mdx) for the full set of prop-inference helpers.
|
|
291
|
+
|
|
261
292
|
---
|
|
262
293
|
|
|
263
294
|
## React Integration
|
|
@@ -408,7 +439,7 @@ effect(() => console.log(fetchTodo.state, fetchTodo.value));
|
|
|
408
439
|
|
|
409
440
|
## `For` — Keyed List Rendering
|
|
410
441
|
|
|
411
|
-
Reconciles a reactive array into the DOM. Each item renders once per key — no full re-renders on reorder, add, or remove.
|
|
442
|
+
Reconciles a reactive array into the DOM. Each item renders once per key — no full re-renders on reorder, add, or remove. `T` is inferred from `each`.
|
|
412
443
|
|
|
413
444
|
```tsx
|
|
414
445
|
import { For } from "elements-kit/for";
|
|
@@ -427,6 +458,34 @@ import { For } from "elements-kit/for";
|
|
|
427
458
|
|
|
428
459
|
---
|
|
429
460
|
|
|
461
|
+
## Prop types
|
|
462
|
+
|
|
463
|
+
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).
|
|
464
|
+
|
|
465
|
+
| Helper | For |
|
|
466
|
+
| ------ | --- |
|
|
467
|
+
| `ElementProps<typeof Cls>` | `HTMLElement` subclass — full surface (attrs, events, slots, children) |
|
|
468
|
+
| `Props<C>` | Class instance, constructor, or function component — unified |
|
|
469
|
+
| `ComponentProps<typeof Cls>` | Class components with `constructor(props: P)` |
|
|
470
|
+
| `MaybeReactiveProps<P>` | Caller-facing — wrap every prop in `MaybeReactive` (what parents pass) |
|
|
471
|
+
| `ReactiveProps<P>` | Component-facing — every prop becomes a `Computed<T>` getter (what function components receive) |
|
|
472
|
+
| `MaybeReactive<T>` | Scalar value-or-getter (from `elements-kit/signals`) |
|
|
473
|
+
| `Require<P, K>` | Promote optional keys to required |
|
|
474
|
+
|
|
475
|
+
The JSX runtime auto-wraps function-component props — each key arrives as a callable getter that subscribes on read. Pair the signature with `ReactiveProps<P>` and read `props.x()`:
|
|
476
|
+
|
|
477
|
+
```tsx
|
|
478
|
+
import type { ReactiveProps } from "elements-kit/jsx-runtime";
|
|
479
|
+
|
|
480
|
+
function Greeting(props: ReactiveProps<{ name: string }>) {
|
|
481
|
+
return <p>Hello, {props.name}</p>;
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
`resolveProps` stays exported for non-JSX call sites or nested prop bags.
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
430
489
|
## `@reactive()` Decorator
|
|
431
490
|
|
|
432
491
|
Makes any class field reactive — reads subscribe, writes trigger updates.
|
|
@@ -465,6 +524,26 @@ class MyElement extends HTMLElement {
|
|
|
465
524
|
}
|
|
466
525
|
```
|
|
467
526
|
|
|
527
|
+
For typed slots, attach a `[SLOTS]` instance field — pass the key list with `as const` so TS can narrow:
|
|
528
|
+
|
|
529
|
+
```ts
|
|
530
|
+
import { SLOTS, Slots } from "elements-kit/slot";
|
|
531
|
+
|
|
532
|
+
class Card extends HTMLElement {
|
|
533
|
+
[SLOTS] = Slots.new(["header", "footer"] as const);
|
|
534
|
+
}
|
|
535
|
+
// ElementProps<typeof Card> now includes `slot:header` / `slot:footer`
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
For typed events, declare a `static events` map:
|
|
539
|
+
|
|
540
|
+
```ts
|
|
541
|
+
class XPicker extends HTMLElement {
|
|
542
|
+
declare static events: { commit: CustomEvent<number> };
|
|
543
|
+
}
|
|
544
|
+
// ElementProps<typeof XPicker> now includes `on:commit`
|
|
545
|
+
```
|
|
546
|
+
|
|
468
547
|
---
|
|
469
548
|
|
|
470
549
|
## Roadmap
|
|
@@ -473,4 +552,3 @@ class MyElement extends HTMLElement {
|
|
|
473
552
|
- [ ] UI library — pre-built reactive components built on ElementsKit primitives
|
|
474
553
|
- [ ] More framework integrations (Vue, Solid, Angular, …)
|
|
475
554
|
- [ ] Tutorial — building a full app from scratch
|
|
476
|
-
- [ ] Complete TypeScript strict-mode coverage
|
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-aiRoArZz.mjs";
|
|
2
2
|
export { ATTRIBUTES, AttrChangeHandler, AttributeDecorated, AttributeTarget, Attributes, attributes, dispatchAttrChange, observedAttributes };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/custom-elements.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* Registry of custom-element tags to their constructors.
|
|
4
4
|
* Users augment this interface to add typed JSX support for their elements:
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
|
-
* declare module "elements-kit" {
|
|
8
|
+
* declare module "elements-kit/custom-elements" {
|
|
9
9
|
* interface CustomElementRegistry {
|
|
10
10
|
* "x-range": typeof XRange;
|
|
11
11
|
* }
|
|
@@ -1,74 +1,2 @@
|
|
|
1
|
-
import { n as defineElement, t as CustomElementRegistry } from "./
|
|
2
|
-
|
|
3
|
-
//#region src/custom-elements.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Runs `setup` inside a fresh `effectScope` and returns both its result and
|
|
6
|
-
* the scope's dispose handle.
|
|
7
|
-
*
|
|
8
|
-
* Use this wherever you need to run reactive code with an explicit lifetime
|
|
9
|
-
* outside the JSX element flow — most commonly inside a custom element's
|
|
10
|
-
* `connectedCallback`. `onCleanup`, nested `effect`s and any other
|
|
11
|
-
* scope-bound registrations made in `setup` are owned by the returned
|
|
12
|
-
* `dispose`.
|
|
13
|
-
*
|
|
14
|
-
* `untracked` detaches the new scope from any enclosing effect so it isn't
|
|
15
|
-
* torn down when that effect re-runs — its lifetime is solely the caller's
|
|
16
|
-
* responsibility.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* class Clock extends HTMLElement {
|
|
21
|
-
* #dispose?: () => void;
|
|
22
|
-
*
|
|
23
|
-
* connectedCallback() {
|
|
24
|
-
* const { dispose } = renderScope(() => {
|
|
25
|
-
* const id = setInterval(() => (this.textContent = String(Date.now())), 1000);
|
|
26
|
-
* onCleanup(() => clearInterval(id));
|
|
27
|
-
* });
|
|
28
|
-
* this.#dispose = dispose;
|
|
29
|
-
* }
|
|
30
|
-
*
|
|
31
|
-
* disconnectedCallback() {
|
|
32
|
-
* this.#dispose?.();
|
|
33
|
-
* this.#dispose = undefined;
|
|
34
|
-
* }
|
|
35
|
-
* }
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
declare function renderScope<T>(setup: () => T): {
|
|
39
|
-
result: T;
|
|
40
|
-
dispose: () => void;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Runs `setup` inside an `effectScope` tied to `el`'s connected lifetime.
|
|
44
|
-
*
|
|
45
|
-
* Call from `connectedCallback`. Effects, `onCleanup` registrations, and
|
|
46
|
-
* reactive reads inside `setup` belong to this scope. Pair with
|
|
47
|
-
* {@link disconnectedScope} from `disconnectedCallback` to dispose.
|
|
48
|
-
*
|
|
49
|
-
* Safe to call more than once (e.g. if the element is reconnected after
|
|
50
|
-
* disconnection): the previous scope is disposed first.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```ts
|
|
54
|
-
* class Clock extends HTMLElement {
|
|
55
|
-
* connectedCallback() {
|
|
56
|
-
* connectedScope(this, () => {
|
|
57
|
-
* const id = setInterval(() => this.textContent = String(Date.now()), 1000);
|
|
58
|
-
* onCleanup(() => clearInterval(id));
|
|
59
|
-
* });
|
|
60
|
-
* }
|
|
61
|
-
* disconnectedCallback() {
|
|
62
|
-
* disconnectedScope(this);
|
|
63
|
-
* }
|
|
64
|
-
* }
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
declare function connectedScope(el: HTMLElement, setup: () => void): void;
|
|
68
|
-
/**
|
|
69
|
-
* Disposes the scope previously created by {@link connectedScope} for `el`.
|
|
70
|
-
* No-op if there is no active scope.
|
|
71
|
-
*/
|
|
72
|
-
declare function disconnectedScope(el: HTMLElement): void;
|
|
73
|
-
//#endregion
|
|
74
|
-
export { type CustomElementRegistry, connectedScope, defineElement, disconnectedScope, renderScope };
|
|
1
|
+
import { n as defineElement, t as CustomElementRegistry } from "./custom-elements-bVYOkHKt.mjs";
|
|
2
|
+
export { CustomElementRegistry, defineElement };
|
package/dist/custom-elements.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/define.ts
|
|
1
|
+
//#region src/custom-elements.ts
|
|
3
2
|
/**
|
|
4
3
|
* Register a custom element with the browser and return its class.
|
|
5
4
|
* Pair with a module augmentation of `CustomElementRegistry` to get typed JSX.
|
|
@@ -9,92 +8,4 @@ function defineElement(tag, cls, options) {
|
|
|
9
8
|
return cls;
|
|
10
9
|
}
|
|
11
10
|
//#endregion
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Runs `setup` inside a fresh `effectScope` and returns both its result and
|
|
15
|
-
* the scope's dispose handle.
|
|
16
|
-
*
|
|
17
|
-
* Use this wherever you need to run reactive code with an explicit lifetime
|
|
18
|
-
* outside the JSX element flow — most commonly inside a custom element's
|
|
19
|
-
* `connectedCallback`. `onCleanup`, nested `effect`s and any other
|
|
20
|
-
* scope-bound registrations made in `setup` are owned by the returned
|
|
21
|
-
* `dispose`.
|
|
22
|
-
*
|
|
23
|
-
* `untracked` detaches the new scope from any enclosing effect so it isn't
|
|
24
|
-
* torn down when that effect re-runs — its lifetime is solely the caller's
|
|
25
|
-
* responsibility.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```ts
|
|
29
|
-
* class Clock extends HTMLElement {
|
|
30
|
-
* #dispose?: () => void;
|
|
31
|
-
*
|
|
32
|
-
* connectedCallback() {
|
|
33
|
-
* const { dispose } = renderScope(() => {
|
|
34
|
-
* const id = setInterval(() => (this.textContent = String(Date.now())), 1000);
|
|
35
|
-
* onCleanup(() => clearInterval(id));
|
|
36
|
-
* });
|
|
37
|
-
* this.#dispose = dispose;
|
|
38
|
-
* }
|
|
39
|
-
*
|
|
40
|
-
* disconnectedCallback() {
|
|
41
|
-
* this.#dispose?.();
|
|
42
|
-
* this.#dispose = undefined;
|
|
43
|
-
* }
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
function renderScope(setup) {
|
|
48
|
-
let result;
|
|
49
|
-
let dispose;
|
|
50
|
-
untracked(() => {
|
|
51
|
-
dispose = effectScope(() => {
|
|
52
|
-
result = setup();
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
return {
|
|
56
|
-
result,
|
|
57
|
-
dispose
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
const scopes = /* @__PURE__ */ new WeakMap();
|
|
61
|
-
/**
|
|
62
|
-
* Runs `setup` inside an `effectScope` tied to `el`'s connected lifetime.
|
|
63
|
-
*
|
|
64
|
-
* Call from `connectedCallback`. Effects, `onCleanup` registrations, and
|
|
65
|
-
* reactive reads inside `setup` belong to this scope. Pair with
|
|
66
|
-
* {@link disconnectedScope} from `disconnectedCallback` to dispose.
|
|
67
|
-
*
|
|
68
|
-
* Safe to call more than once (e.g. if the element is reconnected after
|
|
69
|
-
* disconnection): the previous scope is disposed first.
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```ts
|
|
73
|
-
* class Clock extends HTMLElement {
|
|
74
|
-
* connectedCallback() {
|
|
75
|
-
* connectedScope(this, () => {
|
|
76
|
-
* const id = setInterval(() => this.textContent = String(Date.now()), 1000);
|
|
77
|
-
* onCleanup(() => clearInterval(id));
|
|
78
|
-
* });
|
|
79
|
-
* }
|
|
80
|
-
* disconnectedCallback() {
|
|
81
|
-
* disconnectedScope(this);
|
|
82
|
-
* }
|
|
83
|
-
* }
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
function connectedScope(el, setup) {
|
|
87
|
-
scopes.get(el)?.();
|
|
88
|
-
const { dispose } = renderScope(setup);
|
|
89
|
-
scopes.set(el, dispose);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Disposes the scope previously created by {@link connectedScope} for `el`.
|
|
93
|
-
* No-op if there is no active scope.
|
|
94
|
-
*/
|
|
95
|
-
function disconnectedScope(el) {
|
|
96
|
-
scopes.get(el)?.();
|
|
97
|
-
scopes.delete(el);
|
|
98
|
-
}
|
|
99
|
-
//#endregion
|
|
100
|
-
export { connectedScope, defineElement, disconnectedScope, renderScope };
|
|
11
|
+
export { defineElement };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as effectScope, g as untracked, p as onCleanup, s as effect } from "./lib-D6duEs38.mjs";
|
|
2
2
|
import "./polyfill-B1lNNcum.mjs";
|
|
3
|
+
import { isReactive, resolveProps } from "./signals/index.mjs";
|
|
3
4
|
import { on } from "./utilities/event-listener.mjs";
|
|
4
5
|
import { i as resolveNode$1, n as Slot, r as Slots, t as SLOTS } from "./slot-Kb61AcgW.mjs";
|
|
5
6
|
//#region \0rolldown/runtime.js
|
|
@@ -85,23 +86,34 @@ function applySlot(slot, value) {
|
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
function mountChildren(el, value) {
|
|
88
|
-
for (const child of ensureFlatArray(value))
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
89
|
+
for (const child of ensureFlatArray(value)) mountChild(el, child);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Mounts a single child into `el`. Reactive functions become live slots; other
|
|
93
|
+
* values append as-is. Each child owns its own `effectScope` so sibling
|
|
94
|
+
* `onCleanup` registrations don't overwrite each other (the signals lib
|
|
95
|
+
* supports only one onCleanup per subscriber).
|
|
96
|
+
*
|
|
97
|
+
* Also used by `createFunctionElement` when a component returns a reactive
|
|
98
|
+
* getter or primitive — keeps the component's `effectScope` alive for the
|
|
99
|
+
* lifetime of the fragment it mounts into.
|
|
100
|
+
*/
|
|
101
|
+
function mountChild(el, child) {
|
|
102
|
+
if (typeof child === "function") {
|
|
103
|
+
const slot = Slot.new();
|
|
104
|
+
el.appendChild(slot());
|
|
105
|
+
effectScope(() => {
|
|
106
|
+
effect(() => slot.set(resolveChild(child())));
|
|
107
|
+
onCleanup(() => slot.clear());
|
|
103
108
|
});
|
|
109
|
+
return;
|
|
104
110
|
}
|
|
111
|
+
const node = resolveChild(child);
|
|
112
|
+
const dispose = node[Symbol.dispose];
|
|
113
|
+
el.appendChild(node);
|
|
114
|
+
if (dispose) effectScope(() => {
|
|
115
|
+
onCleanup(dispose);
|
|
116
|
+
});
|
|
105
117
|
}
|
|
106
118
|
function resolveChild(value) {
|
|
107
119
|
if (Array.isArray(value)) {
|
|
@@ -209,10 +221,10 @@ function setAttribute(el, key, value) {
|
|
|
209
221
|
else el.setAttribute(key, value === true ? "" : String(value));
|
|
210
222
|
}
|
|
211
223
|
function isEventKey(key) {
|
|
212
|
-
return key.startsWith("on:")
|
|
224
|
+
return key.startsWith("on:");
|
|
213
225
|
}
|
|
214
226
|
function eventName(key) {
|
|
215
|
-
return key.
|
|
227
|
+
return key.slice(3);
|
|
216
228
|
}
|
|
217
229
|
//#endregion
|
|
218
230
|
//#region src/jsx-runtime/element.ts
|
|
@@ -229,7 +241,7 @@ function createFunctionElement(type, props, ref) {
|
|
|
229
241
|
let dispose;
|
|
230
242
|
untracked(() => {
|
|
231
243
|
dispose = effectScope(() => {
|
|
232
|
-
el = type(props);
|
|
244
|
+
el = type(resolveProps(props));
|
|
233
245
|
if (typeof ref === "function" && el instanceof Element) ref(el);
|
|
234
246
|
});
|
|
235
247
|
});
|
|
@@ -280,4 +292,4 @@ function attachDisposables(el, disposables) {
|
|
|
280
292
|
});
|
|
281
293
|
}
|
|
282
294
|
//#endregion
|
|
283
|
-
export { disposeElement as n, createElement as t };
|
|
295
|
+
export { disposeElement as n, mountChild as r, createElement as t };
|
package/dist/for.d.mts
CHANGED
package/dist/for.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { n as disposeElement } from "./element-
|
|
2
|
-
import {
|
|
1
|
+
import { n as disposeElement } from "./element-DxmInKJw.mjs";
|
|
2
|
+
import { c as effectScope, g as untracked, h as trigger, m as signal, p as onCleanup, s as effect } from "./lib-D6duEs38.mjs";
|
|
3
|
+
import "./signals/index.mjs";
|
|
3
4
|
//#region src/for.ts
|
|
4
5
|
var For = class {
|
|
5
6
|
constructor(_props) {}
|