elements-kit 0.22.0 → 0.23.0
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/LICENSE +201 -21
- package/README.md +30 -13
- package/dist/await.d.mts +1 -1
- package/dist/await.mjs +4 -6
- package/dist/children-BbHF-Dew.d.mts +253 -0
- package/dist/{element-Di0PYFX1.mjs → element-w3nDE2S5.mjs} +2 -2
- package/dist/environment-Fg46vL6e.d.mts +19 -0
- package/dist/for.d.mts +1 -1
- package/dist/for.mjs +1 -1
- package/dist/{fragment-Bvs1sGu1.mjs → fragment-DEhI5x0f.mjs} +2 -3
- package/dist/hydrate/index.mjs +1 -1
- package/dist/{hydrate-CHomBRY9.mjs → hydrate-CrVzu88K.mjs} +5 -5
- package/dist/index-BR8XVkck.d.mts +392 -0
- package/dist/integrations/astro-client.mjs +2 -2
- package/dist/integrations/astro-server.mjs +3 -4
- package/dist/integrations/astro-slots.mjs +2 -2
- package/dist/integrations/react.d.mts +1 -1
- package/dist/jsx-runtime/index.d.mts +3 -2
- package/dist/jsx-runtime/index.mjs +2 -2
- package/dist/server/index.mjs +1 -1
- package/dist/{server-CTkyXTV6.mjs → server-D7ffi7b_.mjs} +4 -4
- package/dist/signals/index.d.mts +2 -2
- package/dist/signals/index.mjs +30 -20
- package/dist/ui/otp-input/index.d.mts +5 -4
- package/dist/ui/otp-input/index.mjs +5 -5
- 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/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 +1 -1
- package/dist/children-s3nFjpLA.d.mts +0 -581
- /package/dist/{polyfill-BVNd6ogU.d.mts → polyfill-C-CxgMqq.d.mts} +0 -0
package/dist/signals/index.mjs
CHANGED
|
@@ -75,42 +75,48 @@ function reactive(source) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
* Resolve a {@link MaybeReactive} to its current value. Calls the getter
|
|
79
|
-
*
|
|
78
|
+
* Resolve a {@link MaybeReactive} to its current value. Calls the getter when
|
|
79
|
+
* reactive (a `signal` or `computed`); returns the value as-is otherwise — an
|
|
80
|
+
* unbranded function is a value, not a source, so a callback survives intact.
|
|
81
|
+
*
|
|
82
|
+
* This is how a function component reads a prop it declared `MaybeReactive`:
|
|
83
|
+
* the runtime hands props over exactly as the caller wrote them, so the value
|
|
84
|
+
* may be either form. Reading inside an effect or a JSX getter subscribes.
|
|
80
85
|
*
|
|
81
86
|
* @example
|
|
82
87
|
* ```ts
|
|
83
|
-
* resolve(5);
|
|
84
|
-
* resolve(
|
|
88
|
+
* resolve(5); // 5
|
|
89
|
+
* resolve(count); // current count value — signal
|
|
90
|
+
* resolve(props.label); // current value, whichever form the caller passed
|
|
91
|
+
* resolve(() => 5); // the function itself — unbranded, so not a source
|
|
85
92
|
* ```
|
|
86
93
|
*/
|
|
87
94
|
function resolve(value) {
|
|
88
95
|
return isReactive(value) ? value() : value;
|
|
89
96
|
}
|
|
97
|
+
const COMPUTED_PROPS = Symbol.for("elements-kit.computed-props");
|
|
90
98
|
/**
|
|
91
|
-
* Turn
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
99
|
+
* Turn props into a bag of per-key getters, so a body reads one shape no matter
|
|
100
|
+
* which form the caller passed. Opt-in: the JSX runtime hands function
|
|
101
|
+
* components their props untouched.
|
|
102
|
+
*
|
|
103
|
+
* Every key is callable, including one the caller omitted. A getter is always
|
|
104
|
+
* truthy, so defaults go on the call: `props.excited() ?? "…"`. Read a bag by
|
|
105
|
+
* calling the key — {@link resolve} is for raw props.
|
|
96
106
|
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
107
|
+
* Function props are the limit: a prop taking arguments is rejected, and a
|
|
108
|
+
* zero-arg one types as its return value. Read those off the raw props.
|
|
99
109
|
*
|
|
100
110
|
* @example
|
|
101
111
|
* ```ts
|
|
102
|
-
* import { resolveProps } from "elements-kit/signals";
|
|
103
|
-
* import { signal } from "elements-kit/signals";
|
|
104
|
-
*
|
|
105
112
|
* const count = signal(0);
|
|
106
|
-
* const props =
|
|
113
|
+
* const props = computedProps({ count, label: "n" });
|
|
107
114
|
* props.count(); // 0 — subscribes to count
|
|
108
115
|
* props.label(); // "n"
|
|
109
116
|
* ```
|
|
110
117
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (raw[RESOLVED_PROPS]) return raw;
|
|
118
|
+
function computedProps(raw) {
|
|
119
|
+
if (raw[COMPUTED_PROPS]) return raw;
|
|
114
120
|
const ownKeys = Reflect.ownKeys(raw);
|
|
115
121
|
const ownKeySet = new Set(ownKeys);
|
|
116
122
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -124,7 +130,11 @@ function resolveProps(raw) {
|
|
|
124
130
|
return getter;
|
|
125
131
|
};
|
|
126
132
|
return new Proxy(raw, {
|
|
127
|
-
get: (
|
|
133
|
+
get: (target, key, receiver) => {
|
|
134
|
+
if (key === COMPUTED_PROPS) return true;
|
|
135
|
+
if (!ownKeySet.has(key) && (typeof key === "symbol" || key in target || key === "toJSON")) return Reflect.get(target, key, receiver);
|
|
136
|
+
return get(key);
|
|
137
|
+
},
|
|
128
138
|
has: (_target, key) => ownKeySet.has(key),
|
|
129
139
|
ownKeys: () => ownKeys,
|
|
130
140
|
getOwnPropertyDescriptor: (_target, key) => ownKeySet.has(key) ? {
|
|
@@ -136,4 +146,4 @@ function resolveProps(raw) {
|
|
|
136
146
|
});
|
|
137
147
|
}
|
|
138
148
|
//#endregion
|
|
139
|
-
export { CLAIM, COMPUTED, EFFECT, EFFECT_SCOPE, SEED, SIGNAL, batch, computed, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve,
|
|
149
|
+
export { CLAIM, COMPUTED, EFFECT, EFFECT_SCOPE, SEED, SIGNAL, batch, computed, computedProps, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve, signal, trigger, untracked };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { n as AttrChangeHandler, t as ATTRIBUTES } from "../../attributes-DILeh3-s.mjs";
|
|
2
|
+
import { t as HTMLElementBase } from "../../environment-Fg46vL6e.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/ui/otp-input/otp-input.d.ts
|
|
4
5
|
/**
|
|
@@ -30,7 +31,7 @@ import { n as AttrChangeHandler, t as ATTRIBUTES } from "../../attributes-DILeh3
|
|
|
30
31
|
* </x-otp-input>
|
|
31
32
|
* ```
|
|
32
33
|
*/
|
|
33
|
-
declare class XOtpInput extends
|
|
34
|
+
declare class XOtpInput extends HTMLElementBase {
|
|
34
35
|
#private;
|
|
35
36
|
static formAssociated: boolean;
|
|
36
37
|
static [ATTRIBUTES]: {
|
|
@@ -82,7 +83,7 @@ declare global {
|
|
|
82
83
|
* `<x-otp-input>` paints its character and active / caret / disabled state by
|
|
83
84
|
* index; all styling lives in the companion CSS.
|
|
84
85
|
*/
|
|
85
|
-
declare class XOtpSlot extends
|
|
86
|
+
declare class XOtpSlot extends HTMLElementBase {
|
|
86
87
|
static [ATTRIBUTES]: {
|
|
87
88
|
index: AttrChangeHandler<XOtpSlot>;
|
|
88
89
|
};
|
|
@@ -102,7 +103,7 @@ declare global {
|
|
|
102
103
|
* `<x-otp-slot>`s into one attached group. All layout lives in CSS; this only
|
|
103
104
|
* applies a `group` role so the visual grouping is exposed to assistive tech.
|
|
104
105
|
*/
|
|
105
|
-
declare class XOtpGroup extends
|
|
106
|
+
declare class XOtpGroup extends HTMLElementBase {
|
|
106
107
|
connectedCallback(): void;
|
|
107
108
|
}
|
|
108
109
|
declare global {
|
|
@@ -118,7 +119,7 @@ declare global {
|
|
|
118
119
|
* `<x-otp-separator>` — decorative divider authored between OTP groups (e.g. a
|
|
119
120
|
* dash between a 3-3 split). Purely visual: `aria-hidden`, glyph drawn in CSS.
|
|
120
121
|
*/
|
|
121
|
-
declare class XOtpSeparator extends
|
|
122
|
+
declare class XOtpSeparator extends HTMLElementBase {
|
|
122
123
|
connectedCallback(): void;
|
|
123
124
|
}
|
|
124
125
|
declare global {
|
|
@@ -3,7 +3,7 @@ import { l as computed, u as effect, x as signal } from "../../lib-DYypKhxk.mjs"
|
|
|
3
3
|
import "../../signals/index.mjs";
|
|
4
4
|
import { on } from "../../utilities/event-listener.mjs";
|
|
5
5
|
import { render } from "../../render.mjs";
|
|
6
|
-
import { isBrowser } from "../../utilities/environment.mjs";
|
|
6
|
+
import { HTMLElementBase, isBrowser } from "../../utilities/environment.mjs";
|
|
7
7
|
//#region src/ui/otp-input/otp-input.shadow.css?inline
|
|
8
8
|
var otp_input_shadow_default = ".x-otp-input__field {\n color: #0000;\n caret-color: #0000;\n width: 100%;\n height: 100%;\n font: inherit;\n letter-spacing: inherit;\n pointer-events: auto;\n background: none;\n border: 0;\n outline: none;\n margin: 0;\n padding: 0;\n position: absolute;\n inset: 0;\n}\n\n.x-otp-input__field::selection {\n color: #0000;\n background-color: #0000;\n}\n";
|
|
9
9
|
//#endregion
|
|
@@ -43,7 +43,7 @@ SHADOW_SHEET?.replaceSync(otp_input_shadow_default);
|
|
|
43
43
|
* </x-otp-input>
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
|
-
var XOtpInput = class XOtpInput extends
|
|
46
|
+
var XOtpInput = class XOtpInput extends HTMLElementBase {
|
|
47
47
|
static formAssociated = true;
|
|
48
48
|
static [ATTRIBUTES] = {
|
|
49
49
|
value(value) {
|
|
@@ -293,7 +293,7 @@ if (isBrowser && !customElements.get("x-otp-input")) customElements.define("x-ot
|
|
|
293
293
|
* `<x-otp-input>` paints its character and active / caret / disabled state by
|
|
294
294
|
* index; all styling lives in the companion CSS.
|
|
295
295
|
*/
|
|
296
|
-
var XOtpSlot = class extends
|
|
296
|
+
var XOtpSlot = class extends HTMLElementBase {
|
|
297
297
|
connectedCallback() {
|
|
298
298
|
this.setAttribute("aria-hidden", "true");
|
|
299
299
|
}
|
|
@@ -306,7 +306,7 @@ if (isBrowser && !customElements.get("x-otp-slot")) customElements.define("x-otp
|
|
|
306
306
|
* `<x-otp-slot>`s into one attached group. All layout lives in CSS; this only
|
|
307
307
|
* applies a `group` role so the visual grouping is exposed to assistive tech.
|
|
308
308
|
*/
|
|
309
|
-
var XOtpGroup = class extends
|
|
309
|
+
var XOtpGroup = class extends HTMLElementBase {
|
|
310
310
|
connectedCallback() {
|
|
311
311
|
if (!this.hasAttribute("role")) this.setAttribute("role", "group");
|
|
312
312
|
}
|
|
@@ -318,7 +318,7 @@ if (isBrowser && !customElements.get("x-otp-group")) customElements.define("x-ot
|
|
|
318
318
|
* `<x-otp-separator>` — decorative divider authored between OTP groups (e.g. a
|
|
319
319
|
* dash between a 3-3 split). Purely visual: `aria-hidden`, glyph drawn in CSS.
|
|
320
320
|
*/
|
|
321
|
-
var XOtpSeparator = class extends
|
|
321
|
+
var XOtpSeparator = class extends HTMLElementBase {
|
|
322
322
|
connectedCallback() {
|
|
323
323
|
this.setAttribute("aria-hidden", "true");
|
|
324
324
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { m as SEED, r as MaybeReactive, u as CLAIM } from "../index-BR8XVkck.mjs";
|
|
2
2
|
import { ComputedPromise } from "./promise.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utilities/async.d.ts
|
|
@@ -38,7 +38,7 @@ declare class Async<TInput = undefined, TOutput = unknown> {
|
|
|
38
38
|
set fn(fn: MaybeReactive<Fn<TInput, TOutput>>);
|
|
39
39
|
get raw(): ComputedPromise<TOutput | undefined>;
|
|
40
40
|
get pending(): boolean;
|
|
41
|
-
get state(): "pending" | "fulfilled" | "rejected";
|
|
41
|
+
get state(): "idle" | "pending" | "fulfilled" | "rejected";
|
|
42
42
|
get value(): TOutput | undefined;
|
|
43
43
|
get reason(): unknown;
|
|
44
44
|
get result(): unknown;
|
package/dist/utilities/async.mjs
CHANGED
|
@@ -9,6 +9,7 @@ function flushDeferredAsyncRuns() {
|
|
|
9
9
|
deferredRuns.clear();
|
|
10
10
|
for (const run of runs) run();
|
|
11
11
|
}
|
|
12
|
+
const IDLE = promise(() => {});
|
|
12
13
|
/**
|
|
13
14
|
* Reactive wrapper around an async function. Exposes the current run as
|
|
14
15
|
* reactive signals (`state`, `value`, `reason`, `result`, `pending`) and
|
|
@@ -44,15 +45,16 @@ var Async = class {
|
|
|
44
45
|
set fn(fn) {
|
|
45
46
|
this.#fn(resolve(fn));
|
|
46
47
|
}
|
|
47
|
-
#current = signal(
|
|
48
|
+
#current = signal(IDLE);
|
|
48
49
|
get raw() {
|
|
49
50
|
return this.#current();
|
|
50
51
|
}
|
|
51
52
|
get pending() {
|
|
52
|
-
return this.
|
|
53
|
+
return this.state === "pending";
|
|
53
54
|
}
|
|
54
55
|
get state() {
|
|
55
|
-
|
|
56
|
+
const current = this.#current();
|
|
57
|
+
return current === IDLE ? "idle" : current.state;
|
|
56
58
|
}
|
|
57
59
|
get value() {
|
|
58
60
|
return this.raw.value;
|
|
@@ -77,7 +79,12 @@ var Async = class {
|
|
|
77
79
|
* `ReactivePromise`. See `ReactivePromise[SEED]`.
|
|
78
80
|
*/
|
|
79
81
|
[SEED](value) {
|
|
80
|
-
|
|
82
|
+
let current = this.#current();
|
|
83
|
+
if (current === IDLE) {
|
|
84
|
+
current = promise(() => {});
|
|
85
|
+
this.#current(current);
|
|
86
|
+
}
|
|
87
|
+
const seed = current[SEED];
|
|
81
88
|
seed?.(value);
|
|
82
89
|
}
|
|
83
90
|
/**
|
|
@@ -89,7 +96,8 @@ var Async = class {
|
|
|
89
96
|
const pendingRun = deferredRuns.get(this);
|
|
90
97
|
deferredRuns.delete(this);
|
|
91
98
|
if (record) {
|
|
92
|
-
|
|
99
|
+
const state = untracked(() => this.state);
|
|
100
|
+
if (state !== "fulfilled" && state !== "rejected") this[SEED](record.value);
|
|
93
101
|
return;
|
|
94
102
|
}
|
|
95
103
|
pendingRun?.();
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
declare const isBrowser: boolean;
|
|
4
|
-
/** A shared `Disposable` whose `Symbol.dispose` is a no-op — useful as a safe default. */
|
|
5
|
-
declare const noopDisposable: Disposable;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { isBrowser, noopDisposable };
|
|
1
|
+
import { n as isBrowser, r as noopDisposable, t as HTMLElementBase } from "../environment-Fg46vL6e.mjs";
|
|
2
|
+
export { HTMLElementBase, isBrowser, noopDisposable };
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
//#region src/utilities/environment.ts
|
|
2
2
|
/** `true` when running in a browser (both `window` and `document` exist). */
|
|
3
3
|
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
4
|
+
/**
|
|
5
|
+
* `HTMLElement` in the browser; an empty stand-in on the server.
|
|
6
|
+
*
|
|
7
|
+
* A custom-element class evaluates its `extends` clause at module load, but
|
|
8
|
+
* `HTMLElement` is undefined in Node — so importing an element module during
|
|
9
|
+
* SSR (e.g. an Astro `client:load` island) throws `HTMLElement is not defined`
|
|
10
|
+
* before any `isBrowser` guard can run. Elements are never *constructed* on the
|
|
11
|
+
* server (the streaming renderer emits plain tags), so a stub base is enough to
|
|
12
|
+
* let the class definition load; the guarded `customElements.define` still only
|
|
13
|
+
* registers in a real browser.
|
|
14
|
+
*/
|
|
15
|
+
const HTMLElementBase = isBrowser ? HTMLElement : class {};
|
|
4
16
|
/** A shared `Disposable` whose `Symbol.dispose` is a no-op — useful as a safe default. */
|
|
5
17
|
const noopDisposable = { [Symbol.dispose]() {} };
|
|
6
18
|
//#endregion
|
|
7
|
-
export { isBrowser, noopDisposable };
|
|
19
|
+
export { HTMLElementBase, isBrowser, noopDisposable };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elements-kit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.23.0",
|
|
5
5
|
"description": "A lightweight reactive UI library that transforms native HTMLElements into reactive components with signals. Ideal for framework-agnostic applications and web components.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"webcomponents",
|