@vielzeug/craftit 1.0.1 → 2.0.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/README.md +112 -401
- package/dist/core/component.cjs +2 -0
- package/dist/core/component.cjs.map +1 -0
- package/dist/core/component.d.ts +172 -0
- package/dist/core/component.d.ts.map +1 -0
- package/dist/core/component.js +2 -0
- package/dist/core/component.js.map +1 -0
- package/dist/core/host.cjs +2 -0
- package/dist/core/host.cjs.map +1 -0
- package/dist/core/host.d.ts +77 -0
- package/dist/core/host.d.ts.map +1 -0
- package/dist/core/host.js +2 -0
- package/dist/core/host.js.map +1 -0
- package/dist/core/internal.cjs +2 -0
- package/dist/core/internal.cjs.map +1 -0
- package/dist/core/internal.d.ts +105 -0
- package/dist/core/internal.d.ts.map +1 -0
- package/dist/core/internal.js +2 -0
- package/dist/core/internal.js.map +1 -0
- package/dist/core/runtime-bindings.cjs +2 -0
- package/dist/core/runtime-bindings.cjs.map +1 -0
- package/dist/core/runtime-bindings.d.ts +6 -0
- package/dist/core/runtime-bindings.d.ts.map +1 -0
- package/dist/core/runtime-bindings.js +2 -0
- package/dist/core/runtime-bindings.js.map +1 -0
- package/dist/core/runtime-lifecycle.cjs +2 -0
- package/dist/core/runtime-lifecycle.cjs.map +1 -0
- package/dist/core/runtime-lifecycle.d.ts +116 -0
- package/dist/core/runtime-lifecycle.d.ts.map +1 -0
- package/dist/core/runtime-lifecycle.js +2 -0
- package/dist/core/runtime-lifecycle.js.map +1 -0
- package/dist/core/runtime.cjs +1 -0
- package/dist/core/runtime.d.ts +3 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +1 -0
- package/dist/core/template-bindings.cjs +2 -0
- package/dist/core/template-bindings.cjs.map +1 -0
- package/dist/core/template-bindings.d.ts +59 -0
- package/dist/core/template-bindings.d.ts.map +1 -0
- package/dist/core/template-bindings.js +2 -0
- package/dist/core/template-bindings.js.map +1 -0
- package/dist/core/template-compiler.cjs +2 -0
- package/dist/core/template-compiler.cjs.map +1 -0
- package/dist/core/template-compiler.d.ts +25 -0
- package/dist/core/template-compiler.d.ts.map +1 -0
- package/dist/core/template-compiler.js +2 -0
- package/dist/core/template-compiler.js.map +1 -0
- package/dist/core/template-dom.cjs +2 -0
- package/dist/core/template-dom.cjs.map +1 -0
- package/dist/core/template-dom.d.ts +13 -0
- package/dist/core/template-dom.d.ts.map +1 -0
- package/dist/core/template-dom.js +2 -0
- package/dist/core/template-dom.js.map +1 -0
- package/dist/core/template-html.cjs +2 -0
- package/dist/core/template-html.cjs.map +1 -0
- package/dist/core/template-html.d.ts +26 -0
- package/dist/core/template-html.d.ts.map +1 -0
- package/dist/core/template-html.js +2 -0
- package/dist/core/template-html.js.map +1 -0
- package/dist/core/template.cjs +2 -0
- package/dist/core/template.cjs.map +1 -0
- package/dist/core/template.d.ts +11 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +2 -0
- package/dist/core/template.js.map +1 -0
- package/dist/core/utilities.cjs +2 -0
- package/dist/core/utilities.cjs.map +1 -0
- package/dist/core/utilities.d.ts +68 -0
- package/dist/core/utilities.d.ts.map +1 -0
- package/dist/core/utilities.js +2 -0
- package/dist/core/utilities.js.map +1 -0
- package/dist/craftit.cjs +2 -18
- package/dist/craftit.cjs.map +1 -1
- package/dist/craftit.js +2 -580
- package/dist/craftit.js.map +1 -1
- package/dist/directives/attr.cjs +2 -0
- package/dist/directives/attr.cjs.map +1 -0
- package/dist/directives/attr.d.ts +14 -0
- package/dist/directives/attr.d.ts.map +1 -0
- package/dist/directives/attr.js +2 -0
- package/dist/directives/attr.js.map +1 -0
- package/dist/directives/bind.cjs +2 -0
- package/dist/directives/bind.cjs.map +1 -0
- package/dist/directives/bind.d.ts +30 -0
- package/dist/directives/bind.d.ts.map +1 -0
- package/dist/directives/bind.js +2 -0
- package/dist/directives/bind.js.map +1 -0
- package/dist/directives/choose.cjs +2 -0
- package/dist/directives/choose.cjs.map +1 -0
- package/dist/directives/choose.d.ts +34 -0
- package/dist/directives/choose.d.ts.map +1 -0
- package/dist/directives/choose.js +2 -0
- package/dist/directives/choose.js.map +1 -0
- package/dist/directives/classes.cjs +2 -0
- package/dist/directives/classes.cjs.map +1 -0
- package/dist/directives/classes.d.ts +20 -0
- package/dist/directives/classes.d.ts.map +1 -0
- package/dist/directives/classes.js +2 -0
- package/dist/directives/classes.js.map +1 -0
- package/dist/directives/each.cjs +2 -0
- package/dist/directives/each.cjs.map +1 -0
- package/dist/directives/each.d.ts +68 -0
- package/dist/directives/each.d.ts.map +1 -0
- package/dist/directives/each.js +2 -0
- package/dist/directives/each.js.map +1 -0
- package/dist/directives/index.cjs +1 -0
- package/dist/directives/index.d.ts +14 -0
- package/dist/directives/index.d.ts.map +1 -0
- package/dist/directives/index.js +1 -0
- package/dist/directives/match.cjs +2 -0
- package/dist/directives/match.cjs.map +1 -0
- package/dist/directives/match.d.ts +31 -0
- package/dist/directives/match.d.ts.map +1 -0
- package/dist/directives/match.js +2 -0
- package/dist/directives/match.js.map +1 -0
- package/dist/directives/memo.cjs +2 -0
- package/dist/directives/memo.cjs.map +1 -0
- package/dist/directives/memo.d.ts +23 -0
- package/dist/directives/memo.d.ts.map +1 -0
- package/dist/directives/memo.js +2 -0
- package/dist/directives/memo.js.map +1 -0
- package/dist/directives/on.cjs +2 -0
- package/dist/directives/on.cjs.map +1 -0
- package/dist/directives/on.d.ts +25 -0
- package/dist/directives/on.d.ts.map +1 -0
- package/dist/directives/on.js +2 -0
- package/dist/directives/on.js.map +1 -0
- package/dist/directives/raw.cjs +2 -0
- package/dist/directives/raw.cjs.map +1 -0
- package/dist/directives/raw.d.ts +25 -0
- package/dist/directives/raw.d.ts.map +1 -0
- package/dist/directives/raw.js +2 -0
- package/dist/directives/raw.js.map +1 -0
- package/dist/directives/spread.cjs +2 -0
- package/dist/directives/spread.cjs.map +1 -0
- package/dist/directives/spread.d.ts +14 -0
- package/dist/directives/spread.d.ts.map +1 -0
- package/dist/directives/spread.js +2 -0
- package/dist/directives/spread.js.map +1 -0
- package/dist/directives/style.cjs +2 -0
- package/dist/directives/style.cjs.map +1 -0
- package/dist/directives/style.d.ts +22 -0
- package/dist/directives/style.d.ts.map +1 -0
- package/dist/directives/style.js +2 -0
- package/dist/directives/style.js.map +1 -0
- package/dist/directives/until.cjs +2 -0
- package/dist/directives/until.cjs.map +1 -0
- package/dist/directives/until.d.ts +26 -0
- package/dist/directives/until.d.ts.map +1 -0
- package/dist/directives/until.js +2 -0
- package/dist/directives/until.js.map +1 -0
- package/dist/directives/when.cjs +2 -0
- package/dist/directives/when.cjs.map +1 -0
- package/dist/directives/when.d.ts +17 -0
- package/dist/directives/when.d.ts.map +1 -0
- package/dist/directives/when.js +2 -0
- package/dist/directives/when.js.map +1 -0
- package/dist/index.cjs +1 -2
- package/dist/index.d.ts +10 -265
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -13
- package/dist/labs/a11y.cjs +2 -0
- package/dist/labs/a11y.cjs.map +1 -0
- package/dist/labs/a11y.d.ts +61 -0
- package/dist/labs/a11y.d.ts.map +1 -0
- package/dist/labs/a11y.js +2 -0
- package/dist/labs/a11y.js.map +1 -0
- package/dist/labs/index.d.ts +8 -0
- package/dist/labs/index.d.ts.map +1 -0
- package/dist/labs/list.cjs +2 -0
- package/dist/labs/list.cjs.map +1 -0
- package/dist/labs/list.d.ts +26 -0
- package/dist/labs/list.d.ts.map +1 -0
- package/dist/labs/list.js +2 -0
- package/dist/labs/list.js.map +1 -0
- package/dist/labs/observers.cjs +2 -0
- package/dist/labs/observers.cjs.map +1 -0
- package/dist/labs/observers.d.ts +42 -0
- package/dist/labs/observers.d.ts.map +1 -0
- package/dist/labs/observers.js +2 -0
- package/dist/labs/observers.js.map +1 -0
- package/dist/labs/overlay.cjs +2 -0
- package/dist/labs/overlay.cjs.map +1 -0
- package/dist/labs/overlay.d.ts +35 -0
- package/dist/labs/overlay.d.ts.map +1 -0
- package/dist/labs/overlay.js +2 -0
- package/dist/labs/overlay.js.map +1 -0
- package/dist/labs/selectable.cjs +2 -0
- package/dist/labs/selectable.cjs.map +1 -0
- package/dist/labs/selectable.d.ts +70 -0
- package/dist/labs/selectable.d.ts.map +1 -0
- package/dist/labs/selectable.js +2 -0
- package/dist/labs/selectable.js.map +1 -0
- package/dist/labs/selection.cjs +2 -0
- package/dist/labs/selection.cjs.map +1 -0
- package/dist/labs/selection.d.ts +68 -0
- package/dist/labs/selection.d.ts.map +1 -0
- package/dist/labs/selection.js +2 -0
- package/dist/labs/selection.js.map +1 -0
- package/dist/labs.cjs +1 -0
- package/dist/labs.js +1 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/test.cjs +2 -0
- package/dist/test/test.cjs.map +1 -0
- package/dist/test/test.d.ts +198 -0
- package/dist/test/test.d.ts.map +1 -0
- package/dist/test/test.js +2 -0
- package/dist/test/test.js.map +1 -0
- package/dist/test.cjs +1 -0
- package/dist/test.js +1 -0
- package/package.json +37 -9
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HTMLResult } from '../core/internal';
|
|
2
|
+
/**
|
|
3
|
+
* Renders `pendingFn` while a Promise is pending, then switches to the resolved
|
|
4
|
+
* result. Lighter-weight alternative to `suspense()` for one-shot data loading
|
|
5
|
+
* with no error/retry UI.
|
|
6
|
+
*
|
|
7
|
+
* Returns a reactive getter the engine tracks automatically — no manual signal
|
|
8
|
+
* management needed at the call site.
|
|
9
|
+
*
|
|
10
|
+
* @param promise The promise to await. Should already resolve to a renderable value.
|
|
11
|
+
* @param pendingFn Optional function called while the promise is pending.
|
|
12
|
+
* @param onError Optional function called when the promise rejects. Receives the rejection reason.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* import { until } from '@vielzeug/craftit/directives';
|
|
16
|
+
*
|
|
17
|
+
* const data = fetch('/api/user').then(r => r.json());
|
|
18
|
+
*
|
|
19
|
+
* html`${until(
|
|
20
|
+
* data.then(u => html`<p>Hello, ${u.name}!</p>`),
|
|
21
|
+
* () => html`<p>Loading…</p>`,
|
|
22
|
+
* (err) => html`<p>Error: ${String(err)}</p>`,
|
|
23
|
+
* )}`
|
|
24
|
+
*/
|
|
25
|
+
export declare function until(promise: Promise<string | HTMLResult>, pendingFn?: () => string | HTMLResult, onError?: (err: unknown) => string | HTMLResult): () => string | HTMLResult;
|
|
26
|
+
//# sourceMappingURL=until.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"until.d.ts","sourceRoot":"","sources":["../../src/directives/until.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,EACrC,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,UAAU,EACrC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,UAAU,GAC9C,MAAM,MAAM,GAAG,UAAU,CAiB3B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{signal as e}from"@vielzeug/stateit";function t(t,n,r){let i=e({done:!1});return t.then(e=>{i.value={done:!0,value:e}},e=>{r?i.value={done:!0,value:r(e)}:i.value={done:!0,value:`Error: ${String(e)}`}}),()=>i.value.done?i.value.value:n?.()??``}export{t as until};
|
|
2
|
+
//# sourceMappingURL=until.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"until.js","names":[],"sources":["../../src/directives/until.ts"],"sourcesContent":["import { signal } from '@vielzeug/stateit';\n\nimport type { HTMLResult } from '../core/internal';\n\ntype State = { done: false } | { done: true; value: string | HTMLResult };\n\n/**\n * Renders `pendingFn` while a Promise is pending, then switches to the resolved\n * result. Lighter-weight alternative to `suspense()` for one-shot data loading\n * with no error/retry UI.\n *\n * Returns a reactive getter the engine tracks automatically — no manual signal\n * management needed at the call site.\n *\n * @param promise The promise to await. Should already resolve to a renderable value.\n * @param pendingFn Optional function called while the promise is pending.\n * @param onError Optional function called when the promise rejects. Receives the rejection reason.\n *\n * @example\n * import { until } from '@vielzeug/craftit/directives';\n *\n * const data = fetch('/api/user').then(r => r.json());\n *\n * html`${until(\n * data.then(u => html`<p>Hello, ${u.name}!</p>`),\n * () => html`<p>Loading…</p>`,\n * (err) => html`<p>Error: ${String(err)}</p>`,\n * )}`\n */\nexport function until(\n promise: Promise<string | HTMLResult>,\n pendingFn?: () => string | HTMLResult,\n onError?: (err: unknown) => string | HTMLResult,\n): () => string | HTMLResult {\n const state = signal<State>({ done: false });\n\n promise.then(\n (val) => {\n state.value = { done: true, value: val };\n },\n (err) => {\n if (onError) {\n state.value = { done: true, value: onError(err) };\n } else {\n state.value = { done: true, value: `Error: ${String(err)}` };\n }\n },\n );\n\n return () => (state.value.done ? state.value.value : (pendingFn?.() ?? ''));\n}\n"],"mappings":"2CA6BA,SAAgB,EACd,EACA,EACA,EAC2B,CAC3B,IAAM,EAAQ,EAAc,CAAE,KAAM,GAAO,CAAC,CAe5C,OAbA,EAAQ,KACL,GAAQ,CACP,EAAM,MAAQ,CAAE,KAAM,GAAM,MAAO,EAAK,EAEzC,GAAQ,CACH,EACF,EAAM,MAAQ,CAAE,KAAM,GAAM,MAAO,EAAQ,EAAI,CAAE,CAEjD,EAAM,MAAQ,CAAE,KAAM,GAAM,MAAO,UAAU,OAAO,EAAI,GAAI,EAGjE,KAEa,EAAM,MAAM,KAAO,EAAM,MAAM,MAAS,KAAa,EAAI"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"when.cjs","names":[],"sources":["../../src/directives/when.ts"],"sourcesContent":["import { isSignal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport type { Directive, HTMLResult } from '../core/internal';\n\n/**\n * Conditionally renders one of two templates based on a condition.\n *\n * - **Signal or getter** — returns a reactive function the engine re-runs automatically.\n * - **Static value** — evaluated once at call time, returns the result directly.\n *\n * @example\n * import { when } from '@vielzeug/craftit/directives';\n *\n * html`${when(isLoggedIn, () => html`<user-panel>`, () => html`<login-form>`)}`\n * html`${when(() => count.value > 0, () => html`<span>${count}</span>`)}`\n */\nexport function when<V extends string | HTMLResult>(\n condition: Signal<unknown> | ReadonlySignal<unknown> | (() => unknown),\n thenFn: () => V,\n elseFn?: () => V,\n): Directive;\nexport function when<V extends string | HTMLResult>(condition: unknown, thenFn: () => V, elseFn?: () => V): V | string;\nexport function when<V extends string | HTMLResult>(\n condition: unknown,\n thenFn: () => V,\n elseFn?: () => V,\n): V | string | Directive {\n if (isSignal(condition) || typeof condition === 'function') {\n const get = isSignal(condition) ? () => (condition as ReadonlySignal<unknown>).value : (condition as () => unknown);\n\n return {\n render: (): string | HTMLResult => (get() ? thenFn() : (elseFn?.() ?? '')),\n };\n }\n\n return condition ? thenFn() : (elseFn?.() ?? '');\n}\n"],"mappings":"mCAsBA,SAAgB,EACd,EACA,EACA,EACwB,CACxB,IAAA,EAAA,EAAA,UAAa,EAAU,EAAI,OAAO,GAAc,WAAY,CAC1D,IAAM,GAAA,EAAA,EAAA,UAAe,EAAU,KAAU,EAAsC,MAAS,EAExF,MAAO,CACL,WAAoC,GAAK,CAAG,GAAQ,CAAI,KAAU,EAAI,GACvE,CAGH,OAAO,EAAY,GAAQ,CAAI,KAAU,EAAI"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ReadonlySignal, type Signal } from '@vielzeug/stateit';
|
|
2
|
+
import type { Directive, HTMLResult } from '../core/internal';
|
|
3
|
+
/**
|
|
4
|
+
* Conditionally renders one of two templates based on a condition.
|
|
5
|
+
*
|
|
6
|
+
* - **Signal or getter** — returns a reactive function the engine re-runs automatically.
|
|
7
|
+
* - **Static value** — evaluated once at call time, returns the result directly.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* import { when } from '@vielzeug/craftit/directives';
|
|
11
|
+
*
|
|
12
|
+
* html`${when(isLoggedIn, () => html`<user-panel>`, () => html`<login-form>`)}`
|
|
13
|
+
* html`${when(() => count.value > 0, () => html`<span>${count}</span>`)}`
|
|
14
|
+
*/
|
|
15
|
+
export declare function when<V extends string | HTMLResult>(condition: Signal<unknown> | ReadonlySignal<unknown> | (() => unknown), thenFn: () => V, elseFn?: () => V): Directive;
|
|
16
|
+
export declare function when<V extends string | HTMLResult>(condition: unknown, thenFn: () => V, elseFn?: () => V): V | string;
|
|
17
|
+
//# sourceMappingURL=when.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"when.d.ts","sourceRoot":"","sources":["../../src/directives/when.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,cAAc,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,UAAU,EAChD,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,EACtE,MAAM,EAAE,MAAM,CAAC,EACf,MAAM,CAAC,EAAE,MAAM,CAAC,GACf,SAAS,CAAC;AACb,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"when.js","names":[],"sources":["../../src/directives/when.ts"],"sourcesContent":["import { isSignal, type ReadonlySignal, type Signal } from '@vielzeug/stateit';\n\nimport type { Directive, HTMLResult } from '../core/internal';\n\n/**\n * Conditionally renders one of two templates based on a condition.\n *\n * - **Signal or getter** — returns a reactive function the engine re-runs automatically.\n * - **Static value** — evaluated once at call time, returns the result directly.\n *\n * @example\n * import { when } from '@vielzeug/craftit/directives';\n *\n * html`${when(isLoggedIn, () => html`<user-panel>`, () => html`<login-form>`)}`\n * html`${when(() => count.value > 0, () => html`<span>${count}</span>`)}`\n */\nexport function when<V extends string | HTMLResult>(\n condition: Signal<unknown> | ReadonlySignal<unknown> | (() => unknown),\n thenFn: () => V,\n elseFn?: () => V,\n): Directive;\nexport function when<V extends string | HTMLResult>(condition: unknown, thenFn: () => V, elseFn?: () => V): V | string;\nexport function when<V extends string | HTMLResult>(\n condition: unknown,\n thenFn: () => V,\n elseFn?: () => V,\n): V | string | Directive {\n if (isSignal(condition) || typeof condition === 'function') {\n const get = isSignal(condition) ? () => (condition as ReadonlySignal<unknown>).value : (condition as () => unknown);\n\n return {\n render: (): string | HTMLResult => (get() ? thenFn() : (elseFn?.() ?? '')),\n };\n }\n\n return condition ? thenFn() : (elseFn?.() ?? '');\n}\n"],"mappings":"6CAsBA,SAAgB,EACd,EACA,EACA,EACwB,CACxB,GAAI,EAAS,EAAU,EAAI,OAAO,GAAc,WAAY,CAC1D,IAAM,EAAM,EAAS,EAAU,KAAU,EAAsC,MAAS,EAExF,MAAO,CACL,WAAoC,GAAK,CAAG,GAAQ,CAAI,KAAU,EAAI,GACvE,CAGH,OAAO,EAAY,GAAQ,CAAI,KAAU,EAAI"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=index.cjs.map
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./core/internal.cjs`),t=require(`./core/runtime-lifecycle.cjs`),n=require(`./core/utilities.cjs`),r=require(`./core/host.cjs`),i=require(`./core/template.cjs`),a=require(`./core/component.cjs`),o=require(`./labs/observers.cjs`);exports.aria=t.aria,exports.createContext=r.createContext,exports.createFormIds=n.createFormIds,exports.createId=n.createId,exports.css=n.css,exports.defineComponent=a.defineComponent,exports.defineField=a.defineField,exports.effect=t.effect,exports.escapeHtml=n.escapeHtml,exports.fire=t.fire,exports.guard=n.guard,exports.handle=t.handle,exports.html=i.html,exports.inject=r.inject,exports.observeResize=o.observeResize,exports.onCleanup=t.onCleanup,exports.onError=t.onError,exports.onMount=t.onMount,exports.onSlotChange=r.onSlotChange,exports.prop=a.prop,exports.provide=r.provide,exports.ref=e.ref,exports.reflect=r.reflect,exports.refs=e.refs,exports.syncContextProps=r.syncContextProps,exports.toKebab=n.toKebab,exports.typed=a.typed,exports.watch=t.watch;var s=require(`@vielzeug/stateit`);Object.keys(s).forEach(function(e){e!==`default`&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:function(){return s[e]}})});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,265 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export declare function attach<T extends HTMLElement>(element: T, container?: HTMLElement): Promise<T>;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Callback invoked when an observed attribute changes
|
|
15
|
-
* @template T - Root element type
|
|
16
|
-
* @template S - State object type
|
|
17
|
-
*/
|
|
18
|
-
export declare type AttributeChangeHook<T = HTMLElement, S extends object = object> = (name: string, oldValue: string | null, newValue: string | null, el: WebComponent<T, S>) => void;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Conditional class helper
|
|
22
|
-
* @param classes - Object mapping class names to boolean conditions
|
|
23
|
-
* @returns Space-separated class string
|
|
24
|
-
* @example classMap({ active: true, disabled: false }) // 'active'
|
|
25
|
-
*/
|
|
26
|
-
export declare const classMap: (classes: Record<string, boolean | undefined>) => string;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Configuration options for creating a web component
|
|
30
|
-
* @template T - Root element type
|
|
31
|
-
* @template S - State object type
|
|
32
|
-
*/
|
|
33
|
-
export declare type ComponentOptions<T = HTMLElement, S extends object = object> = {
|
|
34
|
-
/** Template for rendering the component */
|
|
35
|
-
template: Template<T, S>;
|
|
36
|
-
/** Initial reactive state */
|
|
37
|
-
state?: S;
|
|
38
|
-
/** CSS styles (strings or CSSStyleSheet objects) */
|
|
39
|
-
styles?: (string | CSSStyleSheet)[];
|
|
40
|
-
/** Attributes to observe for changes */
|
|
41
|
-
observedAttributes?: readonly string[];
|
|
42
|
-
/** Enable form association (allows component to participate in forms) */
|
|
43
|
-
formAssociated?: boolean;
|
|
44
|
-
/** Called when component is added to DOM */
|
|
45
|
-
onConnected?: LifecycleHook<T, S>;
|
|
46
|
-
/** Called when component is removed from DOM */
|
|
47
|
-
onDisconnected?: LifecycleHook<T, S>;
|
|
48
|
-
/** Called when an observed attribute changes */
|
|
49
|
-
onAttributeChanged?: AttributeChangeHook<T, S>;
|
|
50
|
-
/** Called after each render completes */
|
|
51
|
-
onUpdated?: LifecycleHook<T, S>;
|
|
52
|
-
} & FormCallbacks<T, S>;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Create a web component class
|
|
56
|
-
* @template T - Root element type
|
|
57
|
-
* @template S - State object type
|
|
58
|
-
* @param options - Component configuration
|
|
59
|
-
* @returns Custom element constructor
|
|
60
|
-
*/
|
|
61
|
-
export declare const createComponent: <T = HTMLElement, S extends object = object>(options: ComponentOptions<T, S>) => CustomElementConstructor;
|
|
62
|
-
|
|
63
|
-
export declare const css: ((strings: TemplateStringsArray, ...values: unknown[]) => string) & {
|
|
64
|
-
/**
|
|
65
|
-
* Create a typed theme with CSS variables and autocomplete
|
|
66
|
-
*
|
|
67
|
-
* Single theme mode:
|
|
68
|
-
* Returns a typed proxy with autocomplete for all theme properties
|
|
69
|
-
*
|
|
70
|
-
* Light/dark mode:
|
|
71
|
-
* Returns the same typed proxy - CSS handles which theme applies via media queries
|
|
72
|
-
* You reference variables the same way regardless of theme mode
|
|
73
|
-
*
|
|
74
|
-
* @param light - Theme variables (or light theme for dual-mode)
|
|
75
|
-
* @param dark - Optional dark theme variables
|
|
76
|
-
* @param options - Configuration options
|
|
77
|
-
* @param options.selector - CSS selector (default: ':host')
|
|
78
|
-
* @param options.attribute - Attribute for manual override (default: 'data-theme')
|
|
79
|
-
* @returns Typed proxy with autocomplete
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* // Single theme
|
|
83
|
-
* const theme = css.theme({
|
|
84
|
-
* primaryColor: '#3b82f6',
|
|
85
|
-
* spacing: '1rem',
|
|
86
|
-
* });
|
|
87
|
-
*
|
|
88
|
-
* css`
|
|
89
|
-
* ${theme}
|
|
90
|
-
* .button {
|
|
91
|
-
* color: ${theme.primaryColor}; // Autocomplete!
|
|
92
|
-
* padding: ${theme.spacing};
|
|
93
|
-
* }
|
|
94
|
-
* `
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* // Light/dark theme - same variable references!
|
|
98
|
-
* const theme = css.theme(
|
|
99
|
-
* { bg: '#fff', text: '#000' }, // Light
|
|
100
|
-
* { bg: '#000', text: '#fff' } // Dark
|
|
101
|
-
* );
|
|
102
|
-
*
|
|
103
|
-
* css`
|
|
104
|
-
* ${theme}
|
|
105
|
-
* .card {
|
|
106
|
-
* background: ${theme.bg}; // Autocomplete! CSS handles light/dark
|
|
107
|
-
* color: ${theme.text}; // Same variable for both themes
|
|
108
|
-
* }
|
|
109
|
-
* `
|
|
110
|
-
*/
|
|
111
|
-
theme: {
|
|
112
|
-
<T extends Record<string, string | number>>(vars: T, dark?: undefined, options?: {
|
|
113
|
-
selector?: string;
|
|
114
|
-
}): ThemeVars<T>;
|
|
115
|
-
<T extends Record<string, string | number>>(light: T, dark: T, options?: {
|
|
116
|
-
selector?: string;
|
|
117
|
-
attribute?: string;
|
|
118
|
-
}): ThemeVars<T>;
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Reference a CSS custom property with var()
|
|
122
|
-
* Automatically converts camelCase to --kebab-case
|
|
123
|
-
* @param name - Variable name (with or without --)
|
|
124
|
-
* @param fallback - Optional fallback value
|
|
125
|
-
* @returns var() function string
|
|
126
|
-
* @example css.var('primaryColor') // "var(--primary-color)"
|
|
127
|
-
*/
|
|
128
|
-
var: (name: string, fallback?: string | number) => string;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Define a custom element
|
|
133
|
-
* @template T - Root element type
|
|
134
|
-
* @template S - State object type
|
|
135
|
-
* @param name - Element tag name (must contain hyphen)
|
|
136
|
-
* @param options - Component configuration
|
|
137
|
-
*/
|
|
138
|
-
export declare const defineElement: <T = HTMLElement, S extends object = object>(name: string, options: ComponentOptions<T, S>) => void;
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Remove a component from the DOM with cleanup
|
|
142
|
-
* @param element - The element to destroy
|
|
143
|
-
* @example
|
|
144
|
-
* const el = await attach(document.createElement('my-component'));
|
|
145
|
-
* // ... test code ...
|
|
146
|
-
* destroy(el); // Clean removal
|
|
147
|
-
*/
|
|
148
|
-
export declare function destroy(element: HTMLElement): void;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Create and define an element in one call
|
|
152
|
-
* @template T - Root element type
|
|
153
|
-
* @template S - State object type
|
|
154
|
-
* @param name - Element tag name (must contain hyphen)
|
|
155
|
-
* @param options - Component configuration
|
|
156
|
-
* @returns Custom element constructor
|
|
157
|
-
*/
|
|
158
|
-
export declare const element: <T = HTMLElement, S extends object = object>(name: string, options: ComponentOptions<T, S>) => CustomElementConstructor;
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Callbacks for form-associated custom elements
|
|
162
|
-
* @template T - Root element type
|
|
163
|
-
* @template S - State object type
|
|
164
|
-
*/
|
|
165
|
-
export declare type FormCallbacks<T = HTMLElement, S extends object = object> = {
|
|
166
|
-
/** Invoked when parent form's disabled state changes */
|
|
167
|
-
onFormDisabled?: (disabled: boolean, el: WebComponent<T, S>) => void;
|
|
168
|
-
/** Invoked when parent form is reset */
|
|
169
|
-
onFormReset?: (el: WebComponent<T, S>) => void;
|
|
170
|
-
/** Invoked when browser restores form state (navigation/autocomplete) */
|
|
171
|
-
onFormStateRestore?: (state: string | File | FormData | null, mode: 'restore' | 'autocomplete', el: WebComponent<T, S>) => void;
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* HTML template string helper
|
|
176
|
-
* @param strings - Template string array
|
|
177
|
-
* @param values - Template values
|
|
178
|
-
* @returns Interpolated HTML string
|
|
179
|
-
*/
|
|
180
|
-
export declare const html: (strings: TemplateStringsArray, ...values: unknown[]) => string;
|
|
181
|
-
|
|
182
|
-
/** biome-ignore-all lint/suspicious/noExplicitAny: Template values can be any type */
|
|
183
|
-
/**
|
|
184
|
-
* Lifecycle hook function called with component instance
|
|
185
|
-
* @template T - Root element type
|
|
186
|
-
* @template S - State object type
|
|
187
|
-
*/
|
|
188
|
-
export declare type LifecycleHook<T = HTMLElement, S extends object = object> = (el: WebComponent<T, S>) => void;
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Conditional style helper
|
|
192
|
-
* @param styles - Object mapping CSS properties to values
|
|
193
|
-
* @returns Semicolon-separated style string
|
|
194
|
-
* @example styleMap({ color: 'red', display: undefined }) // 'color: red'
|
|
195
|
-
*/
|
|
196
|
-
export declare const styleMap: (styles: Partial<CSSStyleDeclaration>) => string;
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Component template - can be a string, DOM node, or function returning either
|
|
200
|
-
* @template T - Root element type
|
|
201
|
-
* @template S - State object type
|
|
202
|
-
*/
|
|
203
|
-
export declare type Template<T = HTMLElement, S extends object = object> = string | Node | ((el: WebComponent<T, S>) => string | Node | DocumentFragment);
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* CSS template string helper with CSS variable utilities
|
|
207
|
-
* @param strings - Template string array
|
|
208
|
-
* @param values - Template values
|
|
209
|
-
* @returns Interpolated CSS string
|
|
210
|
-
* @example css`.button { color: ${color}; }`
|
|
211
|
-
*/
|
|
212
|
-
/** Type helper for theme variable proxy */
|
|
213
|
-
declare type ThemeVars<T extends Record<string, string | number>> = {
|
|
214
|
-
[K in keyof T]: string;
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Web component instance interface
|
|
219
|
-
* @template T - Root element type (first child in shadow DOM)
|
|
220
|
-
* @template S - State object type
|
|
221
|
-
*/
|
|
222
|
-
export declare type WebComponent<T = HTMLElement, S extends object = object> = HTMLElement & {
|
|
223
|
-
/** Reactive state object (changes trigger re-renders) */
|
|
224
|
-
readonly state: S;
|
|
225
|
-
/** Shadow DOM root */
|
|
226
|
-
readonly shadow: ShadowRoot;
|
|
227
|
-
/** First element in shadow DOM */
|
|
228
|
-
readonly root: T;
|
|
229
|
-
/** ElementInternals (only when formAssociated: true) */
|
|
230
|
-
readonly internals?: ElementInternals;
|
|
231
|
-
/** Form value (only when formAssociated: true) */
|
|
232
|
-
value?: string;
|
|
233
|
-
/** Schedule a render in the next animation frame */
|
|
234
|
-
render(): void;
|
|
235
|
-
/** Wait for the pending render to complete */
|
|
236
|
-
flush(): Promise<void>;
|
|
237
|
-
/** Update state (merge, replace, or via function) */
|
|
238
|
-
set(patch: Partial<S> | ((state: S) => S | Promise<S>), options?: {
|
|
239
|
-
replace?: boolean;
|
|
240
|
-
silent?: boolean;
|
|
241
|
-
}): Promise<void>;
|
|
242
|
-
/** Watch a state slice and react to changes */
|
|
243
|
-
watch<U>(selector: (state: S) => U, callback: (value: U, prev: U) => void): () => void;
|
|
244
|
-
/** Find a single element in shadow DOM */
|
|
245
|
-
find<E extends Element = Element>(selector: string): E | null;
|
|
246
|
-
/** Find all matching elements in shadow DOM */
|
|
247
|
-
findAll<E extends Element = Element>(selector: string): E[];
|
|
248
|
-
/** Add event listener with automatic cleanup and delegation support */
|
|
249
|
-
on(target: string | EventTarget, event: string, handler: EventListener, options?: AddEventListenerOptions): void;
|
|
250
|
-
/** Dispatch custom event */
|
|
251
|
-
emit(name: string, detail?: unknown, options?: CustomEventInit): void;
|
|
252
|
-
/** Set timeout with automatic cleanup */
|
|
253
|
-
delay(callback: () => void, ms: number): number;
|
|
254
|
-
/** Clear scheduled timeout */
|
|
255
|
-
clear(id: number): void;
|
|
256
|
-
/** Form utilities (only when formAssociated: true) */
|
|
257
|
-
form?: {
|
|
258
|
-
/** Set form value */
|
|
259
|
-
value(value: string | File | FormData | null, state?: File | FormData | null): void;
|
|
260
|
-
/** Set a validation state */
|
|
261
|
-
valid(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;
|
|
262
|
-
};
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
export { }
|
|
1
|
+
export * from '@vielzeug/stateit';
|
|
2
|
+
export { aria, effect, fire, handle, onCleanup, onError, onMount, watch } from './core/runtime-lifecycle';
|
|
3
|
+
export { defineComponent, defineField, prop, typed, type BuildPropSchema, type DefineComponentOptions, type DefineComponentSetupContext, type FormFieldCallbacks, type FormFieldHandle, type FormFieldOptions, type InferPropsSignals, type PropDef, type PropOptions, } from './core/component';
|
|
4
|
+
export { createContext, inject, onSlotChange, provide, syncContextProps, type InjectionKey, type Slots, } from './core/host';
|
|
5
|
+
export { reflect, type HostBindingValue, type ReflectConfig } from './core/host';
|
|
6
|
+
export { html, type KeyedNode } from './core/template';
|
|
7
|
+
export { ref, refs, type Directive, type HTMLResult, type Ref, type RefCallback, type Refs } from './core/internal';
|
|
8
|
+
export { createFormIds, createId, css, escapeHtml, guard, toKebab, type CSSResult, type EmitFn, } from './core/utilities';
|
|
9
|
+
export { observeResize } from './labs/observers';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAElC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAE1G,OAAO,EACL,eAAe,EACf,WAAW,EACX,IAAI,EACJ,KAAK,EACL,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,aAAa,EACb,MAAM,EACN,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,KAAK,GACX,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjF,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEpH,OAAO,EACL,aAAa,EACb,QAAQ,EACR,GAAG,EACH,UAAU,EACV,KAAK,EACL,OAAO,EACP,KAAK,SAAS,EACd,KAAK,MAAM,GACZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
a as attach,
|
|
4
|
-
s as classMap,
|
|
5
|
-
l as createComponent,
|
|
6
|
-
m as css,
|
|
7
|
-
n as defineElement,
|
|
8
|
-
o as destroy,
|
|
9
|
-
c as element,
|
|
10
|
-
p as html,
|
|
11
|
-
r as styleMap
|
|
12
|
-
};
|
|
13
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import{ref as e,refs as t}from"./core/internal.js";import{aria as n,effect as r,fire as i,handle as a,onCleanup as o,onError as s,onMount as c,watch as l}from"./core/runtime-lifecycle.js";import{createFormIds as u,createId as d,css as f,escapeHtml as p,guard as m,toKebab as h}from"./core/utilities.js";import{createContext as g,inject as _,onSlotChange as v,provide as y,reflect as b,syncContextProps as x}from"./core/host.js";import{html as S}from"./core/template.js";import{defineComponent as C,defineField as w,prop as T,typed as E}from"./core/component.js";import{observeResize as D}from"./labs/observers.js";export*from"@vielzeug/stateit";export{n as aria,g as createContext,u as createFormIds,d as createId,f as css,C as defineComponent,w as defineField,r as effect,p as escapeHtml,i as fire,m as guard,a as handle,S as html,_ as inject,D as observeResize,o as onCleanup,s as onError,c as onMount,v as onSlotChange,T as prop,y as provide,e as ref,b as reflect,t as refs,x as syncContextProps,h as toKebab,E as typed,l as watch};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../core/runtime-lifecycle.cjs`),t=require(`../core/utilities.cjs`);require(`../core/runtime.cjs`);function n(n,r){let i=r.labelId||t.createId(`a11y-label`),a=r.helperId||t.createId(`a11y-helper`),o=null;return n.setAttribute(`role`,r.role),e.onMount(()=>{let t=n.shadowRoot;if(t&&(o=t.querySelector(`[data-a11y-helper]`)),t){let e=t.querySelector(`[data-a11y-label]`);if(e){let t=e.querySelector(`slot`);(t?t.assignedNodes().length>0:e.textContent?.trim().length??!1)&&(e.id=i,n.setAttribute(`aria-labelledby`,i))}}e.effect(()=>{if(r.checked){let e=r.checked();e!==void 0&&n.setAttribute(`aria-checked`,e)}if(r.invalid){let e=r.invalid();n.setAttribute(`aria-invalid`,String(e))}if(r.helperText&&o){let e=r.helperText();e?(o.textContent=e,o.hidden=!1,n.setAttribute(`aria-describedby`,a),(r.helperTone?.()??`default`)===`error`?o.setAttribute(`role`,`alert`):o.removeAttribute(`role`)):(o.hidden=!0,n.removeAttribute(`aria-describedby`))}})}),{helperId:a,labelId:i}}exports.useA11yControl=n;
|
|
2
|
+
//# sourceMappingURL=a11y.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y.cjs","names":[],"sources":["../../src/labs/a11y.ts"],"sourcesContent":["import { effect, onMount } from '../core/runtime';\nimport { createId } from '../core/utilities';\n\n/**\n * Tone of helper/error text: 'default' for helper, 'error' for error message.\n */\nexport type A11yTone = 'default' | 'error';\n\n/**\n * Configuration for `useA11yControl()`.\n *\n * Label presence is detected via DOM query (not heuristics).\n * All other state getters are reactive and can change over time.\n */\nexport type A11yControlConfig = {\n /** Reactive aria-checked value ('true' | 'false' | 'mixed' | undefined) */\n checked?: () => 'true' | 'false' | 'mixed' | undefined;\n /** Optional: custom helper ID instead of auto-generated */\n helperId?: string;\n /** Helper text content (mutually exclusive with explicit label/helper management) */\n helperText?: () => string | undefined;\n /** Tone of helper text: 'error' to set role=\"alert\", 'default' otherwise */\n helperTone?: () => A11yTone;\n /** Reactive aria-invalid value */\n invalid?: () => boolean;\n /** Optional: custom label ID instead of auto-generated */\n labelId?: string;\n /** ARIA role (e.g., 'checkbox', 'radio', 'switch') */\n role: string;\n};\n\n/**\n * Return value from `useA11yControl()`.\n */\nexport type A11yControlHandle = {\n /** ID for helper text element */\n helperId: string;\n /** ID for label element */\n labelId: string;\n};\n\n/**\n * Manages ARIA attributes, IDs, and helper/error live region for accessible form controls.\n *\n * Encapsulates:\n * - Stable ID generation for labels and helpers\n * - `aria-labelledby` wiring when label is present (detected via DOM query)\n * - `aria-describedby` wiring when helper text is present\n * - `aria-invalid` sync with error state\n * - `aria-checked` for checkable controls\n * - Helper text live region with `aria-live=\"polite\"` or `role=\"alert\"` based on tone\n *\n * @example\n * const a11y = useA11yControl(host, {\n * role: 'checkbox',\n * checked: () => indeterminate.value ? 'mixed' : String(checked.value),\n * invalid: () => !!error.value,\n * helperText: () => error.value || helper.value,\n * helperTone: () => error.value ? 'error' : 'default',\n * });\n *\n * // Later in template:\n * // <span id=${a11y.labelId}>Label</span>\n * // <div id=${a11y.helperId} aria-live=\"polite\">Error or helper text</div>\n */\nexport function useA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle {\n const labelId = config.labelId || createId('a11y-label');\n const helperId = config.helperId || createId('a11y-helper');\n\n let helperElement: HTMLDivElement | null = null;\n\n // Set role once at setup\n host.setAttribute('role', config.role);\n\n onMount(() => {\n // Find helper element in shadow DOM\n const shadow = host.shadowRoot;\n\n if (shadow) {\n helperElement = shadow.querySelector('[data-a11y-helper]') as HTMLDivElement | null;\n }\n\n // Detect label presence via DOM query: check if label span has slotted content\n if (shadow) {\n const labelSpan = shadow.querySelector('[data-a11y-label]') as HTMLElement | null;\n\n if (labelSpan) {\n // Check if the label slot has any assigned nodes\n const slot = labelSpan.querySelector('slot') as HTMLSlotElement | null;\n const hasLabelContent = slot\n ? slot.assignedNodes().length > 0\n : (labelSpan.textContent?.trim().length ?? 0 > 0);\n\n if (hasLabelContent) {\n labelSpan.id = labelId;\n host.setAttribute('aria-labelledby', labelId);\n }\n }\n }\n\n // Reactive effects for aria attrs that can change\n effect(() => {\n // aria-checked\n if (config.checked) {\n const checked = config.checked();\n\n if (checked !== undefined) {\n host.setAttribute('aria-checked', checked);\n }\n }\n\n // aria-invalid\n if (config.invalid) {\n const invalid = config.invalid();\n\n host.setAttribute('aria-invalid', String(invalid));\n }\n\n // Helper text and describedby\n if (config.helperText && helperElement) {\n const text = config.helperText();\n\n if (text) {\n helperElement.textContent = text;\n helperElement.hidden = false;\n host.setAttribute('aria-describedby', helperId);\n\n // Set role based on explicit tone (no text heuristics)\n const tone = config.helperTone?.() ?? 'default';\n\n if (tone === 'error') {\n helperElement.setAttribute('role', 'alert');\n } else {\n helperElement.removeAttribute('role');\n }\n } else {\n helperElement.hidden = true;\n host.removeAttribute('aria-describedby');\n }\n }\n });\n });\n\n return {\n helperId,\n labelId,\n };\n}\n"],"mappings":"mHAiEA,SAAgB,EAAe,EAAmB,EAA8C,CAC9F,IAAM,EAAU,EAAO,SAAW,EAAA,SAAS,aAAa,CAClD,EAAW,EAAO,UAAY,EAAA,SAAS,cAAc,CAEvD,EAAuC,KA0E3C,OAvEA,EAAK,aAAa,OAAQ,EAAO,KAAK,CAEtC,EAAA,YAAc,CAEZ,IAAM,EAAS,EAAK,WAOpB,GALI,IACF,EAAgB,EAAO,cAAc,qBAAqB,EAIxD,EAAQ,CACV,IAAM,EAAY,EAAO,cAAc,oBAAoB,CAE3D,GAAI,EAAW,CAEb,IAAM,EAAO,EAAU,cAAc,OAAO,EACpB,EACpB,EAAK,eAAe,CAAC,OAAS,EAC7B,EAAU,aAAa,MAAM,CAAC,QAAU,MAG3C,EAAU,GAAK,EACf,EAAK,aAAa,kBAAmB,EAAQ,GAMnD,EAAA,WAAa,CAEX,GAAI,EAAO,QAAS,CAClB,IAAM,EAAU,EAAO,SAAS,CAE5B,IAAY,IAAA,IACd,EAAK,aAAa,eAAgB,EAAQ,CAK9C,GAAI,EAAO,QAAS,CAClB,IAAM,EAAU,EAAO,SAAS,CAEhC,EAAK,aAAa,eAAgB,OAAO,EAAQ,CAAC,CAIpD,GAAI,EAAO,YAAc,EAAe,CACtC,IAAM,EAAO,EAAO,YAAY,CAE5B,GACF,EAAc,YAAc,EAC5B,EAAc,OAAS,GACvB,EAAK,aAAa,mBAAoB,EAAS,EAGlC,EAAO,cAAc,EAAI,aAEzB,QACX,EAAc,aAAa,OAAQ,QAAQ,CAE3C,EAAc,gBAAgB,OAAO,GAGvC,EAAc,OAAS,GACvB,EAAK,gBAAgB,mBAAmB,IAG5C,EACF,CAEK,CACL,WACA,UACD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tone of helper/error text: 'default' for helper, 'error' for error message.
|
|
3
|
+
*/
|
|
4
|
+
export type A11yTone = 'default' | 'error';
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for `useA11yControl()`.
|
|
7
|
+
*
|
|
8
|
+
* Label presence is detected via DOM query (not heuristics).
|
|
9
|
+
* All other state getters are reactive and can change over time.
|
|
10
|
+
*/
|
|
11
|
+
export type A11yControlConfig = {
|
|
12
|
+
/** Reactive aria-checked value ('true' | 'false' | 'mixed' | undefined) */
|
|
13
|
+
checked?: () => 'true' | 'false' | 'mixed' | undefined;
|
|
14
|
+
/** Optional: custom helper ID instead of auto-generated */
|
|
15
|
+
helperId?: string;
|
|
16
|
+
/** Helper text content (mutually exclusive with explicit label/helper management) */
|
|
17
|
+
helperText?: () => string | undefined;
|
|
18
|
+
/** Tone of helper text: 'error' to set role="alert", 'default' otherwise */
|
|
19
|
+
helperTone?: () => A11yTone;
|
|
20
|
+
/** Reactive aria-invalid value */
|
|
21
|
+
invalid?: () => boolean;
|
|
22
|
+
/** Optional: custom label ID instead of auto-generated */
|
|
23
|
+
labelId?: string;
|
|
24
|
+
/** ARIA role (e.g., 'checkbox', 'radio', 'switch') */
|
|
25
|
+
role: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Return value from `useA11yControl()`.
|
|
29
|
+
*/
|
|
30
|
+
export type A11yControlHandle = {
|
|
31
|
+
/** ID for helper text element */
|
|
32
|
+
helperId: string;
|
|
33
|
+
/** ID for label element */
|
|
34
|
+
labelId: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Manages ARIA attributes, IDs, and helper/error live region for accessible form controls.
|
|
38
|
+
*
|
|
39
|
+
* Encapsulates:
|
|
40
|
+
* - Stable ID generation for labels and helpers
|
|
41
|
+
* - `aria-labelledby` wiring when label is present (detected via DOM query)
|
|
42
|
+
* - `aria-describedby` wiring when helper text is present
|
|
43
|
+
* - `aria-invalid` sync with error state
|
|
44
|
+
* - `aria-checked` for checkable controls
|
|
45
|
+
* - Helper text live region with `aria-live="polite"` or `role="alert"` based on tone
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* const a11y = useA11yControl(host, {
|
|
49
|
+
* role: 'checkbox',
|
|
50
|
+
* checked: () => indeterminate.value ? 'mixed' : String(checked.value),
|
|
51
|
+
* invalid: () => !!error.value,
|
|
52
|
+
* helperText: () => error.value || helper.value,
|
|
53
|
+
* helperTone: () => error.value ? 'error' : 'default',
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* // Later in template:
|
|
57
|
+
* // <span id=${a11y.labelId}>Label</span>
|
|
58
|
+
* // <div id=${a11y.helperId} aria-live="polite">Error or helper text</div>
|
|
59
|
+
*/
|
|
60
|
+
export declare function useA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle;
|
|
61
|
+
//# sourceMappingURL=a11y.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../src/labs/a11y.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACvD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,QAAQ,CAAC;IAC5B,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;IACxB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAkF9F"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{effect as e,onMount as t}from"../core/runtime-lifecycle.js";import{createId as n}from"../core/utilities.js";import"../core/runtime.js";function r(r,i){let a=i.labelId||n(`a11y-label`),o=i.helperId||n(`a11y-helper`),s=null;return r.setAttribute(`role`,i.role),t(()=>{let t=r.shadowRoot;if(t&&(s=t.querySelector(`[data-a11y-helper]`)),t){let e=t.querySelector(`[data-a11y-label]`);if(e){let t=e.querySelector(`slot`);(t?t.assignedNodes().length>0:e.textContent?.trim().length??!1)&&(e.id=a,r.setAttribute(`aria-labelledby`,a))}}e(()=>{if(i.checked){let e=i.checked();e!==void 0&&r.setAttribute(`aria-checked`,e)}if(i.invalid){let e=i.invalid();r.setAttribute(`aria-invalid`,String(e))}if(i.helperText&&s){let e=i.helperText();e?(s.textContent=e,s.hidden=!1,r.setAttribute(`aria-describedby`,o),(i.helperTone?.()??`default`)===`error`?s.setAttribute(`role`,`alert`):s.removeAttribute(`role`)):(s.hidden=!0,r.removeAttribute(`aria-describedby`))}})}),{helperId:o,labelId:a}}export{r as useA11yControl};
|
|
2
|
+
//# sourceMappingURL=a11y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y.js","names":[],"sources":["../../src/labs/a11y.ts"],"sourcesContent":["import { effect, onMount } from '../core/runtime';\nimport { createId } from '../core/utilities';\n\n/**\n * Tone of helper/error text: 'default' for helper, 'error' for error message.\n */\nexport type A11yTone = 'default' | 'error';\n\n/**\n * Configuration for `useA11yControl()`.\n *\n * Label presence is detected via DOM query (not heuristics).\n * All other state getters are reactive and can change over time.\n */\nexport type A11yControlConfig = {\n /** Reactive aria-checked value ('true' | 'false' | 'mixed' | undefined) */\n checked?: () => 'true' | 'false' | 'mixed' | undefined;\n /** Optional: custom helper ID instead of auto-generated */\n helperId?: string;\n /** Helper text content (mutually exclusive with explicit label/helper management) */\n helperText?: () => string | undefined;\n /** Tone of helper text: 'error' to set role=\"alert\", 'default' otherwise */\n helperTone?: () => A11yTone;\n /** Reactive aria-invalid value */\n invalid?: () => boolean;\n /** Optional: custom label ID instead of auto-generated */\n labelId?: string;\n /** ARIA role (e.g., 'checkbox', 'radio', 'switch') */\n role: string;\n};\n\n/**\n * Return value from `useA11yControl()`.\n */\nexport type A11yControlHandle = {\n /** ID for helper text element */\n helperId: string;\n /** ID for label element */\n labelId: string;\n};\n\n/**\n * Manages ARIA attributes, IDs, and helper/error live region for accessible form controls.\n *\n * Encapsulates:\n * - Stable ID generation for labels and helpers\n * - `aria-labelledby` wiring when label is present (detected via DOM query)\n * - `aria-describedby` wiring when helper text is present\n * - `aria-invalid` sync with error state\n * - `aria-checked` for checkable controls\n * - Helper text live region with `aria-live=\"polite\"` or `role=\"alert\"` based on tone\n *\n * @example\n * const a11y = useA11yControl(host, {\n * role: 'checkbox',\n * checked: () => indeterminate.value ? 'mixed' : String(checked.value),\n * invalid: () => !!error.value,\n * helperText: () => error.value || helper.value,\n * helperTone: () => error.value ? 'error' : 'default',\n * });\n *\n * // Later in template:\n * // <span id=${a11y.labelId}>Label</span>\n * // <div id=${a11y.helperId} aria-live=\"polite\">Error or helper text</div>\n */\nexport function useA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle {\n const labelId = config.labelId || createId('a11y-label');\n const helperId = config.helperId || createId('a11y-helper');\n\n let helperElement: HTMLDivElement | null = null;\n\n // Set role once at setup\n host.setAttribute('role', config.role);\n\n onMount(() => {\n // Find helper element in shadow DOM\n const shadow = host.shadowRoot;\n\n if (shadow) {\n helperElement = shadow.querySelector('[data-a11y-helper]') as HTMLDivElement | null;\n }\n\n // Detect label presence via DOM query: check if label span has slotted content\n if (shadow) {\n const labelSpan = shadow.querySelector('[data-a11y-label]') as HTMLElement | null;\n\n if (labelSpan) {\n // Check if the label slot has any assigned nodes\n const slot = labelSpan.querySelector('slot') as HTMLSlotElement | null;\n const hasLabelContent = slot\n ? slot.assignedNodes().length > 0\n : (labelSpan.textContent?.trim().length ?? 0 > 0);\n\n if (hasLabelContent) {\n labelSpan.id = labelId;\n host.setAttribute('aria-labelledby', labelId);\n }\n }\n }\n\n // Reactive effects for aria attrs that can change\n effect(() => {\n // aria-checked\n if (config.checked) {\n const checked = config.checked();\n\n if (checked !== undefined) {\n host.setAttribute('aria-checked', checked);\n }\n }\n\n // aria-invalid\n if (config.invalid) {\n const invalid = config.invalid();\n\n host.setAttribute('aria-invalid', String(invalid));\n }\n\n // Helper text and describedby\n if (config.helperText && helperElement) {\n const text = config.helperText();\n\n if (text) {\n helperElement.textContent = text;\n helperElement.hidden = false;\n host.setAttribute('aria-describedby', helperId);\n\n // Set role based on explicit tone (no text heuristics)\n const tone = config.helperTone?.() ?? 'default';\n\n if (tone === 'error') {\n helperElement.setAttribute('role', 'alert');\n } else {\n helperElement.removeAttribute('role');\n }\n } else {\n helperElement.hidden = true;\n host.removeAttribute('aria-describedby');\n }\n }\n });\n });\n\n return {\n helperId,\n labelId,\n };\n}\n"],"mappings":"8IAiEA,SAAgB,EAAe,EAAmB,EAA8C,CAC9F,IAAM,EAAU,EAAO,SAAW,EAAS,aAAa,CAClD,EAAW,EAAO,UAAY,EAAS,cAAc,CAEvD,EAAuC,KA0E3C,OAvEA,EAAK,aAAa,OAAQ,EAAO,KAAK,CAEtC,MAAc,CAEZ,IAAM,EAAS,EAAK,WAOpB,GALI,IACF,EAAgB,EAAO,cAAc,qBAAqB,EAIxD,EAAQ,CACV,IAAM,EAAY,EAAO,cAAc,oBAAoB,CAE3D,GAAI,EAAW,CAEb,IAAM,EAAO,EAAU,cAAc,OAAO,EACpB,EACpB,EAAK,eAAe,CAAC,OAAS,EAC7B,EAAU,aAAa,MAAM,CAAC,QAAU,MAG3C,EAAU,GAAK,EACf,EAAK,aAAa,kBAAmB,EAAQ,GAMnD,MAAa,CAEX,GAAI,EAAO,QAAS,CAClB,IAAM,EAAU,EAAO,SAAS,CAE5B,IAAY,IAAA,IACd,EAAK,aAAa,eAAgB,EAAQ,CAK9C,GAAI,EAAO,QAAS,CAClB,IAAM,EAAU,EAAO,SAAS,CAEhC,EAAK,aAAa,eAAgB,OAAO,EAAQ,CAAC,CAIpD,GAAI,EAAO,YAAc,EAAe,CACtC,IAAM,EAAO,EAAO,YAAY,CAE5B,GACF,EAAc,YAAc,EAC5B,EAAc,OAAS,GACvB,EAAK,aAAa,mBAAoB,EAAS,EAGlC,EAAO,cAAc,EAAI,aAEzB,QACX,EAAc,aAAa,OAAQ,QAAQ,CAE3C,EAAc,gBAAgB,OAAO,GAGvC,EAAc,OAAS,GACvB,EAAK,gBAAgB,mBAAmB,IAG5C,EACF,CAEK,CACL,WACA,UACD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Experimental/labs API for @vielzeug/craftit. */
|
|
2
|
+
export { createListNavigation, type ListNavigationController, type ListNavigationOptions, type ListNavigationResult, type ListNavigationResultReason, } from './list';
|
|
3
|
+
export { createOverlayControl, type OverlayChangeContext, type OverlayCloseReason, type OverlayControl, type OverlayControlOptions, type OverlayOpenReason, type OverlayPositioner, } from './overlay';
|
|
4
|
+
export { createSelectionControl, type SelectionController, type SelectionControllerOptions, type SelectionKeyExtractor, type SelectionMode, } from './selection';
|
|
5
|
+
export { useA11yControl, type A11yControlConfig, type A11yControlHandle, type A11yTone } from './a11y';
|
|
6
|
+
export { createCheckableControl, type CheckableChangePayload, type CheckableControlConfig, type CheckableControlHandle, } from './selectable';
|
|
7
|
+
export { observeIntersection, observeMedia, observeResize } from './observers';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/labs/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAGnD,OAAO,EACL,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,KAAK,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvG,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=e=>{let t=(e,t,n=!1)=>e<0?{index:-1,moved:!1,reason:`no-enabled-item`,wrapped:n}:e===t?{index:e,moved:!1,reason:`unchanged`,wrapped:n}:{index:e,moved:!0,reason:`moved`,wrapped:n},n={index:-1,moved:!1,reason:`empty`,wrapped:!1},r=(t,n)=>e.isItemDisabled?e.isItemDisabled(t,n):!!t.disabled,i=(e,t)=>{for(let n=t;n<e.length;n++)if(!r(e[n],n))return n;return-1},a=(e,t)=>{for(let n=t;n>=0;n--)if(!r(e[n],n))return n;return-1},o=r=>{let a=e.getItems();if(a.length===0)return n;let o=e.getIndex(),s=i(a,Math.max(0,r));return s===-1?e.loop?t(i(a,0),o,!0):t(o,o):t(s,o)};return{first:()=>{let r=e.getItems();if(r.length===0)return n;let a=e.getIndex(),o=t(i(r,0),a);return o.index>=0&&e.setIndex(o.index),o},getActiveItem:()=>{let t=e.getItems(),n=e.getIndex();if(!(n<0||n>=t.length))return t[n]},getEnabledIndex:o,last:()=>{let r=e.getItems();if(r.length===0)return n;let i=e.getIndex(),o=t(a(r,r.length-1),i);return o.index>=0&&e.setIndex(o.index),o},next:()=>{let r=e.getItems();if(r.length===0)return n;let a=e.getIndex(),o=i(r,Math.max(0,a+1));if(o!==-1)return e.setIndex(o),t(o,a);if(e.loop){let n=i(r,0);return n!==-1&&e.setIndex(n),t(n,a,!0)}return t(a,a)},prev:()=>{let r=e.getItems();if(r.length===0)return n;let i=e.getIndex(),o=a(r,i-1);if(o!==-1)return e.setIndex(o),t(o,i);if(e.loop){let n=a(r,r.length-1);return n!==-1&&e.setIndex(n),t(n,i,!0)}return t(i,i)},reset:()=>{e.setIndex(-1)},set:t=>{let n=o(t);return n.index>=0&&e.setIndex(n.index),n}}};exports.createListNavigation=e;
|
|
2
|
+
//# sourceMappingURL=list.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.cjs","names":[],"sources":["../../src/labs/list.ts"],"sourcesContent":["export type ListNavigationOptions<T> = {\n getIndex: () => number;\n getItems: () => T[];\n isItemDisabled?: (item: T, index: number) => boolean;\n loop?: boolean;\n setIndex: (index: number) => void;\n};\n\nexport type ListNavigationResultReason = 'empty' | 'moved' | 'no-enabled-item' | 'unchanged';\n\nexport type ListNavigationResult = {\n index: number;\n moved: boolean;\n reason: ListNavigationResultReason;\n wrapped: boolean;\n};\n\nexport type ListNavigationController<T> = {\n first: () => ListNavigationResult;\n getActiveItem: () => T | undefined;\n getEnabledIndex: (index: number) => ListNavigationResult;\n last: () => ListNavigationResult;\n next: () => ListNavigationResult;\n prev: () => ListNavigationResult;\n reset: () => void;\n set: (index: number) => ListNavigationResult;\n};\n\nexport const createListNavigation = <T>(options: ListNavigationOptions<T>): ListNavigationController<T> => {\n const createResult = (nextIndex: number, currentIndex: number, wrapped = false): ListNavigationResult => {\n if (nextIndex < 0) {\n return {\n index: -1,\n moved: false,\n reason: 'no-enabled-item',\n wrapped,\n };\n }\n\n if (nextIndex === currentIndex) {\n return {\n index: nextIndex,\n moved: false,\n reason: 'unchanged',\n wrapped,\n };\n }\n\n return {\n index: nextIndex,\n moved: true,\n reason: 'moved',\n wrapped,\n };\n };\n\n const emptyResult: ListNavigationResult = {\n index: -1,\n moved: false,\n reason: 'empty',\n wrapped: false,\n };\n\n const isDisabled = (item: T, index: number): boolean => {\n if (options.isItemDisabled) return options.isItemDisabled(item, index);\n\n return Boolean((item as { disabled?: boolean }).disabled);\n };\n\n const findForward = (items: T[], start: number): number => {\n for (let idx = start; idx < items.length; idx++) {\n if (!isDisabled(items[idx], idx)) return idx;\n }\n\n return -1;\n };\n\n const findBackward = (items: T[], start: number): number => {\n for (let idx = start; idx >= 0; idx--) {\n if (!isDisabled(items[idx], idx)) return idx;\n }\n\n return -1;\n };\n\n const getEnabledIndex = (index: number): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const forward = findForward(items, Math.max(0, index));\n\n if (forward !== -1) return createResult(forward, current);\n\n if (options.loop) {\n const wrapped = findForward(items, 0);\n\n return createResult(wrapped, current, true);\n }\n\n return createResult(current, current);\n };\n\n const set = (index: number): ListNavigationResult => {\n const result = getEnabledIndex(index);\n\n if (result.index >= 0) options.setIndex(result.index);\n\n return result;\n };\n\n const first = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const next = findForward(items, 0);\n const result = createResult(next, current);\n\n if (result.index >= 0) options.setIndex(result.index);\n\n return result;\n };\n\n const last = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const next = findBackward(items, items.length - 1);\n const result = createResult(next, current);\n\n if (result.index >= 0) options.setIndex(result.index);\n\n return result;\n };\n\n const next = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const forward = findForward(items, Math.max(0, current + 1));\n\n if (forward !== -1) {\n options.setIndex(forward);\n\n return createResult(forward, current);\n }\n\n if (options.loop) {\n const wrapped = findForward(items, 0);\n\n if (wrapped !== -1) options.setIndex(wrapped);\n\n return createResult(wrapped, current, true);\n }\n\n return createResult(current, current);\n };\n\n const prev = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const backward = findBackward(items, current - 1);\n\n if (backward !== -1) {\n options.setIndex(backward);\n\n return createResult(backward, current);\n }\n\n if (options.loop) {\n const wrapped = findBackward(items, items.length - 1);\n\n if (wrapped !== -1) options.setIndex(wrapped);\n\n return createResult(wrapped, current, true);\n }\n\n return createResult(current, current);\n };\n\n const reset = (): void => {\n options.setIndex(-1);\n };\n\n const getActiveItem = (): T | undefined => {\n const items = options.getItems();\n const index = options.getIndex();\n\n if (index < 0 || index >= items.length) return undefined;\n\n return items[index];\n };\n\n return {\n first,\n getActiveItem,\n getEnabledIndex,\n last,\n next,\n prev,\n reset,\n set,\n };\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type ListNavigationOptions<T> = {
|
|
2
|
+
getIndex: () => number;
|
|
3
|
+
getItems: () => T[];
|
|
4
|
+
isItemDisabled?: (item: T, index: number) => boolean;
|
|
5
|
+
loop?: boolean;
|
|
6
|
+
setIndex: (index: number) => void;
|
|
7
|
+
};
|
|
8
|
+
export type ListNavigationResultReason = 'empty' | 'moved' | 'no-enabled-item' | 'unchanged';
|
|
9
|
+
export type ListNavigationResult = {
|
|
10
|
+
index: number;
|
|
11
|
+
moved: boolean;
|
|
12
|
+
reason: ListNavigationResultReason;
|
|
13
|
+
wrapped: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type ListNavigationController<T> = {
|
|
16
|
+
first: () => ListNavigationResult;
|
|
17
|
+
getActiveItem: () => T | undefined;
|
|
18
|
+
getEnabledIndex: (index: number) => ListNavigationResult;
|
|
19
|
+
last: () => ListNavigationResult;
|
|
20
|
+
next: () => ListNavigationResult;
|
|
21
|
+
prev: () => ListNavigationResult;
|
|
22
|
+
reset: () => void;
|
|
23
|
+
set: (index: number) => ListNavigationResult;
|
|
24
|
+
};
|
|
25
|
+
export declare const createListNavigation: <T>(options: ListNavigationOptions<T>) => ListNavigationController<T>;
|
|
26
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/labs/list.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,OAAO,GAAG,iBAAiB,GAAG,WAAW,CAAC;AAE7F,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,0BAA0B,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI;IACxC,KAAK,EAAE,MAAM,oBAAoB,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACnC,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,oBAAoB,CAAC;IACzD,IAAI,EAAE,MAAM,oBAAoB,CAAC;IACjC,IAAI,EAAE,MAAM,oBAAoB,CAAC;IACjC,IAAI,EAAE,MAAM,oBAAoB,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,oBAAoB,CAAC;CAC9C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,CAAC,EAAE,SAAS,qBAAqB,CAAC,CAAC,CAAC,KAAG,wBAAwB,CAAC,CAAC,CAyLrG,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=e=>{let t=(e,t,n=!1)=>e<0?{index:-1,moved:!1,reason:`no-enabled-item`,wrapped:n}:e===t?{index:e,moved:!1,reason:`unchanged`,wrapped:n}:{index:e,moved:!0,reason:`moved`,wrapped:n},n={index:-1,moved:!1,reason:`empty`,wrapped:!1},r=(t,n)=>e.isItemDisabled?e.isItemDisabled(t,n):!!t.disabled,i=(e,t)=>{for(let n=t;n<e.length;n++)if(!r(e[n],n))return n;return-1},a=(e,t)=>{for(let n=t;n>=0;n--)if(!r(e[n],n))return n;return-1},o=r=>{let a=e.getItems();if(a.length===0)return n;let o=e.getIndex(),s=i(a,Math.max(0,r));return s===-1?e.loop?t(i(a,0),o,!0):t(o,o):t(s,o)};return{first:()=>{let r=e.getItems();if(r.length===0)return n;let a=e.getIndex(),o=t(i(r,0),a);return o.index>=0&&e.setIndex(o.index),o},getActiveItem:()=>{let t=e.getItems(),n=e.getIndex();if(!(n<0||n>=t.length))return t[n]},getEnabledIndex:o,last:()=>{let r=e.getItems();if(r.length===0)return n;let i=e.getIndex(),o=t(a(r,r.length-1),i);return o.index>=0&&e.setIndex(o.index),o},next:()=>{let r=e.getItems();if(r.length===0)return n;let a=e.getIndex(),o=i(r,Math.max(0,a+1));if(o!==-1)return e.setIndex(o),t(o,a);if(e.loop){let n=i(r,0);return n!==-1&&e.setIndex(n),t(n,a,!0)}return t(a,a)},prev:()=>{let r=e.getItems();if(r.length===0)return n;let i=e.getIndex(),o=a(r,i-1);if(o!==-1)return e.setIndex(o),t(o,i);if(e.loop){let n=a(r,r.length-1);return n!==-1&&e.setIndex(n),t(n,i,!0)}return t(i,i)},reset:()=>{e.setIndex(-1)},set:t=>{let n=o(t);return n.index>=0&&e.setIndex(n.index),n}}};export{e as createListNavigation};
|
|
2
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","names":[],"sources":["../../src/labs/list.ts"],"sourcesContent":["export type ListNavigationOptions<T> = {\n getIndex: () => number;\n getItems: () => T[];\n isItemDisabled?: (item: T, index: number) => boolean;\n loop?: boolean;\n setIndex: (index: number) => void;\n};\n\nexport type ListNavigationResultReason = 'empty' | 'moved' | 'no-enabled-item' | 'unchanged';\n\nexport type ListNavigationResult = {\n index: number;\n moved: boolean;\n reason: ListNavigationResultReason;\n wrapped: boolean;\n};\n\nexport type ListNavigationController<T> = {\n first: () => ListNavigationResult;\n getActiveItem: () => T | undefined;\n getEnabledIndex: (index: number) => ListNavigationResult;\n last: () => ListNavigationResult;\n next: () => ListNavigationResult;\n prev: () => ListNavigationResult;\n reset: () => void;\n set: (index: number) => ListNavigationResult;\n};\n\nexport const createListNavigation = <T>(options: ListNavigationOptions<T>): ListNavigationController<T> => {\n const createResult = (nextIndex: number, currentIndex: number, wrapped = false): ListNavigationResult => {\n if (nextIndex < 0) {\n return {\n index: -1,\n moved: false,\n reason: 'no-enabled-item',\n wrapped,\n };\n }\n\n if (nextIndex === currentIndex) {\n return {\n index: nextIndex,\n moved: false,\n reason: 'unchanged',\n wrapped,\n };\n }\n\n return {\n index: nextIndex,\n moved: true,\n reason: 'moved',\n wrapped,\n };\n };\n\n const emptyResult: ListNavigationResult = {\n index: -1,\n moved: false,\n reason: 'empty',\n wrapped: false,\n };\n\n const isDisabled = (item: T, index: number): boolean => {\n if (options.isItemDisabled) return options.isItemDisabled(item, index);\n\n return Boolean((item as { disabled?: boolean }).disabled);\n };\n\n const findForward = (items: T[], start: number): number => {\n for (let idx = start; idx < items.length; idx++) {\n if (!isDisabled(items[idx], idx)) return idx;\n }\n\n return -1;\n };\n\n const findBackward = (items: T[], start: number): number => {\n for (let idx = start; idx >= 0; idx--) {\n if (!isDisabled(items[idx], idx)) return idx;\n }\n\n return -1;\n };\n\n const getEnabledIndex = (index: number): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const forward = findForward(items, Math.max(0, index));\n\n if (forward !== -1) return createResult(forward, current);\n\n if (options.loop) {\n const wrapped = findForward(items, 0);\n\n return createResult(wrapped, current, true);\n }\n\n return createResult(current, current);\n };\n\n const set = (index: number): ListNavigationResult => {\n const result = getEnabledIndex(index);\n\n if (result.index >= 0) options.setIndex(result.index);\n\n return result;\n };\n\n const first = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const next = findForward(items, 0);\n const result = createResult(next, current);\n\n if (result.index >= 0) options.setIndex(result.index);\n\n return result;\n };\n\n const last = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const next = findBackward(items, items.length - 1);\n const result = createResult(next, current);\n\n if (result.index >= 0) options.setIndex(result.index);\n\n return result;\n };\n\n const next = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const forward = findForward(items, Math.max(0, current + 1));\n\n if (forward !== -1) {\n options.setIndex(forward);\n\n return createResult(forward, current);\n }\n\n if (options.loop) {\n const wrapped = findForward(items, 0);\n\n if (wrapped !== -1) options.setIndex(wrapped);\n\n return createResult(wrapped, current, true);\n }\n\n return createResult(current, current);\n };\n\n const prev = (): ListNavigationResult => {\n const items = options.getItems();\n\n if (items.length === 0) return emptyResult;\n\n const current = options.getIndex();\n const backward = findBackward(items, current - 1);\n\n if (backward !== -1) {\n options.setIndex(backward);\n\n return createResult(backward, current);\n }\n\n if (options.loop) {\n const wrapped = findBackward(items, items.length - 1);\n\n if (wrapped !== -1) options.setIndex(wrapped);\n\n return createResult(wrapped, current, true);\n }\n\n return createResult(current, current);\n };\n\n const reset = (): void => {\n options.setIndex(-1);\n };\n\n const getActiveItem = (): T | undefined => {\n const items = options.getItems();\n const index = options.getIndex();\n\n if (index < 0 || index >= items.length) return undefined;\n\n return items[index];\n };\n\n return {\n first,\n getActiveItem,\n getEnabledIndex,\n last,\n next,\n prev,\n reset,\n set,\n };\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../core/runtime-lifecycle.cjs`);require(`../core/runtime.cjs`);let t=require(`@vielzeug/stateit`);var n=n=>{let r=(0,t.signal)({height:0,width:0}),i=new ResizeObserver(([e])=>{if(!e)return;let t=e.contentBoxSize[0];t&&(r.value={height:t.blockSize,width:t.inlineSize})});return i.observe(n),e.onCleanup(()=>i.disconnect()),r},r=(n,r)=>{let i=(0,t.signal)(null),a=new IntersectionObserver(([e])=>{e&&(i.value=e)},r);return a.observe(n),e.onCleanup(()=>a.disconnect()),i},i=n=>{let r=window.matchMedia(n),i=(0,t.signal)(r.matches),a=e=>{i.value=e.matches};return r.addEventListener(`change`,a),e.onCleanup(()=>r.removeEventListener(`change`,a)),i};exports.observeIntersection=r,exports.observeMedia=i,exports.observeResize=n;
|
|
2
|
+
//# sourceMappingURL=observers.cjs.map
|