elements-kit 0.3.1 → 0.3.3
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/dist/{benchmark.CX_oY03V-COK1VBpH.mjs → benchmark.CX_oY03V-CsUg-gW0.mjs} +2 -2
- package/dist/custom-elements-D5CgfNKc.d.mts +55 -0
- package/dist/custom-elements.d.mts +1 -1
- package/dist/custom-elements.mjs +6 -4
- package/dist/{element-BjpyY6qv.mjs → element-DvqBlRly.mjs} +195 -47
- package/dist/for.d.mts +1 -1
- package/dist/for.mjs +1 -1
- package/dist/{infer-BUUWMoG9.d.mts → infer-K2Te9gn1.d.mts} +50 -38
- package/dist/integrations/react.d.mts +1 -1
- package/dist/jsx-runtime/index.d.mts +1 -1
- package/dist/jsx-runtime/index.mjs +1 -1
- package/dist/signals/index.d.mts +1 -1
- package/dist/signals/index.mjs +5 -3
- package/dist/slot-B8y0aEoz.d.mts +71 -0
- package/dist/slot-DLjSL6t1.mjs +124 -0
- package/dist/slot.d.mts +2 -2
- package/dist/slot.mjs +2 -2
- package/dist/{test.BmQO5GaM-C8YqghE0.mjs → test.BmQO5GaM-ZC2MPXQb.mjs} +4 -4
- package/dist/utilities/active-element.d.mts +1 -1
- package/dist/utilities/active-element.test.mjs +2 -2
- package/dist/utilities/async.d.mts +7 -1
- package/dist/utilities/async.mjs +6 -0
- package/dist/utilities/async.test.mjs +2 -2
- package/dist/utilities/context.test.mjs +2 -2
- package/dist/utilities/debounced.d.mts +1 -1
- package/dist/utilities/debounced.test.mjs +2 -2
- package/dist/utilities/dom-lifecycle.bench.mjs +1 -1
- package/dist/utilities/dom-lifecycle.d.mts +19 -21
- package/dist/utilities/dom-lifecycle.mjs +16 -13
- package/dist/utilities/dom-lifecycle.test.mjs +3 -2
- package/dist/utilities/element-rect.d.mts +1 -1
- package/dist/utilities/element-rect.test.mjs +2 -2
- package/dist/utilities/element-scroll.d.mts +1 -1
- package/dist/utilities/element-scroll.test.mjs +2 -2
- package/dist/utilities/event-driven.d.mts +1 -1
- package/dist/utilities/event-listener.d.mts +1 -1
- package/dist/utilities/event-listener.test.mjs +2 -2
- package/dist/utilities/focus-within.d.mts +1 -1
- package/dist/utilities/focus-within.test.mjs +2 -2
- package/dist/utilities/hover.d.mts +1 -1
- package/dist/utilities/hover.test.mjs +2 -2
- package/dist/utilities/intersection-observer.d.mts +17 -0
- package/dist/utilities/intersection-observer.mjs +17 -0
- package/dist/utilities/intersection-observer.test.mjs +2 -2
- package/dist/utilities/interval.d.mts +1 -1
- package/dist/utilities/interval.test.mjs +2 -2
- package/dist/utilities/location.d.mts +1 -1
- package/dist/utilities/location.test.mjs +2 -2
- package/dist/utilities/long-press.test.mjs +2 -2
- package/dist/utilities/media-devices.d.mts +1 -1
- package/dist/utilities/media-devices.test.mjs +2 -2
- package/dist/utilities/media-player.d.mts +1 -1
- package/dist/utilities/media-player.test.mjs +2 -2
- package/dist/utilities/media-query.d.mts +1 -1
- package/dist/utilities/mutation-observer.test.mjs +2 -2
- package/dist/utilities/network.d.mts +1 -1
- package/dist/utilities/network.test.mjs +2 -2
- package/dist/utilities/on-click-outside.test.mjs +2 -2
- package/dist/utilities/orientation.d.mts +1 -1
- package/dist/utilities/previous.d.mts +1 -1
- package/dist/utilities/previous.test.mjs +2 -2
- package/dist/utilities/promise.d.mts +1 -1
- package/dist/utilities/promise.test.mjs +2 -2
- package/dist/utilities/retry.test.mjs +2 -2
- package/dist/utilities/routing.d.mts +1 -1
- package/dist/utilities/routing.test.mjs +2 -2
- package/dist/utilities/search-params.d.mts +1 -1
- package/dist/utilities/search-params.test.mjs +2 -2
- package/dist/utilities/ssr.test.mjs +2 -2
- package/dist/utilities/storage.d.mts +1 -1
- package/dist/utilities/storage.test.mjs +2 -2
- package/dist/utilities/throttled.d.mts +1 -1
- package/dist/utilities/throttled.test.mjs +2 -2
- package/dist/utilities/timeout.d.mts +1 -1
- package/dist/utilities/timeout.test.mjs +2 -2
- package/dist/utilities/window-focus.d.mts +1 -1
- package/dist/utilities/window-size.d.mts +1 -1
- package/dist/utilities/window-size.test.mjs +2 -2
- package/package.json +1 -1
- package/dist/custom-elements-CBuenqVD.d.mts +0 -41
- package/dist/slot-BnzxFBfO.mjs +0 -198
- package/dist/slot-CfafCBOW.d.mts +0 -121
package/dist/signals/index.mjs
CHANGED
|
@@ -109,6 +109,8 @@ function resolve(value) {
|
|
|
109
109
|
* ```
|
|
110
110
|
*/
|
|
111
111
|
function resolveProps(raw) {
|
|
112
|
+
const ownKeys = Reflect.ownKeys(raw);
|
|
113
|
+
const ownKeySet = new Set(ownKeys);
|
|
112
114
|
const cache = /* @__PURE__ */ new Map();
|
|
113
115
|
const get = (key) => {
|
|
114
116
|
let getter = cache.get(key);
|
|
@@ -121,9 +123,9 @@ function resolveProps(raw) {
|
|
|
121
123
|
};
|
|
122
124
|
return new Proxy(raw, {
|
|
123
125
|
get: (_target, key) => get(key),
|
|
124
|
-
has: (_target, key) => key
|
|
125
|
-
ownKeys: (
|
|
126
|
-
getOwnPropertyDescriptor: (_target, key) => key
|
|
126
|
+
has: (_target, key) => ownKeySet.has(key),
|
|
127
|
+
ownKeys: () => ownKeys,
|
|
128
|
+
getOwnPropertyDescriptor: (_target, key) => ownKeySet.has(key) ? {
|
|
127
129
|
enumerable: true,
|
|
128
130
|
configurable: true,
|
|
129
131
|
writable: false,
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
//#region src/lib.d.ts
|
|
2
|
+
type PrimitiveNodeType = Node | string | boolean | number | bigint | symbol | Date | RegExp | null | undefined;
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region src/polyfill.d.ts
|
|
5
|
+
declare global {
|
|
6
|
+
interface SymbolConstructor {
|
|
7
|
+
readonly dispose: symbol;
|
|
8
|
+
}
|
|
9
|
+
interface Disposable {
|
|
10
|
+
[Symbol.dispose](): void;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/slot.d.ts
|
|
15
|
+
/**
|
|
16
|
+
* A lightweight slot that reserves a region in the DOM using comment markers.
|
|
17
|
+
* Content between the markers can be replaced dynamically without wrapper elements.
|
|
18
|
+
*/
|
|
19
|
+
declare class Slot {
|
|
20
|
+
#private;
|
|
21
|
+
/**
|
|
22
|
+
* Render the slot as a DocumentFragment.
|
|
23
|
+
* If not yet mounted, inserts the comment markers and optional default content.
|
|
24
|
+
* If already mounted, extracts and returns the current content WITHOUT disposing
|
|
25
|
+
* it — the caller takes ownership of the returned nodes and is responsible for
|
|
26
|
+
* their disposal.
|
|
27
|
+
*/
|
|
28
|
+
render(defaultContent?: PrimitiveNodeType): DocumentFragment;
|
|
29
|
+
/** Dispose reactive children and remove all content between the markers. */
|
|
30
|
+
clear(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Replace the slot's content with the given element.
|
|
33
|
+
* No-op if the slot is not mounted or the content is identical.
|
|
34
|
+
*/
|
|
35
|
+
set(element: Node): void;
|
|
36
|
+
/**
|
|
37
|
+
* Extract and return the current slot content as a DocumentFragment.
|
|
38
|
+
* Returns `null` if the slot is not mounted.
|
|
39
|
+
* Content is NOT disposed — the caller takes ownership and is responsible
|
|
40
|
+
* for disposal.
|
|
41
|
+
*/
|
|
42
|
+
get(): DocumentFragment | null;
|
|
43
|
+
/** Returns the parent node if the slot is mounted, otherwise `null`. */
|
|
44
|
+
parent(): ParentNode | null;
|
|
45
|
+
/** Whether the slot's comment markers are attached to the DOM. */
|
|
46
|
+
isMounted(): boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Symbol key for attaching a slot collection to a custom element instance.
|
|
50
|
+
* Prevents collisions with public Element properties and signals to the JSX
|
|
51
|
+
* runtime that this property holds slot wiring (not regular children).
|
|
52
|
+
*
|
|
53
|
+
* The value at `[SLOTS]` is a plain object whose keys are slot names and whose
|
|
54
|
+
* values are {@link Slot} instances. Declare with `as const` so TypeScript
|
|
55
|
+
* preserves the literal key union — this is what `ElementProps<typeof Cls>`
|
|
56
|
+
* uses to synthesize `slot:${K}` entries.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* class Card extends HTMLElement {
|
|
61
|
+
* // ✅ literal keys flow through — "header" | "footer"
|
|
62
|
+
* [SLOTS] = { header: new Slot(), footer: new Slot() } as const;
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* // ❌ widens — no typed slot:* props
|
|
66
|
+
* // [SLOTS] = { header: new Slot(), footer: new Slot() };
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
declare const SLOTS: unique symbol;
|
|
70
|
+
//#endregion
|
|
71
|
+
export { Slot as n, PrimitiveNodeType as r, SLOTS as t };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import "./polyfill-CdZVCxdo.mjs";
|
|
2
|
+
//#region src/lib.ts
|
|
3
|
+
var UnsupportedChildError = class extends Error {
|
|
4
|
+
constructor(value) {
|
|
5
|
+
super(`Unsupported child type: ${typeof value}`);
|
|
6
|
+
this.name = "UnsupportedChildError";
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
function resolveNode(c) {
|
|
10
|
+
if (c instanceof Node) return c;
|
|
11
|
+
if (c === null || c === void 0 || typeof c === "boolean") return document.createComment("");
|
|
12
|
+
if (typeof c === "string" || typeof c === "number" || typeof c === "bigint" || typeof c === "symbol" || c instanceof Date || c instanceof RegExp) return document.createTextNode(String(c));
|
|
13
|
+
throw new UnsupportedChildError(c);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/slot.ts
|
|
17
|
+
/**
|
|
18
|
+
* A lightweight slot that reserves a region in the DOM using comment markers.
|
|
19
|
+
* Content between the markers can be replaced dynamically without wrapper elements.
|
|
20
|
+
*/
|
|
21
|
+
var Slot = class {
|
|
22
|
+
#start = document.createComment("{");
|
|
23
|
+
#end = document.createComment("}");
|
|
24
|
+
#pending;
|
|
25
|
+
/**
|
|
26
|
+
* Render the slot as a DocumentFragment.
|
|
27
|
+
* If not yet mounted, inserts the comment markers and optional default content.
|
|
28
|
+
* If already mounted, extracts and returns the current content WITHOUT disposing
|
|
29
|
+
* it — the caller takes ownership of the returned nodes and is responsible for
|
|
30
|
+
* their disposal.
|
|
31
|
+
*/
|
|
32
|
+
render(defaultContent) {
|
|
33
|
+
const fragment = document.createDocumentFragment();
|
|
34
|
+
if (this.isMounted()) {
|
|
35
|
+
const range = document.createRange();
|
|
36
|
+
range.setStartAfter(this.#start);
|
|
37
|
+
range.setEndBefore(this.#end);
|
|
38
|
+
fragment.appendChild(range.extractContents());
|
|
39
|
+
return fragment;
|
|
40
|
+
}
|
|
41
|
+
fragment.appendChild(this.#start);
|
|
42
|
+
fragment.appendChild(this.#end);
|
|
43
|
+
const initialContent = this.#pending ?? resolveNode(defaultContent);
|
|
44
|
+
if (initialContent) fragment.insertBefore(initialContent, this.#end);
|
|
45
|
+
this.#pending = void 0;
|
|
46
|
+
return fragment;
|
|
47
|
+
}
|
|
48
|
+
/** Dispose reactive children and remove all content between the markers. */
|
|
49
|
+
clear() {
|
|
50
|
+
let node = this.#start.nextSibling;
|
|
51
|
+
while (node && node !== this.#end) {
|
|
52
|
+
const next = node.nextSibling;
|
|
53
|
+
if (node instanceof Element) node[Symbol.dispose]?.();
|
|
54
|
+
node = next;
|
|
55
|
+
}
|
|
56
|
+
const range = document.createRange();
|
|
57
|
+
range.setStartAfter(this.#start);
|
|
58
|
+
range.setEndBefore(this.#end);
|
|
59
|
+
range.deleteContents();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Replace the slot's content with the given element.
|
|
63
|
+
* No-op if the slot is not mounted or the content is identical.
|
|
64
|
+
*/
|
|
65
|
+
set(element) {
|
|
66
|
+
const parent = this.parent();
|
|
67
|
+
if (!parent) {
|
|
68
|
+
this.#pending = element;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (this.#isSame(element)) return;
|
|
72
|
+
this.clear();
|
|
73
|
+
parent.insertBefore(element, this.#end);
|
|
74
|
+
this.#pending = void 0;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Extract and return the current slot content as a DocumentFragment.
|
|
78
|
+
* Returns `null` if the slot is not mounted.
|
|
79
|
+
* Content is NOT disposed — the caller takes ownership and is responsible
|
|
80
|
+
* for disposal.
|
|
81
|
+
*/
|
|
82
|
+
get() {
|
|
83
|
+
if (!this.isMounted()) return null;
|
|
84
|
+
const range = document.createRange();
|
|
85
|
+
range.setStartAfter(this.#start);
|
|
86
|
+
range.setEndBefore(this.#end);
|
|
87
|
+
return range.extractContents();
|
|
88
|
+
}
|
|
89
|
+
/** Returns the parent node if the slot is mounted, otherwise `null`. */
|
|
90
|
+
parent() {
|
|
91
|
+
return this.isMounted() ? this.#start.parentNode : null;
|
|
92
|
+
}
|
|
93
|
+
/** Whether the slot's comment markers are attached to the DOM. */
|
|
94
|
+
isMounted() {
|
|
95
|
+
return this.#start.parentNode === this.#end.parentNode && !!this.#start.parentNode;
|
|
96
|
+
}
|
|
97
|
+
#isSame(element) {
|
|
98
|
+
return this.#start.nextSibling === element && this.#end === element.nextSibling;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Symbol key for attaching a slot collection to a custom element instance.
|
|
103
|
+
* Prevents collisions with public Element properties and signals to the JSX
|
|
104
|
+
* runtime that this property holds slot wiring (not regular children).
|
|
105
|
+
*
|
|
106
|
+
* The value at `[SLOTS]` is a plain object whose keys are slot names and whose
|
|
107
|
+
* values are {@link Slot} instances. Declare with `as const` so TypeScript
|
|
108
|
+
* preserves the literal key union — this is what `ElementProps<typeof Cls>`
|
|
109
|
+
* uses to synthesize `slot:${K}` entries.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* class Card extends HTMLElement {
|
|
114
|
+
* // ✅ literal keys flow through — "header" | "footer"
|
|
115
|
+
* [SLOTS] = { header: new Slot(), footer: new Slot() } as const;
|
|
116
|
+
* }
|
|
117
|
+
*
|
|
118
|
+
* // ❌ widens — no typed slot:* props
|
|
119
|
+
* // [SLOTS] = { header: new Slot(), footer: new Slot() };
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
const SLOTS = Symbol("slots");
|
|
123
|
+
//#endregion
|
|
124
|
+
export { Slot as n, resolveNode as r, SLOTS as t };
|
package/dist/slot.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { SLOTS, Slot
|
|
1
|
+
import { n as Slot, t as SLOTS } from "./slot-B8y0aEoz.mjs";
|
|
2
|
+
export { SLOTS, Slot };
|
package/dist/slot.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as Slot,
|
|
2
|
-
export { SLOTS, Slot
|
|
1
|
+
import { n as Slot, t as SLOTS } from "./slot-DLjSL6t1.mjs";
|
|
2
|
+
export { SLOTS, Slot };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as plugins, C as getCallLastIndex, D as ordinal, E as noop, O as stringify, S as createSimpleStackTrace, T as isObject, _ as getSafeTimers, a as waitForImportsToResolve, b as printDiffOrStringify, d as getNames, g as delay, h as parseSingleStack, i as resetModules, j as y, k as format, m as parseErrorStacktrace, n as getWorkerState, r as isChildProcess, u as getCurrentTest, v as processError, w as getType, x as assertTypes, y as diff } from "./benchmark.CX_oY03V-
|
|
1
|
+
import { A as plugins, C as getCallLastIndex, D as ordinal, E as noop, O as stringify, S as createSimpleStackTrace, T as isObject, _ as getSafeTimers, a as waitForImportsToResolve, b as printDiffOrStringify, d as getNames, g as delay, h as parseSingleStack, i as resetModules, j as y, k as format, m as parseErrorStacktrace, n as getWorkerState, r as isChildProcess, u as getCurrentTest, v as processError, w as getType, x as assertTypes, y as diff } from "./benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
2
2
|
//#region node_modules/.pnpm/@vitest+spy@4.1.3/node_modules/@vitest/spy/dist/index.js
|
|
3
3
|
function isMockFunction(fn) {
|
|
4
4
|
return typeof fn === "function" && "_isMockFunction" in fn && fn._isMockFunction === true;
|
|
@@ -4735,10 +4735,10 @@ function offsetToLineNumber(source, offset) {
|
|
|
4735
4735
|
return line + 1;
|
|
4736
4736
|
}
|
|
4737
4737
|
//#endregion
|
|
4738
|
-
//#region node_modules/.pnpm/vitest@4.1.3_@types+node@25.5.2_happy-dom@20.8.
|
|
4738
|
+
//#region node_modules/.pnpm/vitest@4.1.3_@types+node@25.5.2_happy-dom@20.8.9_vite@8.0.8_@types+node@25.5.2_esbuild@0.27.7_/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js
|
|
4739
4739
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
4740
4740
|
//#endregion
|
|
4741
|
-
//#region node_modules/.pnpm/vitest@4.1.3_@types+node@25.5.2_happy-dom@20.8.
|
|
4741
|
+
//#region node_modules/.pnpm/vitest@4.1.3_@types+node@25.5.2_happy-dom@20.8.9_vite@8.0.8_@types+node@25.5.2_esbuild@0.27.7_/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js
|
|
4742
4742
|
const RealDate = Date;
|
|
4743
4743
|
let now = null;
|
|
4744
4744
|
var MockDate = class MockDate extends RealDate {
|
|
@@ -5506,7 +5506,7 @@ var SnapshotClient = class {
|
|
|
5506
5506
|
}
|
|
5507
5507
|
};
|
|
5508
5508
|
//#endregion
|
|
5509
|
-
//#region node_modules/.pnpm/vitest@4.1.3_@types+node@25.5.2_happy-dom@20.8.
|
|
5509
|
+
//#region node_modules/.pnpm/vitest@4.1.3_@types+node@25.5.2_happy-dom@20.8.9_vite@8.0.8_@types+node@25.5.2_esbuild@0.27.7_/node_modules/vitest/dist/chunks/test.BmQO5GaM.js
|
|
5510
5510
|
var fakeTimersSrc = {};
|
|
5511
5511
|
var global$1;
|
|
5512
5512
|
var hasRequiredGlobal;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as it, l as describe } from "../benchmark.CX_oY03V-
|
|
2
|
-
import { t as globalExpect } from "../test.BmQO5GaM-
|
|
1
|
+
import { f as it, l as describe } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
2
|
+
import { t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
3
3
|
import { activeElement } from "./active-element.mjs";
|
|
4
4
|
//#region src/utilities/active-element.test.ts
|
|
5
5
|
describe("activeElement (singleton)", () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as MaybeReactive } from "../infer-
|
|
1
|
+
import { b as MaybeReactive } from "../infer-K2Te9gn1.mjs";
|
|
2
2
|
import { ComputedPromise } from "./promise.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utilities/async.d.ts
|
|
@@ -9,6 +9,12 @@ type Fn<TInput, TOutput> = (input: TInput) => Promise<TOutput>;
|
|
|
9
9
|
* reactive signals (`state`, `value`, `reason`, `result`, `pending`) and
|
|
10
10
|
* lets you `run`/`start`/`stop` the underlying task imperatively.
|
|
11
11
|
*
|
|
12
|
+
* Trigger choice: `start()` tracks the body and re-runs when its parameter
|
|
13
|
+
* signals change — right for "fetch X whenever `id` changes". `run()` is
|
|
14
|
+
* one-shot and untracked — right for externally-driven loads (intersection,
|
|
15
|
+
* click, form submit), especially when the body writes to the same signals
|
|
16
|
+
* it reads (`start()` would cascade).
|
|
17
|
+
*
|
|
12
18
|
* Prefer the {@link async} factory — it returns an `Async` that is also
|
|
13
19
|
* callable as a signal (`op()` === `op.result`), which is what most call
|
|
14
20
|
* sites want. Use this class directly only when you need the object form.
|
package/dist/utilities/async.mjs
CHANGED
|
@@ -7,6 +7,12 @@ import { promise } from "./promise.mjs";
|
|
|
7
7
|
* reactive signals (`state`, `value`, `reason`, `result`, `pending`) and
|
|
8
8
|
* lets you `run`/`start`/`stop` the underlying task imperatively.
|
|
9
9
|
*
|
|
10
|
+
* Trigger choice: `start()` tracks the body and re-runs when its parameter
|
|
11
|
+
* signals change — right for "fetch X whenever `id` changes". `run()` is
|
|
12
|
+
* one-shot and untracked — right for externally-driven loads (intersection,
|
|
13
|
+
* click, form submit), especially when the body writes to the same signals
|
|
14
|
+
* it reads (`start()` would cascade).
|
|
15
|
+
*
|
|
10
16
|
* Prefer the {@link async} factory — it returns an `Async` that is also
|
|
11
17
|
* callable as a signal (`op()` === `op.result`), which is what most call
|
|
12
18
|
* sites want. Use this class directly only when you need the object form.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { m as signal, p as onCleanup, s as effect } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { f as it, l as describe } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { f as it, l as describe } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { Async, async } from "./async.mjs";
|
|
6
6
|
import { createInterval } from "./interval.mjs";
|
|
7
7
|
//#region src/utilities/async.test.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as effectScope, m as signal, s as effect } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { getContext, setContext } from "./context.mjs";
|
|
6
6
|
//#region src/utilities/context.test.ts
|
|
7
7
|
afterEach(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as effectScope, m as signal } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { c as beforeEach, f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { c as beforeEach, f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { createDebounced } from "./debounced.mjs";
|
|
6
6
|
//#region src/utilities/debounced.test.ts
|
|
7
7
|
beforeEach(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as describe, t as bench } from "../benchmark.CX_oY03V-
|
|
1
|
+
import { l as describe, t as bench } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
2
2
|
//#region src/utilities/dom-lifecycle.bench.ts
|
|
3
3
|
describe("dom-lifecycle — registration cost", () => {
|
|
4
4
|
bench("register 100 entries on already-connected elements", () => {
|
|
@@ -34,19 +34,9 @@ type AdoptedCallback = (oldDocument: Document, newDocument: Document) => void;
|
|
|
34
34
|
* place the lifecycle element where those selectors don't reach if needed.)
|
|
35
35
|
*
|
|
36
36
|
* @example
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* onConnect={(el) => el.parentElement?.classList.add("ready")}
|
|
41
|
-
* onDisconnect={(el) => {
|
|
42
|
-
* // el.parentElement is null here per spec — stash from onConnect if needed
|
|
43
|
-
* }}
|
|
44
|
-
* />
|
|
45
|
-
* </div>
|
|
46
|
-
* ```
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* Wrap children — read the wrapped subtree via `firstElementChild`:
|
|
37
|
+
* Canonical form — wrap the subtree the lifecycle owns. `onConnect` runs
|
|
38
|
+
* inside an `effectScope` tied to the wrapped subtree, so observers, context
|
|
39
|
+
* lookups, and `onCleanup` registrations clean up on disconnect.
|
|
50
40
|
* ```tsx
|
|
51
41
|
* <section>
|
|
52
42
|
* <dom-lifecycle onConnect={(el) => measure(el.firstElementChild)}>
|
|
@@ -55,6 +45,19 @@ type AdoptedCallback = (oldDocument: Document, newDocument: Document) => void;
|
|
|
55
45
|
* </dom-lifecycle>
|
|
56
46
|
* </section>
|
|
57
47
|
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* Sibling form — fallback for cases where the host element is already
|
|
51
|
+
* present for layout reasons and you only need lifecycle on the surrounding
|
|
52
|
+
* element. Read `self.parentElement` for the host; capture it in `onConnect`
|
|
53
|
+
* if you need it on disconnect (the spec nulls it before `onDisconnect`).
|
|
54
|
+
* ```tsx
|
|
55
|
+
* <div>
|
|
56
|
+
* <dom-lifecycle
|
|
57
|
+
* onConnect={(el) => el.parentElement?.classList.add("ready")}
|
|
58
|
+
* />
|
|
59
|
+
* </div>
|
|
60
|
+
* ```
|
|
58
61
|
*/
|
|
59
62
|
declare class DomLifecycleElement extends HTMLElement {
|
|
60
63
|
#private;
|
|
@@ -72,14 +75,9 @@ declare class DomLifecycleElement extends HTMLElement {
|
|
|
72
75
|
adoptedCallback(oldDocument: Document, newDocument: Document): void;
|
|
73
76
|
}
|
|
74
77
|
declare global {
|
|
75
|
-
namespace
|
|
76
|
-
interface
|
|
77
|
-
"dom-lifecycle":
|
|
78
|
-
onConnect?: LifecycleCallback;
|
|
79
|
-
onDisconnect?: LifecycleCallback;
|
|
80
|
-
onMove?: LifecycleCallback;
|
|
81
|
-
onAdopted?: AdoptedCallback;
|
|
82
|
-
};
|
|
78
|
+
namespace ElementsKit {
|
|
79
|
+
interface CustomElementRegistry {
|
|
80
|
+
"dom-lifecycle": typeof DomLifecycleElement;
|
|
83
81
|
}
|
|
84
82
|
}
|
|
85
83
|
}
|
|
@@ -35,19 +35,9 @@ import { isBrowser } from "./environment.mjs";
|
|
|
35
35
|
* place the lifecycle element where those selectors don't reach if needed.)
|
|
36
36
|
*
|
|
37
37
|
* @example
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* onConnect={(el) => el.parentElement?.classList.add("ready")}
|
|
42
|
-
* onDisconnect={(el) => {
|
|
43
|
-
* // el.parentElement is null here per spec — stash from onConnect if needed
|
|
44
|
-
* }}
|
|
45
|
-
* />
|
|
46
|
-
* </div>
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* Wrap children — read the wrapped subtree via `firstElementChild`:
|
|
38
|
+
* Canonical form — wrap the subtree the lifecycle owns. `onConnect` runs
|
|
39
|
+
* inside an `effectScope` tied to the wrapped subtree, so observers, context
|
|
40
|
+
* lookups, and `onCleanup` registrations clean up on disconnect.
|
|
51
41
|
* ```tsx
|
|
52
42
|
* <section>
|
|
53
43
|
* <dom-lifecycle onConnect={(el) => measure(el.firstElementChild)}>
|
|
@@ -56,6 +46,19 @@ import { isBrowser } from "./environment.mjs";
|
|
|
56
46
|
* </dom-lifecycle>
|
|
57
47
|
* </section>
|
|
58
48
|
* ```
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* Sibling form — fallback for cases where the host element is already
|
|
52
|
+
* present for layout reasons and you only need lifecycle on the surrounding
|
|
53
|
+
* element. Read `self.parentElement` for the host; capture it in `onConnect`
|
|
54
|
+
* if you need it on disconnect (the spec nulls it before `onDisconnect`).
|
|
55
|
+
* ```tsx
|
|
56
|
+
* <div>
|
|
57
|
+
* <dom-lifecycle
|
|
58
|
+
* onConnect={(el) => el.parentElement?.classList.add("ready")}
|
|
59
|
+
* />
|
|
60
|
+
* </div>
|
|
61
|
+
* ```
|
|
59
62
|
*/
|
|
60
63
|
var DomLifecycleElement = class extends HTMLElement {
|
|
61
64
|
#onConnect = null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
2
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
1
|
+
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
2
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
3
3
|
import { DomLifecycleElement } from "./dom-lifecycle.mjs";
|
|
4
4
|
//#region src/utilities/dom-lifecycle.test.ts
|
|
5
5
|
afterEach(() => {
|
|
@@ -193,6 +193,7 @@ describe("dom-lifecycle", () => {
|
|
|
193
193
|
});
|
|
194
194
|
it("applies render-inert defaults: display:contents and role='none'", () => {
|
|
195
195
|
const probe = makeProbe();
|
|
196
|
+
document.body.appendChild(probe);
|
|
196
197
|
globalExpect(probe.style.display).toBe("contents");
|
|
197
198
|
globalExpect(probe.getAttribute("role")).toBe("none");
|
|
198
199
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as effectScope } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { createElementRect } from "./element-rect.mjs";
|
|
6
6
|
//#region src/utilities/element-rect.test.ts
|
|
7
7
|
afterEach(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as effectScope } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { f as it, l as describe } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { f as it, l as describe } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { createElementScroll } from "./element-scroll.mjs";
|
|
6
6
|
//#region src/utilities/element-scroll.test.ts
|
|
7
7
|
describe("createElementScroll", () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { c as effectScope, m as signal, s as effect } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
3
|
import { on } from "./event-listener.mjs";
|
|
4
|
-
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
5
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
4
|
+
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
5
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
6
6
|
//#region src/utilities/event-listener.test.ts
|
|
7
7
|
afterEach(() => {
|
|
8
8
|
document.body.innerHTML = "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as effectScope } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { createFocusWithin } from "./focus-within.mjs";
|
|
6
6
|
//#region src/utilities/focus-within.test.ts
|
|
7
7
|
afterEach(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as effectScope } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { createHover } from "./hover.mjs";
|
|
6
6
|
//#region src/utilities/hover.test.ts
|
|
7
7
|
afterEach(() => {
|
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Raw `IntersectionObserver` wrapper with automatic cleanup.
|
|
4
4
|
* Use `createIsInViewport` for the common boolean case.
|
|
5
|
+
*
|
|
6
|
+
* The platform default is `root: null`, which observes intersections with
|
|
7
|
+
* the **viewport** — not with `target`'s nearest scrollable ancestor. For a
|
|
8
|
+
* sentinel inside an in-page scroll container, pass `root: containerEl`
|
|
9
|
+
* explicitly; otherwise the sentinel reads as "intersecting" the viewport
|
|
10
|
+
* and fires immediately and repeatedly.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* // In-page scroll container — pass `root` so intersection is computed
|
|
15
|
+
* // against the container's scrollport, not the viewport.
|
|
16
|
+
* createIntersectionObserver(
|
|
17
|
+
* sentinelEl,
|
|
18
|
+
* ([entry]) => { if (entry.isIntersecting) loadMore.run(); },
|
|
19
|
+
* { root: containerEl, rootMargin: "100px" },
|
|
20
|
+
* );
|
|
21
|
+
* ```
|
|
5
22
|
*/
|
|
6
23
|
declare function createIntersectionObserver(target: Element, callback: IntersectionObserverCallback, options?: IntersectionObserverInit): Disposable;
|
|
7
24
|
//#endregion
|
|
@@ -3,6 +3,23 @@ import { observe } from "./_observe.mjs";
|
|
|
3
3
|
/**
|
|
4
4
|
* Raw `IntersectionObserver` wrapper with automatic cleanup.
|
|
5
5
|
* Use `createIsInViewport` for the common boolean case.
|
|
6
|
+
*
|
|
7
|
+
* The platform default is `root: null`, which observes intersections with
|
|
8
|
+
* the **viewport** — not with `target`'s nearest scrollable ancestor. For a
|
|
9
|
+
* sentinel inside an in-page scroll container, pass `root: containerEl`
|
|
10
|
+
* explicitly; otherwise the sentinel reads as "intersecting" the viewport
|
|
11
|
+
* and fires immediately and repeatedly.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // In-page scroll container — pass `root` so intersection is computed
|
|
16
|
+
* // against the container's scrollport, not the viewport.
|
|
17
|
+
* createIntersectionObserver(
|
|
18
|
+
* sentinelEl,
|
|
19
|
+
* ([entry]) => { if (entry.isIntersecting) loadMore.run(); },
|
|
20
|
+
* { root: containerEl, rootMargin: "100px" },
|
|
21
|
+
* );
|
|
22
|
+
* ```
|
|
6
23
|
*/
|
|
7
24
|
function createIntersectionObserver(target, callback, options) {
|
|
8
25
|
return observe(new IntersectionObserver(callback, options), (o) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as effectScope } from "../lib-CVfOddra.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-
|
|
4
|
-
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-
|
|
3
|
+
import { f as it, l as describe, o as afterEach } from "../benchmark.CX_oY03V-CsUg-gW0.mjs";
|
|
4
|
+
import { n as vi, t as globalExpect } from "../test.BmQO5GaM-ZC2MPXQb.mjs";
|
|
5
5
|
import { createIntersectionObserver } from "./intersection-observer.mjs";
|
|
6
6
|
//#region src/utilities/intersection-observer.test.ts
|
|
7
7
|
afterEach(() => {
|