@vielzeug/craftit 2.0.1 → 2.1.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 +71 -53
- package/dist/component.cjs +2 -0
- package/dist/component.cjs.map +1 -0
- package/dist/component.d.ts +39 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +2 -0
- package/dist/component.js.map +1 -0
- package/dist/controls/a11y-control.cjs +2 -0
- package/dist/controls/a11y-control.cjs.map +1 -0
- package/dist/controls/a11y-control.d.ts +16 -0
- package/dist/controls/a11y-control.d.ts.map +1 -0
- package/dist/controls/a11y-control.js +2 -0
- package/dist/controls/a11y-control.js.map +1 -0
- package/dist/controls/checkable-control.cjs +2 -0
- package/dist/controls/checkable-control.cjs.map +1 -0
- package/dist/controls/checkable-control.d.ts +15 -0
- package/dist/controls/checkable-control.d.ts.map +1 -0
- package/dist/controls/checkable-control.js +2 -0
- package/dist/controls/checkable-control.js.map +1 -0
- package/dist/controls/field-control.cjs +2 -0
- package/dist/controls/field-control.cjs.map +1 -0
- package/dist/controls/field-control.d.ts +156 -0
- package/dist/controls/field-control.d.ts.map +1 -0
- package/dist/controls/field-control.js +2 -0
- package/dist/controls/field-control.js.map +1 -0
- package/dist/controls/index.d.ts +10 -0
- package/dist/controls/index.d.ts.map +1 -0
- package/dist/controls/internal/control-state.cjs +2 -0
- package/dist/controls/internal/control-state.cjs.map +1 -0
- package/dist/controls/internal/control-state.d.ts +19 -0
- package/dist/controls/internal/control-state.d.ts.map +1 -0
- package/dist/controls/internal/control-state.js +2 -0
- package/dist/controls/internal/control-state.js.map +1 -0
- package/dist/controls/internal/keyboard-utils.cjs +2 -0
- package/dist/controls/internal/keyboard-utils.cjs.map +1 -0
- package/dist/controls/internal/keyboard-utils.d.ts +7 -0
- package/dist/controls/internal/keyboard-utils.d.ts.map +1 -0
- package/dist/controls/internal/keyboard-utils.js +2 -0
- package/dist/controls/internal/keyboard-utils.js.map +1 -0
- package/dist/controls/internal/number-utils.cjs +2 -0
- package/dist/controls/internal/number-utils.cjs.map +1 -0
- package/dist/controls/internal/number-utils.d.ts +6 -0
- package/dist/controls/internal/number-utils.d.ts.map +1 -0
- package/dist/controls/internal/number-utils.js +2 -0
- package/dist/controls/internal/number-utils.js.map +1 -0
- package/dist/controls/internal/validation-utils.cjs +2 -0
- package/dist/controls/internal/validation-utils.cjs.map +1 -0
- package/dist/controls/internal/validation-utils.d.ts +13 -0
- package/dist/controls/internal/validation-utils.d.ts.map +1 -0
- package/dist/controls/internal/validation-utils.js +2 -0
- package/dist/controls/internal/validation-utils.js.map +1 -0
- package/dist/controls/list-control.cjs +2 -0
- package/dist/controls/list-control.cjs.map +1 -0
- package/dist/controls/list-control.d.ts +21 -0
- package/dist/controls/list-control.d.ts.map +1 -0
- package/dist/controls/list-control.js +2 -0
- package/dist/controls/list-control.js.map +1 -0
- package/dist/controls/list-key-control.cjs +2 -0
- package/dist/controls/list-key-control.cjs.map +1 -0
- package/dist/controls/list-key-control.d.ts +14 -0
- package/dist/controls/list-key-control.d.ts.map +1 -0
- package/dist/controls/list-key-control.js +2 -0
- package/dist/controls/list-key-control.js.map +1 -0
- package/dist/controls/overlay-control.cjs +2 -0
- package/dist/controls/overlay-control.cjs.map +1 -0
- package/dist/controls/overlay-control.d.ts +37 -0
- package/dist/controls/overlay-control.d.ts.map +1 -0
- package/dist/controls/overlay-control.js +2 -0
- package/dist/controls/overlay-control.js.map +1 -0
- package/dist/controls/press-control.cjs +2 -0
- package/dist/controls/press-control.cjs.map +1 -0
- package/dist/controls/press-control.d.ts +12 -0
- package/dist/controls/press-control.d.ts.map +1 -0
- package/dist/controls/press-control.js +2 -0
- package/dist/controls/press-control.js.map +1 -0
- package/dist/controls/slider-control.cjs +2 -0
- package/dist/controls/slider-control.cjs.map +1 -0
- package/dist/controls/slider-control.d.ts +19 -0
- package/dist/controls/slider-control.d.ts.map +1 -0
- package/dist/controls/slider-control.js +2 -0
- package/dist/controls/slider-control.js.map +1 -0
- package/dist/controls/spinner-control.cjs +2 -0
- package/dist/controls/spinner-control.cjs.map +1 -0
- package/dist/controls/spinner-control.d.ts +18 -0
- package/dist/controls/spinner-control.d.ts.map +1 -0
- package/dist/controls/spinner-control.js +2 -0
- package/dist/controls/spinner-control.js.map +1 -0
- package/dist/controls.cjs +1 -0
- package/dist/controls.js +1 -0
- package/dist/craftit.cjs +1 -1
- package/dist/craftit.cjs.map +1 -1
- package/dist/craftit.js +1 -1
- package/dist/craftit.js.map +1 -1
- package/dist/directives/attr.cjs +1 -1
- package/dist/directives/attr.cjs.map +1 -1
- package/dist/directives/attr.d.ts +4 -6
- package/dist/directives/attr.d.ts.map +1 -1
- package/dist/directives/attr.js +1 -1
- package/dist/directives/attr.js.map +1 -1
- package/dist/directives/bind.cjs +1 -1
- package/dist/directives/bind.cjs.map +1 -1
- package/dist/directives/bind.d.ts +20 -12
- package/dist/directives/bind.d.ts.map +1 -1
- package/dist/directives/bind.js +1 -1
- package/dist/directives/bind.js.map +1 -1
- package/dist/directives/choose.cjs +1 -1
- package/dist/directives/choose.cjs.map +1 -1
- package/dist/directives/choose.d.ts +17 -12
- package/dist/directives/choose.d.ts.map +1 -1
- package/dist/directives/choose.js +1 -1
- package/dist/directives/choose.js.map +1 -1
- package/dist/directives/each.cjs +1 -1
- package/dist/directives/each.cjs.map +1 -1
- package/dist/directives/each.d.ts +19 -31
- package/dist/directives/each.d.ts.map +1 -1
- package/dist/directives/each.js +1 -1
- package/dist/directives/each.js.map +1 -1
- package/dist/directives/index.d.ts +1 -2
- package/dist/directives/index.d.ts.map +1 -1
- package/dist/directives/memo.cjs +1 -1
- package/dist/directives/memo.cjs.map +1 -1
- package/dist/directives/memo.d.ts +8 -4
- package/dist/directives/memo.d.ts.map +1 -1
- package/dist/directives/memo.js +1 -1
- package/dist/directives/memo.js.map +1 -1
- package/dist/directives/on.cjs +1 -1
- package/dist/directives/on.cjs.map +1 -1
- package/dist/directives/on.d.ts +1 -1
- package/dist/directives/on.d.ts.map +1 -1
- package/dist/directives/on.js +1 -1
- package/dist/directives/on.js.map +1 -1
- package/dist/directives/raw.cjs +1 -1
- package/dist/directives/raw.cjs.map +1 -1
- package/dist/directives/raw.d.ts +1 -1
- package/dist/directives/raw.d.ts.map +1 -1
- package/dist/directives/raw.js +1 -1
- package/dist/directives/raw.js.map +1 -1
- package/dist/directives/spread.cjs +1 -1
- package/dist/directives/spread.cjs.map +1 -1
- package/dist/directives/spread.d.ts +1 -1
- package/dist/directives/spread.d.ts.map +1 -1
- package/dist/directives/spread.js +1 -1
- package/dist/directives/spread.js.map +1 -1
- package/dist/directives/style.cjs +1 -1
- package/dist/directives/style.cjs.map +1 -1
- package/dist/directives/style.js +1 -1
- package/dist/directives/style.js.map +1 -1
- package/dist/directives/until.cjs.map +1 -1
- package/dist/directives/until.d.ts +1 -1
- package/dist/directives/until.d.ts.map +1 -1
- package/dist/directives/until.js.map +1 -1
- package/dist/directives/when.cjs +1 -1
- package/dist/directives/when.cjs.map +1 -1
- package/dist/directives/when.d.ts +11 -5
- package/dist/directives/when.d.ts.map +1 -1
- package/dist/directives/when.js +1 -1
- package/dist/directives/when.js.map +1 -1
- package/dist/directives.cjs +1 -0
- package/dist/directives.js +1 -0
- package/dist/form.cjs +2 -0
- package/dist/form.cjs.map +1 -0
- package/dist/form.d.ts +29 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +2 -0
- package/dist/form.js.map +1 -0
- package/dist/host.cjs +2 -0
- package/dist/host.cjs.map +1 -0
- package/dist/host.d.ts +75 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +2 -0
- package/dist/host.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +8 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.cjs +2 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.ts +171 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -0
- package/dist/observers/index.d.ts +4 -0
- package/dist/observers/index.d.ts.map +1 -0
- package/dist/observers/intersection-observe.cjs +2 -0
- package/dist/observers/intersection-observe.cjs.map +1 -0
- package/dist/observers/intersection-observe.d.ts +9 -0
- package/dist/observers/intersection-observe.d.ts.map +1 -0
- package/dist/observers/intersection-observe.js +2 -0
- package/dist/observers/intersection-observe.js.map +1 -0
- package/dist/observers/media-observe.cjs +2 -0
- package/dist/observers/media-observe.cjs.map +1 -0
- package/dist/observers/media-observe.d.ts +8 -0
- package/dist/observers/media-observe.d.ts.map +1 -0
- package/dist/observers/media-observe.js +2 -0
- package/dist/observers/media-observe.js.map +1 -0
- package/dist/observers/resize-observe.cjs +2 -0
- package/dist/observers/resize-observe.cjs.map +1 -0
- package/dist/observers/resize-observe.d.ts +11 -0
- package/dist/observers/resize-observe.d.ts.map +1 -0
- package/dist/observers/resize-observe.js +2 -0
- package/dist/observers/resize-observe.js.map +1 -0
- package/dist/observers.cjs +1 -0
- package/dist/observers.js +1 -0
- package/dist/props.cjs +2 -0
- package/dist/props.cjs.map +1 -0
- package/dist/props.d.ts +52 -0
- package/dist/props.d.ts.map +1 -0
- package/dist/props.js +2 -0
- package/dist/props.js.map +1 -0
- package/dist/registration.cjs +2 -0
- package/dist/registration.cjs.map +1 -0
- package/dist/registration.d.ts +18 -0
- package/dist/registration.d.ts.map +1 -0
- package/dist/registration.js +2 -0
- package/dist/registration.js.map +1 -0
- package/dist/runtime-bindings.cjs +2 -0
- package/dist/runtime-bindings.cjs.map +1 -0
- package/dist/runtime-bindings.d.ts.map +1 -0
- package/dist/runtime-bindings.js +2 -0
- package/dist/runtime-bindings.js.map +1 -0
- package/dist/runtime-core.cjs +2 -0
- package/dist/runtime-core.cjs.map +1 -0
- package/dist/runtime-core.d.ts +21 -0
- package/dist/runtime-core.d.ts.map +1 -0
- package/dist/runtime-core.js +2 -0
- package/dist/runtime-core.js.map +1 -0
- package/dist/runtime-lifecycle.cjs +2 -0
- package/dist/runtime-lifecycle.cjs.map +1 -0
- package/dist/runtime-lifecycle.d.ts +24 -0
- package/dist/runtime-lifecycle.d.ts.map +1 -0
- package/dist/runtime-lifecycle.js +2 -0
- package/dist/runtime-lifecycle.js.map +1 -0
- package/dist/runtime.cjs +2 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.ts +21 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2 -0
- package/dist/runtime.js.map +1 -0
- package/dist/template-bindings.cjs +2 -0
- package/dist/template-bindings.cjs.map +1 -0
- package/dist/{core/template-bindings.d.ts → template-bindings.d.ts} +4 -1
- package/dist/template-bindings.d.ts.map +1 -0
- package/dist/template-bindings.js +2 -0
- package/dist/template-bindings.js.map +1 -0
- package/dist/template-compiler.cjs +2 -0
- package/dist/template-compiler.cjs.map +1 -0
- package/dist/{core/template-compiler.d.ts → template-compiler.d.ts} +1 -2
- package/dist/template-compiler.d.ts.map +1 -0
- package/dist/template-compiler.js +2 -0
- package/dist/template-compiler.js.map +1 -0
- package/dist/template-dom.cjs +2 -0
- package/dist/{core/template-dom.js.map → template-dom.cjs.map} +1 -1
- package/dist/template-dom.d.ts.map +1 -0
- package/dist/template-dom.js +2 -0
- package/dist/template-dom.js.map +1 -0
- package/dist/template-html.cjs +2 -0
- package/dist/template-html.cjs.map +1 -0
- package/dist/{core/template-html.d.ts → template-html.d.ts} +1 -4
- package/dist/template-html.d.ts.map +1 -0
- package/dist/template-html.js +2 -0
- package/dist/template-html.js.map +1 -0
- package/dist/template.cjs +2 -0
- package/dist/template.cjs.map +1 -0
- package/dist/{core/template.d.ts → template.d.ts} +2 -3
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +2 -0
- package/dist/template.js.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/testing.cjs +2 -0
- package/dist/testing/testing.cjs.map +1 -0
- package/dist/{test/test.d.ts → testing/testing.d.ts} +8 -8
- package/dist/testing/testing.d.ts.map +1 -0
- package/dist/testing/testing.js +2 -0
- package/dist/testing/testing.js.map +1 -0
- package/dist/testing.cjs +1 -0
- package/dist/testing.js +1 -0
- package/package.json +19 -14
- package/dist/core/component.cjs +0 -2
- package/dist/core/component.cjs.map +0 -1
- package/dist/core/component.d.ts +0 -172
- package/dist/core/component.d.ts.map +0 -1
- package/dist/core/component.js +0 -2
- package/dist/core/component.js.map +0 -1
- package/dist/core/host.cjs +0 -2
- package/dist/core/host.cjs.map +0 -1
- package/dist/core/host.d.ts +0 -77
- package/dist/core/host.d.ts.map +0 -1
- package/dist/core/host.js +0 -2
- package/dist/core/host.js.map +0 -1
- package/dist/core/internal.cjs +0 -2
- package/dist/core/internal.cjs.map +0 -1
- package/dist/core/internal.d.ts +0 -107
- package/dist/core/internal.d.ts.map +0 -1
- package/dist/core/internal.js +0 -2
- package/dist/core/internal.js.map +0 -1
- package/dist/core/runtime-bindings.cjs +0 -2
- package/dist/core/runtime-bindings.cjs.map +0 -1
- package/dist/core/runtime-bindings.d.ts.map +0 -1
- package/dist/core/runtime-bindings.js +0 -2
- package/dist/core/runtime-bindings.js.map +0 -1
- package/dist/core/runtime-lifecycle.cjs +0 -2
- package/dist/core/runtime-lifecycle.cjs.map +0 -1
- package/dist/core/runtime-lifecycle.d.ts +0 -116
- package/dist/core/runtime-lifecycle.d.ts.map +0 -1
- package/dist/core/runtime-lifecycle.js +0 -2
- package/dist/core/runtime-lifecycle.js.map +0 -1
- package/dist/core/runtime.cjs +0 -1
- package/dist/core/runtime.d.ts +0 -3
- package/dist/core/runtime.d.ts.map +0 -1
- package/dist/core/runtime.js +0 -1
- package/dist/core/template-bindings.cjs +0 -2
- package/dist/core/template-bindings.cjs.map +0 -1
- package/dist/core/template-bindings.d.ts.map +0 -1
- package/dist/core/template-bindings.js +0 -2
- package/dist/core/template-bindings.js.map +0 -1
- package/dist/core/template-compiler.cjs +0 -2
- package/dist/core/template-compiler.cjs.map +0 -1
- package/dist/core/template-compiler.d.ts.map +0 -1
- package/dist/core/template-compiler.js +0 -2
- package/dist/core/template-compiler.js.map +0 -1
- package/dist/core/template-dom.cjs +0 -2
- package/dist/core/template-dom.cjs.map +0 -1
- package/dist/core/template-dom.d.ts.map +0 -1
- package/dist/core/template-dom.js +0 -2
- package/dist/core/template-html.cjs +0 -2
- package/dist/core/template-html.cjs.map +0 -1
- package/dist/core/template-html.d.ts.map +0 -1
- package/dist/core/template-html.js +0 -2
- package/dist/core/template-html.js.map +0 -1
- package/dist/core/template.cjs +0 -2
- package/dist/core/template.cjs.map +0 -1
- package/dist/core/template.d.ts.map +0 -1
- package/dist/core/template.js +0 -2
- package/dist/core/template.js.map +0 -1
- package/dist/core/utilities.cjs +0 -2
- package/dist/core/utilities.cjs.map +0 -1
- package/dist/core/utilities.d.ts +0 -68
- package/dist/core/utilities.d.ts.map +0 -1
- package/dist/core/utilities.js +0 -2
- package/dist/core/utilities.js.map +0 -1
- package/dist/directives/index.cjs +0 -1
- package/dist/directives/index.js +0 -1
- package/dist/directives/match.cjs +0 -2
- package/dist/directives/match.cjs.map +0 -1
- package/dist/directives/match.d.ts +0 -31
- package/dist/directives/match.d.ts.map +0 -1
- package/dist/directives/match.js +0 -2
- package/dist/directives/match.js.map +0 -1
- package/dist/labs/a11y.cjs +0 -2
- package/dist/labs/a11y.cjs.map +0 -1
- package/dist/labs/a11y.d.ts +0 -61
- package/dist/labs/a11y.d.ts.map +0 -1
- package/dist/labs/a11y.js +0 -2
- package/dist/labs/a11y.js.map +0 -1
- package/dist/labs/index.d.ts +0 -8
- package/dist/labs/index.d.ts.map +0 -1
- package/dist/labs/list.cjs +0 -2
- package/dist/labs/list.cjs.map +0 -1
- package/dist/labs/list.d.ts +0 -26
- package/dist/labs/list.d.ts.map +0 -1
- package/dist/labs/list.js +0 -2
- package/dist/labs/list.js.map +0 -1
- package/dist/labs/observers.cjs +0 -2
- package/dist/labs/observers.cjs.map +0 -1
- package/dist/labs/observers.d.ts +0 -42
- package/dist/labs/observers.d.ts.map +0 -1
- package/dist/labs/observers.js +0 -2
- package/dist/labs/observers.js.map +0 -1
- package/dist/labs/overlay.cjs +0 -2
- package/dist/labs/overlay.cjs.map +0 -1
- package/dist/labs/overlay.d.ts +0 -35
- package/dist/labs/overlay.d.ts.map +0 -1
- package/dist/labs/overlay.js +0 -2
- package/dist/labs/overlay.js.map +0 -1
- package/dist/labs/selectable.cjs +0 -2
- package/dist/labs/selectable.cjs.map +0 -1
- package/dist/labs/selectable.d.ts +0 -70
- package/dist/labs/selectable.d.ts.map +0 -1
- package/dist/labs/selectable.js +0 -2
- package/dist/labs/selectable.js.map +0 -1
- package/dist/labs/selection.cjs +0 -2
- package/dist/labs/selection.cjs.map +0 -1
- package/dist/labs/selection.d.ts +0 -68
- package/dist/labs/selection.d.ts.map +0 -1
- package/dist/labs/selection.js +0 -2
- package/dist/labs/selection.js.map +0 -1
- package/dist/labs.cjs +0 -1
- package/dist/labs.js +0 -1
- package/dist/test/index.d.ts +0 -2
- package/dist/test/index.d.ts.map +0 -1
- package/dist/test/test.cjs +0 -2
- package/dist/test/test.cjs.map +0 -1
- package/dist/test/test.d.ts.map +0 -1
- package/dist/test/test.js +0 -2
- package/dist/test/test.js.map +0 -1
- package/dist/test.cjs +0 -1
- package/dist/test.js +0 -1
- /package/dist/{core/runtime-bindings.d.ts → runtime-bindings.d.ts} +0 -0
- /package/dist/{core/template-dom.d.ts → template-dom.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@vielzeug/craftit) [](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
**Craftit** provides a compact API for authoring custom elements with fine-grained reactivity. It builds on `@vielzeug/stateit` (re-exported from the main entry) and adds component lifecycle, templating, typed props,
|
|
7
|
+
**Craftit** provides a compact API for authoring custom elements with fine-grained reactivity. It builds on `@vielzeug/stateit` (re-exported from the main entry) and adds component lifecycle, templating, typed props, typed emits, setup-context slots, form-associated helpers, and observer utilities.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -17,9 +17,9 @@ pnpm add @vielzeug/craftit
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
|
-
import {
|
|
20
|
+
import { computed, define, html, signal } from '@vielzeug/craftit';
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
define('my-counter', {
|
|
23
23
|
setup() {
|
|
24
24
|
const count = signal(0);
|
|
25
25
|
const doubled = computed(() => count.value * 2);
|
|
@@ -29,87 +29,109 @@ defineComponent({
|
|
|
29
29
|
<p>Doubled: ${doubled}</p>
|
|
30
30
|
`;
|
|
31
31
|
},
|
|
32
|
-
tag: 'my-counter',
|
|
33
32
|
});
|
|
34
33
|
```
|
|
35
34
|
|
|
36
35
|
## Features
|
|
37
36
|
|
|
38
|
-
- ✅ **Component authoring** — `
|
|
37
|
+
- ✅ **Component authoring** — `define(tag, { props, setup, ... })`
|
|
39
38
|
- ✅ **Signals included** — all `@vielzeug/stateit` exports are re-exported
|
|
40
39
|
- ✅ **Reactive templates** — `html` tagged template with text/attr/prop/event/ref bindings
|
|
41
40
|
- ✅ **Lifecycle helpers** — `onMount`, `onCleanup`, `onError`, `handle`, `watch`, `effect`, `fire.*`
|
|
42
|
-
- ✅ **Typed component APIs** — `
|
|
41
|
+
- ✅ **Typed component APIs** — `define`, `prop`, `typed`, setup-context `emit` and `slots`
|
|
43
42
|
- ✅ **Context / DI** — `createContext`, `provide`, `inject`, `syncContextProps`
|
|
44
43
|
- ✅ **Form-associated controls** — `defineField` with `ElementInternals`
|
|
45
|
-
- ✅ **Observer utilities** — `
|
|
44
|
+
- ✅ **Observer utilities (observers)** — `resizeObserver`, `intersectionObserver`, and `mediaObserver`
|
|
46
45
|
- ✅ **Directive subpath** — `@vielzeug/craftit/directives`
|
|
47
|
-
- ✅ **Test subpath** — `@vielzeug/craftit/
|
|
46
|
+
- ✅ **Test subpath** — `@vielzeug/craftit/testing`
|
|
48
47
|
|
|
49
48
|
## Entry Points
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
- `@vielzeug/craftit` — Main API with component authoring and stateit re-exports.
|
|
51
|
+
- `@vielzeug/craftit/controls` — Stable composables for controls and overlays.
|
|
52
|
+
- `@vielzeug/craftit/observers` — Stable browser observer composables.
|
|
53
|
+
- `@vielzeug/craftit/directives` — Directive helpers like `attrs`, `bind`, `choose`, `each`, `when`, and `until`.
|
|
54
|
+
- `@vielzeug/craftit/testing` — Mount, query, and event testing utilities.
|
|
56
55
|
|
|
57
56
|
## Usage Highlights
|
|
58
57
|
|
|
59
58
|
### Typed props + emits
|
|
60
59
|
|
|
61
60
|
```ts
|
|
62
|
-
import {
|
|
61
|
+
import { define, html } from '@vielzeug/craftit';
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
{ disabled: boolean; label: string },
|
|
66
|
-
{ change: string }
|
|
67
|
-
>({
|
|
63
|
+
define<{ disabled: boolean; label: string }, { change: string }>('name-input', {
|
|
68
64
|
props: {
|
|
69
|
-
disabled:
|
|
70
|
-
label:
|
|
65
|
+
disabled: false,
|
|
66
|
+
label: 'Name',
|
|
71
67
|
},
|
|
72
68
|
setup({ emit, props }) {
|
|
73
69
|
return html`
|
|
74
70
|
<label>${props.label}</label>
|
|
75
|
-
<input
|
|
76
|
-
:disabled=${props.disabled}
|
|
77
|
-
@input=${(e: Event) => emit('change', (e.target as HTMLInputElement).value)}
|
|
78
|
-
/>
|
|
71
|
+
<input :disabled=${props.disabled} @input=${(e: Event) => emit('change', (e.target as HTMLInputElement).value)} />
|
|
79
72
|
`;
|
|
80
73
|
},
|
|
81
|
-
tag: 'name-input',
|
|
82
74
|
});
|
|
83
75
|
```
|
|
84
76
|
|
|
85
77
|
### Directives subpath
|
|
86
78
|
|
|
87
79
|
```ts
|
|
88
|
-
import {
|
|
80
|
+
import { define, html, signal } from '@vielzeug/craftit';
|
|
89
81
|
import { each, when } from '@vielzeug/craftit/directives';
|
|
90
82
|
|
|
91
|
-
|
|
83
|
+
define('todo-list', {
|
|
92
84
|
setup() {
|
|
93
85
|
const todos = signal([{ id: 1, text: 'Write docs', done: false }]);
|
|
94
86
|
|
|
95
87
|
return html`
|
|
96
|
-
${when(
|
|
97
|
-
() => todos.value.length > 0,
|
|
98
|
-
|
|
99
|
-
() =>
|
|
100
|
-
|
|
88
|
+
${when({
|
|
89
|
+
condition: () => todos.value.length > 0,
|
|
90
|
+
else: () => html`<p>No todos</p>`,
|
|
91
|
+
then: () =>
|
|
92
|
+
html`<ul>${each(todos, { key: (todo) => todo.id, render: (todo) => html`<li>${todo.text}</li>` })}</ul>`,
|
|
93
|
+
})}
|
|
101
94
|
`;
|
|
102
95
|
},
|
|
103
|
-
tag: 'todo-list',
|
|
104
96
|
});
|
|
105
97
|
```
|
|
106
98
|
|
|
99
|
+
### Setup-context slots
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { define, effect, html } from '@vielzeug/craftit';
|
|
103
|
+
import { when } from '@vielzeug/craftit/directives';
|
|
104
|
+
|
|
105
|
+
define('slot-panel', {
|
|
106
|
+
setup({ slots }) {
|
|
107
|
+
effect(() => {
|
|
108
|
+
console.log('default elements:', slots.elements().value.length);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return html`
|
|
112
|
+
${when({
|
|
113
|
+
condition: () => slots.has('header').value,
|
|
114
|
+
else: () => html`<h2>Fallback header</h2>`,
|
|
115
|
+
then: () => html`<slot name="header"></slot>`,
|
|
116
|
+
})}
|
|
117
|
+
${when({
|
|
118
|
+
condition: () => slots.has().value,
|
|
119
|
+
else: () => html`<p>No content yet</p>`,
|
|
120
|
+
then: () => html`<slot></slot>`,
|
|
121
|
+
})}
|
|
122
|
+
`;
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Use `slots.has(name?)` for presence checks and `slots.elements(name?)` when you need flattened assigned elements.
|
|
128
|
+
|
|
107
129
|
### Form-associated field
|
|
108
130
|
|
|
109
131
|
```ts
|
|
110
|
-
import {
|
|
132
|
+
import { define, defineField, html, signal } from '@vielzeug/craftit';
|
|
111
133
|
|
|
112
|
-
|
|
134
|
+
define('email-field', {
|
|
113
135
|
formAssociated: true,
|
|
114
136
|
setup() {
|
|
115
137
|
const value = signal('');
|
|
@@ -126,34 +148,30 @@ defineComponent({
|
|
|
126
148
|
/>
|
|
127
149
|
`;
|
|
128
150
|
},
|
|
129
|
-
tag: 'email-field',
|
|
130
151
|
});
|
|
131
152
|
```
|
|
132
153
|
|
|
133
154
|
## API Summary
|
|
134
155
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
| Re-exported from stateit | `signal`, `computed`, `batch`, `untrack`, `readonly`, and more |
|
|
156
|
+
- Components: `define`, `ComponentOptions`, `ComponentSetupContext`
|
|
157
|
+
- Runtime: `onMount`, `onCleanup`, `onError`, `handle`, `aria`, `effect`, `watch`, `fire`
|
|
158
|
+
- Props: `prop`, `typed`, `PropOptions`, `PropDef`, `InferPropsSignals`
|
|
159
|
+
- Slots / emits: setup-context `slots`, setup-context `emit`, `EmitFn`
|
|
160
|
+
- Context: `createContext`, `provide`, `inject`, `syncContextProps`, `InjectionKey`
|
|
161
|
+
- Form: `defineField`, `FormFieldOptions`, `FormFieldCallbacks`, `FormFieldHandle`
|
|
162
|
+
- Observers: `resizeObserver`, `intersectionObserver`, `mediaObserver`
|
|
163
|
+
- Controls: `createFieldIds`
|
|
164
|
+
- Utilities: `html`, `css`, `createId`
|
|
165
|
+
- Re-exported from stateit: `signal`, `computed`, `batch`, `untrack`, `readonly`, and more
|
|
146
166
|
|
|
147
167
|
## Documentation
|
|
148
168
|
|
|
149
169
|
Full docs at **[vielzeug.dev/craftit](https://vielzeug.dev/craftit)**
|
|
150
170
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
| [API Reference](https://vielzeug.dev/craftit/api) | Complete signatures and types |
|
|
156
|
-
| [Examples](https://vielzeug.dev/craftit/examples) | End-to-end component examples |
|
|
171
|
+
- [Overview](https://vielzeug.dev/craftit/) — Install and architecture overview
|
|
172
|
+
- [Usage Guide](https://vielzeug.dev/craftit/usage) — Practical patterns and subpath usage
|
|
173
|
+
- [API Reference](https://vielzeug.dev/craftit/api) — Complete signatures and types
|
|
174
|
+
- [Examples](https://vielzeug.dev/craftit/examples) — End-to-end component examples
|
|
157
175
|
|
|
158
176
|
## License
|
|
159
177
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./internal.cjs`),t=require(`./host.cjs`),n=require(`./props.cjs`),r=require(`./registration.cjs`);var i=(i,a)=>{let{formAssociated:o,host:s,props:c,setup:l,shadow:u,styles:d}=a;return r.registerComponent(i,()=>{let r=c?n.createProps(c):{},i=e.createEmitFn(),a=t.createHost(),o;return l({emit:i,host:a,props:r,shadowRoot:a.shadowRoot,slots:{elements:e=>(o||=t.createSlots(),o.elements(e)),has:e=>(o||=t.createSlots(),o.has(e))}})},{formAssociated:o,host:s,observedAttrs:c?Object.keys(c).map(e.toKebab):[],shadow:u,styles:d})};function a(e,t){return i(e,t)}exports.define=a;
|
|
2
|
+
//# sourceMappingURL=component.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.cjs","names":[],"sources":["../src/component.ts"],"sourcesContent":["/**\n * Component authoring API — define custom elements, props, and registration.\n */\n\nimport { type ComponentHost, type ComponentSlots, createHost, createSlots } from './host';\nimport { type EmitFn, type HTMLResult, createEmitFn, toKebab } from './internal';\nimport {\n createProps,\n type ComponentProps,\n type InferPropsFromDefs,\n type InferPropsSignals,\n type PropDef,\n type PropInputDefs,\n type PropOptions,\n type PropsInput,\n type ResolveComponentProps,\n} from './props';\nimport { type ComponentRegistrationOptions, registerComponent } from './registration';\n\nexport { createProps, type PropsInput };\nexport type {\n InferPropsFromDefs,\n InferPropsSignals,\n ComponentProps,\n PropDef,\n PropInputDefs,\n PropOptions,\n ResolveComponentProps,\n};\nexport { registerComponent, type ComponentRegistrationOptions };\n\n/**\n * Unified setup context passed to component setup functions.\n */\nexport type ComponentSetupContext<\n P extends Record<string, unknown> = Record<never, never>,\n E extends Record<string, unknown> = Record<string, never>,\n D extends PropInputDefs = PropsInput<P>,\n> = {\n emit: EmitFn<E>;\n host: ComponentHost;\n props: ComponentProps<ResolveComponentProps<P, D>>;\n shadowRoot: ShadowRoot;\n slots: ComponentSlots;\n};\n\n/**\n * Configuration object for define().\n */\nexport type ComponentOptions<\n Props extends Record<string, unknown> = Record<never, never>,\n Emits extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n> = {\n formAssociated?: boolean;\n host?: Record<string, string | boolean | number>;\n props?: PropDefs;\n setup: (ctx: ComponentSetupContext<ResolveComponentProps<Props, PropDefs>, Emits, PropDefs>) => string | HTMLResult;\n shadow?: Omit<ShadowRootInit, 'mode'>;\n styles?: (string | CSSStyleSheet | import('./internal').CSSResult)[];\n};\n\nexport type ComponentDefinition<\n Props extends Record<string, unknown> = Record<never, never>,\n Emits extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n> = ComponentOptions<Props, Emits, PropDefs>;\n\nconst defineInternal = <\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n>(\n tag: string,\n definition: ComponentDefinition<Props, EventsType, PropDefs> & { props?: PropDefs },\n): string => {\n const { formAssociated, host: hostOptions, props: propDefs, setup, shadow: shadowOptions, styles } = definition;\n\n const observedAttrs = propDefs ? Object.keys(propDefs).map(toKebab) : [];\n\n return registerComponent(\n tag,\n () => {\n const props = propDefs ? createProps(propDefs) : ({} as ComponentProps<ResolveComponentProps<Props, PropDefs>>);\n const emit = createEmitFn<EventsType>();\n const host = createHost();\n let slotsApi: ComponentSlots | undefined;\n const slots: ComponentSlots = {\n elements: (name?: string) => {\n if (!slotsApi) slotsApi = createSlots();\n\n return slotsApi.elements(name);\n },\n has: (name?: string) => {\n if (!slotsApi) slotsApi = createSlots();\n\n return slotsApi.has(name);\n },\n };\n\n return setup({\n emit: emit as EmitFn<EventsType>,\n host,\n props: props as ComponentProps<ResolveComponentProps<Props, PropDefs>>,\n shadowRoot: host.shadowRoot,\n slots,\n } as ComponentSetupContext<ResolveComponentProps<Props, PropDefs>, EventsType, PropDefs>);\n },\n {\n formAssociated,\n host: hostOptions,\n observedAttrs,\n shadow: shadowOptions,\n styles,\n } satisfies ComponentRegistrationOptions,\n );\n};\n\nexport function define<\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n const PropDefs extends PropInputDefs = PropsInput<Props>,\n>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & { props: PropDefs }): string;\nexport function define<\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & { props?: PropDefs }): string;\nexport function define<\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & { props?: PropDefs }): string {\n return defineInternal(tag, definition);\n}\n"],"mappings":"mHAoEA,IAAM,GAKJ,EACA,IACW,CACX,GAAM,CAAE,iBAAgB,KAAM,EAAa,MAAO,EAAU,QAAO,OAAQ,EAAe,UAAW,EAIrG,OAAO,EAAA,kBACL,MACM,CACJ,IAAM,EAAQ,EAAW,EAAA,YAAY,EAAS,CAAI,EAAE,CAC9C,EAAO,EAAA,cAA0B,CACjC,EAAO,EAAA,YAAY,CACrB,EAcJ,OAAO,EAAM,CACL,OACN,OACO,QACP,WAAY,EAAK,WACjB,MAlB4B,CAC5B,SAAW,IACT,AAAe,IAAW,EAAA,aAAa,CAEhC,EAAS,SAAS,EAAK,EAEhC,IAAM,IACJ,AAAe,IAAW,EAAA,aAAa,CAEhC,EAAS,IAAI,EAAK,EAE5B,CAQA,CAAwF,EAE3F,CACE,iBACA,KAAM,EACN,cAjCkB,EAAW,OAAO,KAAK,EAAS,CAAC,IAAI,EAAA,QAAQ,CAAG,EAAE,CAkCpE,OAAQ,EACR,SACD,CACF,EAaH,SAAgB,EAId,EAAa,EAA6F,CAC1G,OAAO,EAAe,EAAK,EAAW"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component authoring API — define custom elements, props, and registration.
|
|
3
|
+
*/
|
|
4
|
+
import { type ComponentHost, type ComponentSlots } from './host';
|
|
5
|
+
import { type EmitFn, type HTMLResult } from './internal';
|
|
6
|
+
import { createProps, type ComponentProps, type InferPropsFromDefs, type InferPropsSignals, type PropDef, type PropInputDefs, type PropOptions, type PropsInput, type ResolveComponentProps } from './props';
|
|
7
|
+
import { type ComponentRegistrationOptions, registerComponent } from './registration';
|
|
8
|
+
export { createProps, type PropsInput };
|
|
9
|
+
export type { InferPropsFromDefs, InferPropsSignals, ComponentProps, PropDef, PropInputDefs, PropOptions, ResolveComponentProps, };
|
|
10
|
+
export { registerComponent, type ComponentRegistrationOptions };
|
|
11
|
+
/**
|
|
12
|
+
* Unified setup context passed to component setup functions.
|
|
13
|
+
*/
|
|
14
|
+
export type ComponentSetupContext<P extends Record<string, unknown> = Record<never, never>, E extends Record<string, unknown> = Record<string, never>, D extends PropInputDefs = PropsInput<P>> = {
|
|
15
|
+
emit: EmitFn<E>;
|
|
16
|
+
host: ComponentHost;
|
|
17
|
+
props: ComponentProps<ResolveComponentProps<P, D>>;
|
|
18
|
+
shadowRoot: ShadowRoot;
|
|
19
|
+
slots: ComponentSlots;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Configuration object for define().
|
|
23
|
+
*/
|
|
24
|
+
export type ComponentOptions<Props extends Record<string, unknown> = Record<never, never>, Emits extends Record<string, unknown> = Record<string, never>, PropDefs extends PropInputDefs = PropsInput<Props>> = {
|
|
25
|
+
formAssociated?: boolean;
|
|
26
|
+
host?: Record<string, string | boolean | number>;
|
|
27
|
+
props?: PropDefs;
|
|
28
|
+
setup: (ctx: ComponentSetupContext<ResolveComponentProps<Props, PropDefs>, Emits, PropDefs>) => string | HTMLResult;
|
|
29
|
+
shadow?: Omit<ShadowRootInit, 'mode'>;
|
|
30
|
+
styles?: (string | CSSStyleSheet | import('./internal').CSSResult)[];
|
|
31
|
+
};
|
|
32
|
+
export type ComponentDefinition<Props extends Record<string, unknown> = Record<never, never>, Emits extends Record<string, unknown> = Record<string, never>, PropDefs extends PropInputDefs = PropsInput<Props>> = ComponentOptions<Props, Emits, PropDefs>;
|
|
33
|
+
export declare function define<Props extends Record<string, unknown> = Record<never, never>, EventsType extends Record<string, unknown> = Record<string, never>, const PropDefs extends PropInputDefs = PropsInput<Props>>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & {
|
|
34
|
+
props: PropDefs;
|
|
35
|
+
}): string;
|
|
36
|
+
export declare function define<Props extends Record<string, unknown> = Record<never, never>, EventsType extends Record<string, unknown> = Record<string, never>, PropDefs extends PropInputDefs = PropsInput<Props>>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & {
|
|
37
|
+
props?: PropDefs;
|
|
38
|
+
}): string;
|
|
39
|
+
//# sourceMappingURL=component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createEmitFn as e,toKebab as t}from"./internal.js";import{createHost as n,createSlots as r}from"./host.js";import{createProps as i}from"./props.js";import{registerComponent as a}from"./registration.js";var o=(o,s)=>{let{formAssociated:c,host:l,props:u,setup:d,shadow:f,styles:p}=s;return a(o,()=>{let t=u?i(u):{},a=e(),o=n(),s;return d({emit:a,host:o,props:t,shadowRoot:o.shadowRoot,slots:{elements:e=>(s||=r(),s.elements(e)),has:e=>(s||=r(),s.has(e))}})},{formAssociated:c,host:l,observedAttrs:u?Object.keys(u).map(t):[],shadow:f,styles:p})};function s(e,t){return o(e,t)}export{s as define};
|
|
2
|
+
//# sourceMappingURL=component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.js","names":[],"sources":["../src/component.ts"],"sourcesContent":["/**\n * Component authoring API — define custom elements, props, and registration.\n */\n\nimport { type ComponentHost, type ComponentSlots, createHost, createSlots } from './host';\nimport { type EmitFn, type HTMLResult, createEmitFn, toKebab } from './internal';\nimport {\n createProps,\n type ComponentProps,\n type InferPropsFromDefs,\n type InferPropsSignals,\n type PropDef,\n type PropInputDefs,\n type PropOptions,\n type PropsInput,\n type ResolveComponentProps,\n} from './props';\nimport { type ComponentRegistrationOptions, registerComponent } from './registration';\n\nexport { createProps, type PropsInput };\nexport type {\n InferPropsFromDefs,\n InferPropsSignals,\n ComponentProps,\n PropDef,\n PropInputDefs,\n PropOptions,\n ResolveComponentProps,\n};\nexport { registerComponent, type ComponentRegistrationOptions };\n\n/**\n * Unified setup context passed to component setup functions.\n */\nexport type ComponentSetupContext<\n P extends Record<string, unknown> = Record<never, never>,\n E extends Record<string, unknown> = Record<string, never>,\n D extends PropInputDefs = PropsInput<P>,\n> = {\n emit: EmitFn<E>;\n host: ComponentHost;\n props: ComponentProps<ResolveComponentProps<P, D>>;\n shadowRoot: ShadowRoot;\n slots: ComponentSlots;\n};\n\n/**\n * Configuration object for define().\n */\nexport type ComponentOptions<\n Props extends Record<string, unknown> = Record<never, never>,\n Emits extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n> = {\n formAssociated?: boolean;\n host?: Record<string, string | boolean | number>;\n props?: PropDefs;\n setup: (ctx: ComponentSetupContext<ResolveComponentProps<Props, PropDefs>, Emits, PropDefs>) => string | HTMLResult;\n shadow?: Omit<ShadowRootInit, 'mode'>;\n styles?: (string | CSSStyleSheet | import('./internal').CSSResult)[];\n};\n\nexport type ComponentDefinition<\n Props extends Record<string, unknown> = Record<never, never>,\n Emits extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n> = ComponentOptions<Props, Emits, PropDefs>;\n\nconst defineInternal = <\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n>(\n tag: string,\n definition: ComponentDefinition<Props, EventsType, PropDefs> & { props?: PropDefs },\n): string => {\n const { formAssociated, host: hostOptions, props: propDefs, setup, shadow: shadowOptions, styles } = definition;\n\n const observedAttrs = propDefs ? Object.keys(propDefs).map(toKebab) : [];\n\n return registerComponent(\n tag,\n () => {\n const props = propDefs ? createProps(propDefs) : ({} as ComponentProps<ResolveComponentProps<Props, PropDefs>>);\n const emit = createEmitFn<EventsType>();\n const host = createHost();\n let slotsApi: ComponentSlots | undefined;\n const slots: ComponentSlots = {\n elements: (name?: string) => {\n if (!slotsApi) slotsApi = createSlots();\n\n return slotsApi.elements(name);\n },\n has: (name?: string) => {\n if (!slotsApi) slotsApi = createSlots();\n\n return slotsApi.has(name);\n },\n };\n\n return setup({\n emit: emit as EmitFn<EventsType>,\n host,\n props: props as ComponentProps<ResolveComponentProps<Props, PropDefs>>,\n shadowRoot: host.shadowRoot,\n slots,\n } as ComponentSetupContext<ResolveComponentProps<Props, PropDefs>, EventsType, PropDefs>);\n },\n {\n formAssociated,\n host: hostOptions,\n observedAttrs,\n shadow: shadowOptions,\n styles,\n } satisfies ComponentRegistrationOptions,\n );\n};\n\nexport function define<\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n const PropDefs extends PropInputDefs = PropsInput<Props>,\n>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & { props: PropDefs }): string;\nexport function define<\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & { props?: PropDefs }): string;\nexport function define<\n Props extends Record<string, unknown> = Record<never, never>,\n EventsType extends Record<string, unknown> = Record<string, never>,\n PropDefs extends PropInputDefs = PropsInput<Props>,\n>(tag: string, definition: ComponentDefinition<Props, EventsType, PropDefs> & { props?: PropDefs }): string {\n return defineInternal(tag, definition);\n}\n"],"mappings":"iNAoEA,IAAM,GAKJ,EACA,IACW,CACX,GAAM,CAAE,iBAAgB,KAAM,EAAa,MAAO,EAAU,QAAO,OAAQ,EAAe,UAAW,EAIrG,OAAO,EACL,MACM,CACJ,IAAM,EAAQ,EAAW,EAAY,EAAS,CAAI,EAAE,CAC9C,EAAO,GAA0B,CACjC,EAAO,GAAY,CACrB,EAcJ,OAAO,EAAM,CACL,OACN,OACO,QACP,WAAY,EAAK,WACjB,MAlB4B,CAC5B,SAAW,IACT,AAAe,IAAW,GAAa,CAEhC,EAAS,SAAS,EAAK,EAEhC,IAAM,IACJ,AAAe,IAAW,GAAa,CAEhC,EAAS,IAAI,EAAK,EAE5B,CAQA,CAAwF,EAE3F,CACE,iBACA,KAAM,EACN,cAjCkB,EAAW,OAAO,KAAK,EAAS,CAAC,IAAI,EAAQ,CAAG,EAAE,CAkCpE,OAAQ,EACR,SACD,CACF,EAaH,SAAgB,EAId,EAAa,EAA6F,CAC1G,OAAO,EAAe,EAAK,EAAW"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../runtime-lifecycle.cjs`),t=require(`../internal.cjs`);var n=e=>{let t=e.querySelector(`slot`);return t instanceof HTMLSlotElement?t.assignedNodes({flatten:!0}).some(e=>(e.textContent?.trim().length??0)>0):(e.textContent?.trim().length??0)>0};function r(r,i){let a=i.labelId||t.createId(`a11y-label`),o=i.helperId||t.createId(`a11y-helper`),s=(e,t,n)=>{e.getAttribute(t)!==n&&e.setAttribute(t,n)},c=(e,t)=>{e.textContent!==t&&(e.textContent=t)};s(r,`role`,i.role);let l=()=>{let e=r.shadowRoot;if(!e)return;let t=e.querySelector(`[data-a11y-label]`),l=e.querySelector(`[data-a11y-helper]`),u=i.checked?.(),d=i.invalid?.(),f=i.helperText?.();t?(t.id!==a&&(t.id=a),n(t)?s(r,`aria-labelledby`,a):r.removeAttribute(`aria-labelledby`)):r.removeAttribute(`aria-labelledby`),l?(l.id!==o&&(l.id=o),f?(c(l,f),l.hidden&&=!1,s(r,`aria-describedby`,o),(i.helperTone?.()??`default`)===`error`?s(l,`role`,`alert`):l.removeAttribute(`role`)):(c(l,``),l.hidden||=!0,l.removeAttribute(`role`),r.removeAttribute(`aria-describedby`))):r.removeAttribute(`aria-describedby`),u===void 0?r.removeAttribute(`aria-checked`):s(r,`aria-checked`,u),d===void 0?r.removeAttribute(`aria-invalid`):s(r,`aria-invalid`,String(d))};return e.effect(()=>{l()}),e.onMount(()=>{let t=r.shadowRoot;if(!t)return;l();let n=[t.querySelector(`[data-a11y-label]`),t.querySelector(`[data-a11y-helper]`)].filter(Boolean);if(n.length===0)return;let i=new MutationObserver(()=>{l()});n.forEach(t=>{i.observe(t,{characterData:!0,childList:!0,subtree:!0});let n=t.querySelector(`slot`);if(n){let t=()=>l();n.addEventListener(`slotchange`,t),e.onCleanup(()=>n.removeEventListener(`slotchange`,t))}}),e.onCleanup(()=>i.disconnect())}),{helperId:o,labelId:a}}exports.createA11yControl=r;
|
|
2
|
+
//# sourceMappingURL=a11y-control.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y-control.cjs","names":[],"sources":["../../src/controls/a11y-control.ts"],"sourcesContent":["import { createId } from '../internal';\nimport { effect, onCleanup, onMount } from '../runtime-lifecycle';\n\nexport type A11yTone = 'default' | 'error';\n\nexport type A11yControlConfig = {\n checked?: () => 'true' | 'false' | 'mixed' | undefined;\n helperId?: string;\n helperText?: () => string | undefined;\n helperTone?: () => A11yTone;\n invalid?: () => boolean;\n labelId?: string;\n role: string;\n};\n\nexport type A11yControlHandle = {\n helperId: string;\n labelId: string;\n};\n\nconst hasLabelContent = (labelElement: HTMLElement): boolean => {\n const slot = labelElement.querySelector('slot');\n\n if (slot instanceof HTMLSlotElement) {\n return slot.assignedNodes({ flatten: true }).some((node) => (node.textContent?.trim().length ?? 0) > 0);\n }\n\n return (labelElement.textContent?.trim().length ?? 0) > 0;\n};\n\nexport function createA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle {\n const labelId = config.labelId || createId('a11y-label');\n const helperId = config.helperId || createId('a11y-helper');\n\n const setAttr = (element: Element, name: string, value: string): void => {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n };\n\n const setText = (element: Node, value: string): void => {\n if (element.textContent !== value) element.textContent = value;\n };\n\n setAttr(host, 'role', config.role);\n\n const sync = (): void => {\n const shadow = host.shadowRoot;\n\n if (!shadow) return;\n\n const labelElement = shadow.querySelector('[data-a11y-label]') as HTMLElement | null;\n const helperElement = shadow.querySelector('[data-a11y-helper]') as HTMLDivElement | null;\n const checked = config.checked?.();\n const invalid = config.invalid?.();\n const helperText = config.helperText?.();\n\n // Sync label\n if (labelElement) {\n if (labelElement.id !== labelId) labelElement.id = labelId;\n\n if (hasLabelContent(labelElement)) setAttr(host, 'aria-labelledby', labelId);\n else host.removeAttribute('aria-labelledby');\n } else {\n host.removeAttribute('aria-labelledby');\n }\n\n // Sync helper\n if (helperElement) {\n if (helperElement.id !== helperId) helperElement.id = helperId;\n\n if (helperText) {\n setText(helperElement, helperText);\n\n if (helperElement.hidden) helperElement.hidden = false;\n\n setAttr(host, 'aria-describedby', helperId);\n\n if ((config.helperTone?.() ?? 'default') === 'error') setAttr(helperElement, 'role', 'alert');\n else helperElement.removeAttribute('role');\n } else {\n setText(helperElement, '');\n\n if (!helperElement.hidden) helperElement.hidden = true;\n\n helperElement.removeAttribute('role');\n host.removeAttribute('aria-describedby');\n }\n } else {\n host.removeAttribute('aria-describedby');\n }\n\n // Sync checked\n if (checked === undefined) host.removeAttribute('aria-checked');\n else setAttr(host, 'aria-checked', checked);\n\n // Sync invalid\n if (invalid === undefined) host.removeAttribute('aria-invalid');\n else setAttr(host, 'aria-invalid', String(invalid));\n };\n\n // Effect for reactive config changes\n effect(() => {\n sync();\n });\n\n // Watch for DOM mutations to label/helper content (slot changes, etc.)\n onMount(() => {\n const shadow = host.shadowRoot;\n\n if (!shadow) return;\n\n sync();\n\n const labelElement = shadow.querySelector('[data-a11y-label]') as HTMLElement | null;\n const helperElement = shadow.querySelector('[data-a11y-helper]') as HTMLElement | null;\n\n const elementsToWatch = [labelElement, helperElement].filter(Boolean) as HTMLElement[];\n\n if (elementsToWatch.length === 0) return;\n\n const observer = new MutationObserver(() => {\n sync();\n });\n\n // Watch label and helper elements for content changes (including slot changes)\n elementsToWatch.forEach((el) => {\n observer.observe(el, { characterData: true, childList: true, subtree: true });\n\n // Also listen for slotchange event to catch slot content updates\n const slot = el.querySelector('slot') as HTMLSlotElement | null;\n\n if (slot) {\n const slotHandler = () => sync();\n\n slot.addEventListener('slotchange', slotHandler);\n onCleanup(() => slot.removeEventListener('slotchange', slotHandler));\n }\n });\n\n onCleanup(() => observer.disconnect());\n });\n\n return { helperId, labelId };\n}\n"],"mappings":"yEAoBA,IAAM,EAAmB,GAAuC,CAC9D,IAAM,EAAO,EAAa,cAAc,OAAO,CAM/C,OAJI,aAAgB,gBACX,EAAK,cAAc,CAAE,QAAS,GAAM,CAAC,CAAC,KAAM,IAAU,EAAK,aAAa,MAAM,CAAC,QAAU,GAAK,EAAE,EAGjG,EAAa,aAAa,MAAM,CAAC,QAAU,GAAK,GAG1D,SAAgB,EAAkB,EAAmB,EAA8C,CACjG,IAAM,EAAU,EAAO,SAAW,EAAA,SAAS,aAAa,CAClD,EAAW,EAAO,UAAY,EAAA,SAAS,cAAc,CAErD,GAAW,EAAkB,EAAc,IAAwB,CACnE,EAAQ,aAAa,EAAK,GAAK,GAAO,EAAQ,aAAa,EAAM,EAAM,EAGvE,GAAW,EAAe,IAAwB,CAClD,EAAQ,cAAgB,IAAO,EAAQ,YAAc,IAG3D,EAAQ,EAAM,OAAQ,EAAO,KAAK,CAElC,IAAM,MAAmB,CACvB,IAAM,EAAS,EAAK,WAEpB,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAe,EAAO,cAAc,oBAAoB,CACxD,EAAgB,EAAO,cAAc,qBAAqB,CAC1D,EAAU,EAAO,WAAW,CAC5B,EAAU,EAAO,WAAW,CAC5B,EAAa,EAAO,cAAc,CAGpC,GACE,EAAa,KAAO,IAAS,EAAa,GAAK,GAE/C,EAAgB,EAAa,CAAE,EAAQ,EAAM,kBAAmB,EAAQ,CACvE,EAAK,gBAAgB,kBAAkB,EAE5C,EAAK,gBAAgB,kBAAkB,CAIrC,GACE,EAAc,KAAO,IAAU,EAAc,GAAK,GAElD,GACF,EAAQ,EAAe,EAAW,CAElC,AAA0B,EAAc,SAAS,GAEjD,EAAQ,EAAM,mBAAoB,EAAS,EAEtC,EAAO,cAAc,EAAI,aAAe,QAAS,EAAQ,EAAe,OAAQ,QAAQ,CACxF,EAAc,gBAAgB,OAAO,GAE1C,EAAQ,EAAe,GAAG,CAE1B,AAA2B,EAAc,SAAS,GAElD,EAAc,gBAAgB,OAAO,CACrC,EAAK,gBAAgB,mBAAmB,GAG1C,EAAK,gBAAgB,mBAAmB,CAItC,IAAY,IAAA,GAAW,EAAK,gBAAgB,eAAe,CAC1D,EAAQ,EAAM,eAAgB,EAAQ,CAGvC,IAAY,IAAA,GAAW,EAAK,gBAAgB,eAAe,CAC1D,EAAQ,EAAM,eAAgB,OAAO,EAAQ,CAAC,EA6CrD,OAzCA,EAAA,WAAa,CACX,GAAM,EACN,CAGF,EAAA,YAAc,CACZ,IAAM,EAAS,EAAK,WAEpB,GAAI,CAAC,EAAQ,OAEb,GAAM,CAKN,IAAM,EAAkB,CAHH,EAAO,cAAc,oBAAoB,CACxC,EAAO,cAAc,qBAAqB,CAEX,CAAC,OAAO,QAAQ,CAErE,GAAI,EAAgB,SAAW,EAAG,OAElC,IAAM,EAAW,IAAI,qBAAuB,CAC1C,GAAM,EACN,CAGF,EAAgB,QAAS,GAAO,CAC9B,EAAS,QAAQ,EAAI,CAAE,cAAe,GAAM,UAAW,GAAM,QAAS,GAAM,CAAC,CAG7E,IAAM,EAAO,EAAG,cAAc,OAAO,CAErC,GAAI,EAAM,CACR,IAAM,MAAoB,GAAM,CAEhC,EAAK,iBAAiB,aAAc,EAAY,CAChD,EAAA,cAAgB,EAAK,oBAAoB,aAAc,EAAY,CAAC,GAEtE,CAEF,EAAA,cAAgB,EAAS,YAAY,CAAC,EACtC,CAEK,CAAE,WAAU,UAAS"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type A11yTone = 'default' | 'error';
|
|
2
|
+
export type A11yControlConfig = {
|
|
3
|
+
checked?: () => 'true' | 'false' | 'mixed' | undefined;
|
|
4
|
+
helperId?: string;
|
|
5
|
+
helperText?: () => string | undefined;
|
|
6
|
+
helperTone?: () => A11yTone;
|
|
7
|
+
invalid?: () => boolean;
|
|
8
|
+
labelId?: string;
|
|
9
|
+
role: string;
|
|
10
|
+
};
|
|
11
|
+
export type A11yControlHandle = {
|
|
12
|
+
helperId: string;
|
|
13
|
+
labelId: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function createA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle;
|
|
16
|
+
//# sourceMappingURL=a11y-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y-control.d.ts","sourceRoot":"","sources":["../../src/controls/a11y-control.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,QAAQ,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAYF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAgHjG"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{effect as e,onCleanup as t,onMount as n}from"../runtime-lifecycle.js";import{createId as r}from"../internal.js";var i=e=>{let t=e.querySelector(`slot`);return t instanceof HTMLSlotElement?t.assignedNodes({flatten:!0}).some(e=>(e.textContent?.trim().length??0)>0):(e.textContent?.trim().length??0)>0};function a(a,o){let s=o.labelId||r(`a11y-label`),c=o.helperId||r(`a11y-helper`),l=(e,t,n)=>{e.getAttribute(t)!==n&&e.setAttribute(t,n)},u=(e,t)=>{e.textContent!==t&&(e.textContent=t)};l(a,`role`,o.role);let d=()=>{let e=a.shadowRoot;if(!e)return;let t=e.querySelector(`[data-a11y-label]`),n=e.querySelector(`[data-a11y-helper]`),r=o.checked?.(),d=o.invalid?.(),f=o.helperText?.();t?(t.id!==s&&(t.id=s),i(t)?l(a,`aria-labelledby`,s):a.removeAttribute(`aria-labelledby`)):a.removeAttribute(`aria-labelledby`),n?(n.id!==c&&(n.id=c),f?(u(n,f),n.hidden&&=!1,l(a,`aria-describedby`,c),(o.helperTone?.()??`default`)===`error`?l(n,`role`,`alert`):n.removeAttribute(`role`)):(u(n,``),n.hidden||=!0,n.removeAttribute(`role`),a.removeAttribute(`aria-describedby`))):a.removeAttribute(`aria-describedby`),r===void 0?a.removeAttribute(`aria-checked`):l(a,`aria-checked`,r),d===void 0?a.removeAttribute(`aria-invalid`):l(a,`aria-invalid`,String(d))};return e(()=>{d()}),n(()=>{let e=a.shadowRoot;if(!e)return;d();let n=[e.querySelector(`[data-a11y-label]`),e.querySelector(`[data-a11y-helper]`)].filter(Boolean);if(n.length===0)return;let r=new MutationObserver(()=>{d()});n.forEach(e=>{r.observe(e,{characterData:!0,childList:!0,subtree:!0});let n=e.querySelector(`slot`);if(n){let e=()=>d();n.addEventListener(`slotchange`,e),t(()=>n.removeEventListener(`slotchange`,e))}}),t(()=>r.disconnect())}),{helperId:c,labelId:s}}export{a as createA11yControl};
|
|
2
|
+
//# sourceMappingURL=a11y-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y-control.js","names":[],"sources":["../../src/controls/a11y-control.ts"],"sourcesContent":["import { createId } from '../internal';\nimport { effect, onCleanup, onMount } from '../runtime-lifecycle';\n\nexport type A11yTone = 'default' | 'error';\n\nexport type A11yControlConfig = {\n checked?: () => 'true' | 'false' | 'mixed' | undefined;\n helperId?: string;\n helperText?: () => string | undefined;\n helperTone?: () => A11yTone;\n invalid?: () => boolean;\n labelId?: string;\n role: string;\n};\n\nexport type A11yControlHandle = {\n helperId: string;\n labelId: string;\n};\n\nconst hasLabelContent = (labelElement: HTMLElement): boolean => {\n const slot = labelElement.querySelector('slot');\n\n if (slot instanceof HTMLSlotElement) {\n return slot.assignedNodes({ flatten: true }).some((node) => (node.textContent?.trim().length ?? 0) > 0);\n }\n\n return (labelElement.textContent?.trim().length ?? 0) > 0;\n};\n\nexport function createA11yControl(host: HTMLElement, config: A11yControlConfig): A11yControlHandle {\n const labelId = config.labelId || createId('a11y-label');\n const helperId = config.helperId || createId('a11y-helper');\n\n const setAttr = (element: Element, name: string, value: string): void => {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n };\n\n const setText = (element: Node, value: string): void => {\n if (element.textContent !== value) element.textContent = value;\n };\n\n setAttr(host, 'role', config.role);\n\n const sync = (): void => {\n const shadow = host.shadowRoot;\n\n if (!shadow) return;\n\n const labelElement = shadow.querySelector('[data-a11y-label]') as HTMLElement | null;\n const helperElement = shadow.querySelector('[data-a11y-helper]') as HTMLDivElement | null;\n const checked = config.checked?.();\n const invalid = config.invalid?.();\n const helperText = config.helperText?.();\n\n // Sync label\n if (labelElement) {\n if (labelElement.id !== labelId) labelElement.id = labelId;\n\n if (hasLabelContent(labelElement)) setAttr(host, 'aria-labelledby', labelId);\n else host.removeAttribute('aria-labelledby');\n } else {\n host.removeAttribute('aria-labelledby');\n }\n\n // Sync helper\n if (helperElement) {\n if (helperElement.id !== helperId) helperElement.id = helperId;\n\n if (helperText) {\n setText(helperElement, helperText);\n\n if (helperElement.hidden) helperElement.hidden = false;\n\n setAttr(host, 'aria-describedby', helperId);\n\n if ((config.helperTone?.() ?? 'default') === 'error') setAttr(helperElement, 'role', 'alert');\n else helperElement.removeAttribute('role');\n } else {\n setText(helperElement, '');\n\n if (!helperElement.hidden) helperElement.hidden = true;\n\n helperElement.removeAttribute('role');\n host.removeAttribute('aria-describedby');\n }\n } else {\n host.removeAttribute('aria-describedby');\n }\n\n // Sync checked\n if (checked === undefined) host.removeAttribute('aria-checked');\n else setAttr(host, 'aria-checked', checked);\n\n // Sync invalid\n if (invalid === undefined) host.removeAttribute('aria-invalid');\n else setAttr(host, 'aria-invalid', String(invalid));\n };\n\n // Effect for reactive config changes\n effect(() => {\n sync();\n });\n\n // Watch for DOM mutations to label/helper content (slot changes, etc.)\n onMount(() => {\n const shadow = host.shadowRoot;\n\n if (!shadow) return;\n\n sync();\n\n const labelElement = shadow.querySelector('[data-a11y-label]') as HTMLElement | null;\n const helperElement = shadow.querySelector('[data-a11y-helper]') as HTMLElement | null;\n\n const elementsToWatch = [labelElement, helperElement].filter(Boolean) as HTMLElement[];\n\n if (elementsToWatch.length === 0) return;\n\n const observer = new MutationObserver(() => {\n sync();\n });\n\n // Watch label and helper elements for content changes (including slot changes)\n elementsToWatch.forEach((el) => {\n observer.observe(el, { characterData: true, childList: true, subtree: true });\n\n // Also listen for slotchange event to catch slot content updates\n const slot = el.querySelector('slot') as HTMLSlotElement | null;\n\n if (slot) {\n const slotHandler = () => sync();\n\n slot.addEventListener('slotchange', slotHandler);\n onCleanup(() => slot.removeEventListener('slotchange', slotHandler));\n }\n });\n\n onCleanup(() => observer.disconnect());\n });\n\n return { helperId, labelId };\n}\n"],"mappings":"uHAoBA,IAAM,EAAmB,GAAuC,CAC9D,IAAM,EAAO,EAAa,cAAc,OAAO,CAM/C,OAJI,aAAgB,gBACX,EAAK,cAAc,CAAE,QAAS,GAAM,CAAC,CAAC,KAAM,IAAU,EAAK,aAAa,MAAM,CAAC,QAAU,GAAK,EAAE,EAGjG,EAAa,aAAa,MAAM,CAAC,QAAU,GAAK,GAG1D,SAAgB,EAAkB,EAAmB,EAA8C,CACjG,IAAM,EAAU,EAAO,SAAW,EAAS,aAAa,CAClD,EAAW,EAAO,UAAY,EAAS,cAAc,CAErD,GAAW,EAAkB,EAAc,IAAwB,CACnE,EAAQ,aAAa,EAAK,GAAK,GAAO,EAAQ,aAAa,EAAM,EAAM,EAGvE,GAAW,EAAe,IAAwB,CAClD,EAAQ,cAAgB,IAAO,EAAQ,YAAc,IAG3D,EAAQ,EAAM,OAAQ,EAAO,KAAK,CAElC,IAAM,MAAmB,CACvB,IAAM,EAAS,EAAK,WAEpB,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAe,EAAO,cAAc,oBAAoB,CACxD,EAAgB,EAAO,cAAc,qBAAqB,CAC1D,EAAU,EAAO,WAAW,CAC5B,EAAU,EAAO,WAAW,CAC5B,EAAa,EAAO,cAAc,CAGpC,GACE,EAAa,KAAO,IAAS,EAAa,GAAK,GAE/C,EAAgB,EAAa,CAAE,EAAQ,EAAM,kBAAmB,EAAQ,CACvE,EAAK,gBAAgB,kBAAkB,EAE5C,EAAK,gBAAgB,kBAAkB,CAIrC,GACE,EAAc,KAAO,IAAU,EAAc,GAAK,GAElD,GACF,EAAQ,EAAe,EAAW,CAElC,AAA0B,EAAc,SAAS,GAEjD,EAAQ,EAAM,mBAAoB,EAAS,EAEtC,EAAO,cAAc,EAAI,aAAe,QAAS,EAAQ,EAAe,OAAQ,QAAQ,CACxF,EAAc,gBAAgB,OAAO,GAE1C,EAAQ,EAAe,GAAG,CAE1B,AAA2B,EAAc,SAAS,GAElD,EAAc,gBAAgB,OAAO,CACrC,EAAK,gBAAgB,mBAAmB,GAG1C,EAAK,gBAAgB,mBAAmB,CAItC,IAAY,IAAA,GAAW,EAAK,gBAAgB,eAAe,CAC1D,EAAQ,EAAM,eAAgB,EAAQ,CAGvC,IAAY,IAAA,GAAW,EAAK,gBAAgB,eAAe,CAC1D,EAAQ,EAAM,eAAgB,OAAO,EAAQ,CAAC,EA6CrD,OAzCA,MAAa,CACX,GAAM,EACN,CAGF,MAAc,CACZ,IAAM,EAAS,EAAK,WAEpB,GAAI,CAAC,EAAQ,OAEb,GAAM,CAKN,IAAM,EAAkB,CAHH,EAAO,cAAc,oBAAoB,CACxC,EAAO,cAAc,qBAAqB,CAEX,CAAC,OAAO,QAAQ,CAErE,GAAI,EAAgB,SAAW,EAAG,OAElC,IAAM,EAAW,IAAI,qBAAuB,CAC1C,GAAM,EACN,CAGF,EAAgB,QAAS,GAAO,CAC9B,EAAS,QAAQ,EAAI,CAAE,cAAe,GAAM,UAAW,GAAM,QAAS,GAAM,CAAC,CAG7E,IAAM,EAAO,EAAG,cAAc,OAAO,CAErC,GAAI,EAAM,CACR,IAAM,MAAoB,GAAM,CAEhC,EAAK,iBAAiB,aAAc,EAAY,CAChD,MAAgB,EAAK,oBAAoB,aAAc,EAAY,CAAC,GAEtE,CAEF,MAAgB,EAAS,YAAY,CAAC,EACtC,CAEK,CAAE,WAAU,UAAS"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./a11y-control.cjs`),t=require(`./field-control.cjs`),n=require(`./press-control.cjs`);var r=r=>{let i=t.createCheckableStateControl(r);return{a11y:e.createA11yControl(r.host,{checked:()=>r.role===`checkbox`&&i.indeterminate.value?`mixed`:i.checked.value?`true`:`false`,helperText:()=>i.assistive.value.text,helperTone:()=>i.assistive.value.isError?`error`:`default`,invalid:()=>i.assistive.value.isError,role:r.role}),control:i,press:n.createPressControl({disabled:()=>i.disabled.value,onPress:e=>{if(r.onPress){r.onPress(i,e);return}i.toggle(e)}})}};exports.createCheckableFieldControl=r;
|
|
2
|
+
//# sourceMappingURL=checkable-control.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkable-control.cjs","names":[],"sources":["../../src/controls/checkable-control.ts"],"sourcesContent":["import { createA11yControl, type A11yControlHandle } from './a11y-control';\nimport { createCheckableStateControl, type CheckableStateHandle, type CheckableStateOptions } from './field-control';\nimport { createPressControl, type PressControl } from './press-control';\n\nexport type CheckableFieldControlOptions = CheckableStateOptions & {\n host: HTMLElement;\n onPress?: (control: CheckableStateHandle, originalEvent: Event) => void;\n role: 'checkbox' | 'radio' | 'switch';\n};\n\nexport type CheckableFieldControlHandle = {\n a11y: A11yControlHandle;\n control: CheckableStateHandle;\n press: PressControl;\n};\n\nexport const createCheckableFieldControl = (options: CheckableFieldControlOptions): CheckableFieldControlHandle => {\n const control = createCheckableStateControl(options);\n const a11y = createA11yControl(options.host, {\n checked: () => {\n if (options.role === 'checkbox' && control.indeterminate.value) return 'mixed';\n\n return control.checked.value ? 'true' : 'false';\n },\n helperText: () => control.assistive.value.text,\n helperTone: () => (control.assistive.value.isError ? 'error' : 'default'),\n invalid: () => control.assistive.value.isError,\n role: options.role,\n });\n const press = createPressControl({\n disabled: () => control.disabled.value,\n onPress: (originalEvent) => {\n if (options.onPress) {\n options.onPress(control, originalEvent);\n\n return;\n }\n\n control.toggle(originalEvent);\n },\n });\n\n return { a11y, control, press };\n};\n"],"mappings":"wGAgBA,IAAa,EAA+B,GAAuE,CACjH,IAAM,EAAU,EAAA,4BAA4B,EAAQ,CAyBpD,MAAO,CAAE,KAxBI,EAAA,kBAAkB,EAAQ,KAAM,CAC3C,YACM,EAAQ,OAAS,YAAc,EAAQ,cAAc,MAAc,QAEhE,EAAQ,QAAQ,MAAQ,OAAS,QAE1C,eAAkB,EAAQ,UAAU,MAAM,KAC1C,eAAmB,EAAQ,UAAU,MAAM,QAAU,QAAU,UAC/D,YAAe,EAAQ,UAAU,MAAM,QACvC,KAAM,EAAQ,KACf,CAAC,CAca,UAAS,MAbV,EAAA,mBAAmB,CAC/B,aAAgB,EAAQ,SAAS,MACjC,QAAU,GAAkB,CAC1B,GAAI,EAAQ,QAAS,CACnB,EAAQ,QAAQ,EAAS,EAAc,CAEvC,OAGF,EAAQ,OAAO,EAAc,EAEhC,CAAC,CAE6B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type A11yControlHandle } from './a11y-control';
|
|
2
|
+
import { type CheckableStateHandle, type CheckableStateOptions } from './field-control';
|
|
3
|
+
import { type PressControl } from './press-control';
|
|
4
|
+
export type CheckableFieldControlOptions = CheckableStateOptions & {
|
|
5
|
+
host: HTMLElement;
|
|
6
|
+
onPress?: (control: CheckableStateHandle, originalEvent: Event) => void;
|
|
7
|
+
role: 'checkbox' | 'radio' | 'switch';
|
|
8
|
+
};
|
|
9
|
+
export type CheckableFieldControlHandle = {
|
|
10
|
+
a11y: A11yControlHandle;
|
|
11
|
+
control: CheckableStateHandle;
|
|
12
|
+
press: PressControl;
|
|
13
|
+
};
|
|
14
|
+
export declare const createCheckableFieldControl: (options: CheckableFieldControlOptions) => CheckableFieldControlHandle;
|
|
15
|
+
//# sourceMappingURL=checkable-control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkable-control.d.ts","sourceRoot":"","sources":["../../src/controls/checkable-control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAA+B,KAAK,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACrH,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAExE,MAAM,MAAM,4BAA4B,GAAG,qBAAqB,GAAG;IACjE,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,KAAK,KAAK,IAAI,CAAC;IACxE,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,SAAS,4BAA4B,KAAG,2BA2BnF,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createA11yControl as e}from"./a11y-control.js";import{createCheckableStateControl as t}from"./field-control.js";import{createPressControl as n}from"./press-control.js";var r=r=>{let i=t(r);return{a11y:e(r.host,{checked:()=>r.role===`checkbox`&&i.indeterminate.value?`mixed`:i.checked.value?`true`:`false`,helperText:()=>i.assistive.value.text,helperTone:()=>i.assistive.value.isError?`error`:`default`,invalid:()=>i.assistive.value.isError,role:r.role}),control:i,press:n({disabled:()=>i.disabled.value,onPress:e=>{if(r.onPress){r.onPress(i,e);return}i.toggle(e)}})}};export{r as createCheckableFieldControl};
|
|
2
|
+
//# sourceMappingURL=checkable-control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkable-control.js","names":[],"sources":["../../src/controls/checkable-control.ts"],"sourcesContent":["import { createA11yControl, type A11yControlHandle } from './a11y-control';\nimport { createCheckableStateControl, type CheckableStateHandle, type CheckableStateOptions } from './field-control';\nimport { createPressControl, type PressControl } from './press-control';\n\nexport type CheckableFieldControlOptions = CheckableStateOptions & {\n host: HTMLElement;\n onPress?: (control: CheckableStateHandle, originalEvent: Event) => void;\n role: 'checkbox' | 'radio' | 'switch';\n};\n\nexport type CheckableFieldControlHandle = {\n a11y: A11yControlHandle;\n control: CheckableStateHandle;\n press: PressControl;\n};\n\nexport const createCheckableFieldControl = (options: CheckableFieldControlOptions): CheckableFieldControlHandle => {\n const control = createCheckableStateControl(options);\n const a11y = createA11yControl(options.host, {\n checked: () => {\n if (options.role === 'checkbox' && control.indeterminate.value) return 'mixed';\n\n return control.checked.value ? 'true' : 'false';\n },\n helperText: () => control.assistive.value.text,\n helperTone: () => (control.assistive.value.isError ? 'error' : 'default'),\n invalid: () => control.assistive.value.isError,\n role: options.role,\n });\n const press = createPressControl({\n disabled: () => control.disabled.value,\n onPress: (originalEvent) => {\n if (options.onPress) {\n options.onPress(control, originalEvent);\n\n return;\n }\n\n control.toggle(originalEvent);\n },\n });\n\n return { a11y, control, press };\n};\n"],"mappings":"+KAgBA,IAAa,EAA+B,GAAuE,CACjH,IAAM,EAAU,EAA4B,EAAQ,CAyBpD,MAAO,CAAE,KAxBI,EAAkB,EAAQ,KAAM,CAC3C,YACM,EAAQ,OAAS,YAAc,EAAQ,cAAc,MAAc,QAEhE,EAAQ,QAAQ,MAAQ,OAAS,QAE1C,eAAkB,EAAQ,UAAU,MAAM,KAC1C,eAAmB,EAAQ,UAAU,MAAM,QAAU,QAAU,UAC/D,YAAe,EAAQ,UAAU,MAAM,QACvC,KAAM,EAAQ,KACf,CAAC,CAca,UAAS,MAbV,EAAmB,CAC/B,aAAgB,EAAQ,SAAS,MACjC,QAAU,GAAkB,CAC1B,GAAI,EAAQ,QAAS,CACnB,EAAQ,QAAQ,EAAS,EAAc,CAEvC,OAGF,EAAQ,OAAO,EAAc,EAEhC,CAAC,CAE6B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../runtime-lifecycle.cjs`),t=require(`../internal.cjs`),n=require(`../directives/spread.cjs`),r=require(`../form.cjs`),i=require(`./internal/control-state.cjs`);let a=require(`@vielzeug/stateit`);var o=(e,n)=>{let r=`${e}-${n&&n.trim()?n.trim():t.createId().replace(/^cft-/,``)}`,i=`label-${r}`;return{errorId:`error-${r}`,fieldId:r,helperId:`helper-${r}`,labelInsetId:i,labelOutsideId:`${i}-outside`}},s=n=>{let r=i.createControlState(n),a=o(n.prefix,n.name?.value),s=t.ref(),c=t.ref();return e.effect(()=>{let e=n.labelPlacement?.value??`inset`,t=n.label?.value??``;s.value&&(s.value.textContent=t,s.value.hidden=!t||e!==`inset`),c.value&&(c.value.textContent=t,c.value.hidden=!t||e!==`outside`)}),{disabled:r.disabled,errorId:a.errorId,fieldId:a.fieldId,helperId:a.helperId,labelInsetId:a.labelInsetId,labelInsetRef:s,labelOutsideId:a.labelOutsideId,labelOutsideRef:c,triggerValidation:(e,t)=>r.triggerValidation(e,t),validateOn:r.validateOn}},c=e=>({disabled:(0,a.computed)(()=>!!e.disabled?.value||!!e.context?.disabled?.value),validateOn:e.validateOn??e.context?.validateOn}),l=e=>(0,a.computed)(()=>{let t=e.value?.value??``,n=e.error?.value??``,r=e.helper?.value??``,i=!!n,a=!!r,o=n||r||``,s=e.maxLength?.value,c=Number(s),l=Number.isFinite(c)&&c>0?c:null,u=l!==null,d=u?`${t.length} / ${l}`:``,f=u?t.length/l:0;return{counterAtLimit:u?f>=1:!1,counterNearLimit:u?f>=.9&&f<1:!1,counterText:d,errorText:n,hasCounter:u,hasError:i,hasHelper:a,helperText:r,hidden:!o,isError:i,showHelper:!i&&a,text:o}}),u=e=>{if(e!==void 0)return(0,a.isSignal)(e)?e.value:typeof e==`function`?e():e},d=e=>()=>{let t=u(e);if(!(t==null||t===``))return String(t)},f=e=>()=>{let t=u(e);if(!(t==null||Number.isNaN(Number(t))||Number(t)<=0))return Number(t)},p=t=>{let i=(0,a.signal)(``),o=c(t),u=s({...t,...o});e.watch(t.value,e=>{i.value=String(e??``)},{immediate:!0});let p=r.defineField({disabled:u.disabled,value:i},{onReset:()=>{i.value=``,t.onReset?.()}}),h=l({error:t.error,helper:t.helper,maxLength:t.maxLength,value:i}),g=e=>{e?.preventDefault?.(),i.value=``,t.onInput?.(e??new Event(`input`),``),t.onChange?.(e??new Event(`change`),``),u.triggerValidation(p,`change`),t.elementRef?.value?.focus()};return t.elementRef&&e.onElement(t.elementRef,e=>{m({element:e,onBlur:t.onBlur,onChange:t.onChange,onInput:(e,n)=>{t.onInputExtra?.(e),t.onInput?.(e,n)},triggerValidation:e=>u.triggerValidation(p,e)})}),{assistive:h,attrs:n.spread({"?required":t.required,".disabled":t.disabled,".readOnly":t.readOnly,".type":t.type,".value":i,autocomplete:d(t.autocomplete),inputmode:d(t.inputmode),maxlength:f(t.maxLength),minlength:f(t.minLength),name:d(t.name),pattern:d(t.pattern),placeholder:d(t.placeholder),rows:f(t.rows)}),...u,clear:g,field:p,triggerValidation:e=>u.triggerValidation(p,e),value:i}},m=t=>{let{element:n,onBlur:r,onChange:i,onInput:a,triggerValidation:o}=t;a&&e.handle(n,`input`,e=>{a(e,n.value)}),e.handle(n,`change`,e=>{i?.(e,n.value),o?.(`change`)}),e.handle(n,`blur`,e=>{r?.(e),o?.(`blur`)})},h=e=>e?e.split(`,`).map(e=>e.trim()).filter(Boolean):[],g=t=>{let n=s({...c(t),label:t.label,labelPlacement:t.labelPlacement,name:t.name,prefix:t.prefix}),i=(0,a.signal)([]),o=(0,a.computed)(()=>!!t.multiple?.value),u=(0,a.computed)(()=>i.value.map(e=>t.getValue(e))),d=(0,a.computed)(()=>o.value?u.value.join(`,`):u.value[0]??``),f=e=>{let n=o.value?e:e.slice(0,1),r=[],i=new Set;for(let e of n){let n=t.getValue(e);i.has(n)||(i.add(n),r.push(e))}return r},p=e=>{i.value=f(e)},m=()=>{p([])},g=e=>{i.value=i.value.filter(n=>t.getValue(n)!==e)},_=e=>{if(o.value){let n=t.getValue(e);if(i.value.some(e=>t.getValue(e)===n))return;p([...i.value,e]);return}p([e])},v=e=>{if(o.value){let n=t.getValue(e);if(i.value.some(e=>t.getValue(e)===n)){g(n);return}p([...i.value,e]);return}p([e])},y=e=>{p(h(typeof e==`string`?e:String(e??``)).map(e=>t.mapControlledValue(e)))},b=r.defineField({disabled:n.disabled,value:d},{onReset:()=>{m(),t.onReset?.()}}),x=l({error:t.error,helper:t.helper});return e.watch(t.value,e=>{y(e)},{immediate:!0}),t.multiple&&e.watch(t.multiple,()=>y(t.value.value)),{...n,assistive:x,clear:m,field:b,formValue:d,isMultiple:o,isSelected:e=>i.value.some(n=>t.getValue(n)===e),removeValue:g,replaceSelectedItems:p,selectedItems:i,selectedValues:u,selectItem:_,toggleItem:v,triggerValidation:e=>n.triggerValidation(b,e)}},_=t=>{let n=(0,a.signal)(``),i=s(t),o=(0,a.signal)(!!t.checked.value),c=(0,a.signal)(!!t.indeterminate?.value),u=l({error:t.error,helper:t.helper});e.watch(t.checked,e=>{o.value=!!e},{immediate:!0}),t.indeterminate&&e.watch(t.indeterminate,e=>{c.value=!!e},{immediate:!0});let d=r.defineField({disabled:i.disabled,toFormValue:e=>e,value:(0,a.computed)(()=>o.value?t.value.value??``:null)},{onReset:()=>{o.value=!!t.checked.value,c.value=!!t.indeterminate?.value,t.onReset?.()}});e.watch(t.value,e=>{n.value=String(e??``)},{immediate:!0});let f=e=>({checked:o.value,fieldValue:t.value.value??``,originalEvent:e}),p=e=>{if(!i.disabled.value){if(t.group){c.value=!1,t.group.toggle(t.value.value??``,e),t.onToggle?.(f(e));return}t.clearIndeterminateFirst&&c.value||(o.value=!o.value),c.value=!1,t.onToggle?.(f(e))}};return{...i,assistive:u,checked:o,field:d,indeterminate:c,toggle:p,triggerValidation:e=>i.triggerValidation(d,e),value:n}};exports.createCheckableStateControl=_,exports.createChoiceFieldControl=g,exports.createTextFieldControl=p,exports.mountTextFieldLifecycle=m;
|
|
2
|
+
//# sourceMappingURL=field-control.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-control.cjs","names":[],"sources":["../../src/controls/field-control.ts"],"sourcesContent":["import { computed, isSignal, type ReadonlySignal, type Signal, signal } from '@vielzeug/stateit';\n\nimport { spread } from '../directives/spread';\nimport { defineField, type FormFieldHandle } from '../form';\nimport { createId, ref, type Directive } from '../internal';\nimport { effect, handle, onElement, watch } from '../runtime-lifecycle';\nimport {\n createControlState,\n type ControlContextOptions,\n type ControlValidationMode,\n type FormControlValidationTrigger,\n} from './internal/control-state';\n\nexport type { FormControlValidationTrigger } from './internal/control-state';\nexport { createValidationControl } from './internal/control-state';\nexport type { ValidationReporter } from './internal/control-state';\n\n// Discriminated union types for text vs checkable variants\nexport type TextFieldControlContext = {\n disabled?: ReadonlySignal<boolean | undefined>;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n};\n\nexport type TextFieldOptions = Omit<ControlContextOptions, 'disabled' | 'validateOn'> & {\n autocomplete?: ReadonlySignal<string | undefined>;\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n elementRef?: { value: HTMLInputElement | HTMLTextAreaElement | null };\n error?: ReadonlySignal<string | undefined>;\n helper?: ReadonlySignal<string | undefined>;\n inputmode?: ReadonlySignal<string | undefined>;\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n maxLength?: ReadonlySignal<number | undefined>;\n minLength?: ReadonlySignal<number | undefined>;\n name?: ReadonlySignal<string | undefined>;\n onBlur?: (event: FocusEvent) => void;\n onChange?: (event: Event, value: string) => void;\n onInput?: (event: Event, value: string) => void;\n onInputExtra?: (event: Event) => void;\n onReset?: () => void;\n pattern?: ReadonlySignal<string | undefined>;\n placeholder?: ReadonlySignal<string | undefined>;\n prefix: string;\n readOnly?: ReadonlySignal<boolean | undefined>;\n required?: ReadonlySignal<boolean | undefined>;\n rows?: ReadonlySignal<number | undefined>;\n type?: ReadonlySignal<string | undefined> | (() => string | undefined) | string;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type ChoiceFieldOptions<T> = {\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n error?: ReadonlySignal<string | undefined>;\n getValue: (item: T) => string;\n helper?: ReadonlySignal<string | undefined>;\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n mapControlledValue: (value: string) => T;\n multiple?: ReadonlySignal<boolean | undefined>;\n name?: ReadonlySignal<string | undefined>;\n onReset?: () => void;\n prefix: string;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableStateOptions = ControlContextOptions & {\n checked: ReadonlySignal<boolean | undefined>;\n clearIndeterminateFirst?: boolean;\n error?: ReadonlySignal<string | undefined>;\n group?: { toggle: (value: string, originalEvent?: Event) => void };\n helper?: ReadonlySignal<string | undefined>;\n indeterminate?: ReadonlySignal<boolean | undefined>;\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n name?: ReadonlySignal<string | undefined>;\n onReset?: () => void;\n onToggle?: (payload: CheckableChangePayload) => void;\n prefix: string;\n value: ReadonlySignal<string | undefined>;\n};\n\nexport type CheckableChangePayload = {\n checked: boolean;\n fieldValue: string;\n originalEvent?: Event;\n};\n\nexport type FieldControlBaseHandle = {\n disabled: ReadonlySignal<boolean>;\n errorId: string;\n field: FormFieldHandle;\n fieldId: string;\n helperId: string;\n labelInsetId: string;\n labelInsetRef: { value: HTMLLabelElement | null };\n labelOutsideId: string;\n labelOutsideRef: { value: HTMLLabelElement | null };\n triggerValidation: (on: FormControlValidationTrigger) => void;\n validateOn: ReadonlySignal<ControlValidationMode> | undefined;\n};\n\nexport type TextFieldHandle = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n attrs: Directive;\n clear: (event?: Event) => void;\n value: Signal<string>;\n};\n\nexport type AssistiveState = {\n counterAtLimit: boolean;\n counterNearLimit: boolean;\n counterText: string;\n errorText: string;\n hasCounter: boolean;\n hasError: boolean;\n hasHelper: boolean;\n helperText: string;\n hidden: boolean;\n isError: boolean;\n showHelper: boolean;\n text: string;\n};\n\nexport type AssistiveOptions = {\n error?: ReadonlySignal<string | undefined>;\n helper?: ReadonlySignal<string | undefined>;\n maxLength?: ReadonlySignal<number | undefined>;\n value?: ReadonlySignal<string | undefined>;\n};\n\nexport type TextFieldLifecycleOptions = {\n element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\n onBlur?: (event: FocusEvent) => void;\n onChange?: (event: Event, value: string) => void;\n onInput?: (event: Event, value: string) => void;\n triggerValidation?: (on: FormControlValidationTrigger) => void;\n};\n\nexport type CheckableStateHandle = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n checked: Signal<boolean>;\n indeterminate: Signal<boolean>;\n toggle: (event: Event) => void;\n value: Signal<string>;\n};\n\nexport type ChoiceFieldHandle<T> = FieldControlBaseHandle & {\n assistive: ReadonlySignal<AssistiveState>;\n clear: () => void;\n field: FormFieldHandle;\n formValue: ReadonlySignal<string>;\n isMultiple: ReadonlySignal<boolean>;\n isSelected: (value: string) => boolean;\n removeValue: (value: string) => void;\n replaceSelectedItems: (items: T[]) => void;\n selectedItems: Signal<T[]>;\n selectedValues: ReadonlySignal<string[]>;\n selectItem: (item: T) => void;\n toggleItem: (item: T) => void;\n};\n\ntype ReactiveValue<T> = ReadonlySignal<T> | (() => T) | T;\n\n/**\n * Generates a stable set of ARIA-related IDs for a field control.\n * Snapshot `name` at call time — IDs are stable strings, not reactive.\n */\nconst createFieldIds = (prefix: string, name?: string | null) => {\n const normalizedName = name && name.trim() ? name.trim() : createId().replace(/^cft-/, '');\n const fieldId = `${prefix}-${normalizedName}`;\n const labelInsetId = `label-${fieldId}`;\n\n return {\n errorId: `error-${fieldId}`,\n fieldId,\n helperId: `helper-${fieldId}`,\n labelInsetId,\n labelOutsideId: `${labelInsetId}-outside`,\n };\n};\n\nconst createBaseFieldHandle = (\n options: {\n label?: ReadonlySignal<string | undefined>;\n labelPlacement?: ReadonlySignal<'inset' | 'outside' | undefined>;\n name?: ReadonlySignal<string | undefined>;\n prefix: string;\n } & ControlContextOptions,\n) => {\n const controlState = createControlState(options);\n const ids = createFieldIds(options.prefix, options.name?.value);\n const labelInsetRef = ref<HTMLLabelElement>();\n const labelOutsideRef = ref<HTMLLabelElement>();\n\n const syncLabels = () => {\n const placement = options.labelPlacement?.value ?? 'inset';\n const text = options.label?.value ?? '';\n\n if (labelInsetRef.value) {\n labelInsetRef.value.textContent = text;\n labelInsetRef.value.hidden = !text || placement !== 'inset';\n }\n\n if (labelOutsideRef.value) {\n labelOutsideRef.value.textContent = text;\n labelOutsideRef.value.hidden = !text || placement !== 'outside';\n }\n };\n\n effect(syncLabels);\n\n return {\n disabled: controlState.disabled,\n errorId: ids.errorId,\n fieldId: ids.fieldId,\n helperId: ids.helperId,\n labelInsetId: ids.labelInsetId,\n labelInsetRef,\n labelOutsideId: ids.labelOutsideId,\n labelOutsideRef,\n triggerValidation: (field: FormFieldHandle, on: FormControlValidationTrigger) =>\n controlState.triggerValidation(field, on),\n validateOn: controlState.validateOn,\n };\n};\n\nconst resolveControlContext = (options: {\n context?: TextFieldControlContext;\n disabled?: ReadonlySignal<boolean | undefined>;\n validateOn?: ReadonlySignal<ControlValidationMode>;\n}) => {\n return {\n disabled: computed(() => Boolean(options.disabled?.value) || Boolean(options.context?.disabled?.value)),\n validateOn: options.validateOn ?? options.context?.validateOn,\n };\n};\n\nexport const createAssistiveState = (options: AssistiveOptions) => {\n return computed<AssistiveState>(() => {\n const value = options.value?.value ?? '';\n const errorText = options.error?.value ?? '';\n const helperText = options.helper?.value ?? '';\n const hasError = Boolean(errorText);\n const hasHelper = Boolean(helperText);\n const text = errorText || helperText || '';\n const maxLength = options.maxLength?.value;\n const parsedMaxLength = Number(maxLength);\n const validMaxLength = Number.isFinite(parsedMaxLength) && parsedMaxLength > 0 ? parsedMaxLength : null;\n const hasCounter = validMaxLength !== null;\n const counterText = hasCounter ? `${value.length} / ${validMaxLength}` : '';\n const ratio = hasCounter ? value.length / validMaxLength : 0;\n\n return {\n counterAtLimit: hasCounter ? ratio >= 1 : false,\n counterNearLimit: hasCounter ? ratio >= 0.9 && ratio < 1 : false,\n counterText,\n errorText,\n hasCounter,\n hasError,\n hasHelper,\n helperText,\n hidden: !text,\n isError: hasError,\n showHelper: !hasError && hasHelper,\n text,\n };\n });\n};\n\nconst resolveReactiveValue = <T>(value: ReactiveValue<T> | undefined): T | undefined => {\n if (value === undefined) return undefined;\n\n if (isSignal(value)) return (value as ReadonlySignal<T>).value;\n\n if (typeof value === 'function') return (value as () => T)();\n\n return value;\n};\n\nconst optionalStringSource = (value: ReactiveValue<string | undefined> | undefined): (() => string | undefined) => {\n return () => {\n const next = resolveReactiveValue(value);\n\n if (next == null || next === '') return undefined;\n\n return String(next);\n };\n};\n\nconst optionalNumberSource = (value: ReactiveValue<number | undefined> | undefined): (() => number | undefined) => {\n return () => {\n const next = resolveReactiveValue(value);\n\n if (next == null || Number.isNaN(Number(next)) || Number(next) <= 0) return undefined;\n\n return Number(next);\n };\n};\n\nexport const createTextFieldControl = (options: TextFieldOptions): TextFieldHandle => {\n const value = signal('');\n const controlContext = resolveControlContext(options);\n const base = createBaseFieldHandle({\n ...options,\n ...controlContext,\n });\n\n watch(\n options.value,\n (next) => {\n value.value = String(next ?? '');\n },\n { immediate: true },\n );\n\n const field = defineField(\n {\n disabled: base.disabled,\n value,\n },\n {\n onReset: () => {\n value.value = '';\n options.onReset?.();\n },\n },\n );\n\n const assistive = createAssistiveState({\n error: options.error,\n helper: options.helper,\n maxLength: options.maxLength,\n value,\n });\n\n const clear = (event?: Event): void => {\n event?.preventDefault?.();\n\n value.value = '';\n options.onInput?.(event ?? new Event('input'), '');\n options.onChange?.(event ?? new Event('change'), '');\n base.triggerValidation(field, 'change');\n options.elementRef?.value?.focus();\n };\n\n if (options.elementRef) {\n onElement(options.elementRef, (element) => {\n mountTextFieldLifecycle({\n element,\n onBlur: options.onBlur,\n onChange: options.onChange,\n onInput: (event, nextValue) => {\n options.onInputExtra?.(event);\n options.onInput?.(event, nextValue);\n },\n triggerValidation: (on) => base.triggerValidation(field, on),\n });\n });\n }\n\n const attrs = spread({\n '?required': options.required,\n '.disabled': options.disabled,\n '.readOnly': options.readOnly,\n '.type': options.type,\n '.value': value,\n autocomplete: optionalStringSource(options.autocomplete),\n inputmode: optionalStringSource(options.inputmode),\n maxlength: optionalNumberSource(options.maxLength),\n minlength: optionalNumberSource(options.minLength),\n name: optionalStringSource(options.name),\n pattern: optionalStringSource(options.pattern),\n placeholder: optionalStringSource(options.placeholder),\n rows: optionalNumberSource(options.rows),\n });\n\n return {\n assistive,\n attrs,\n ...base,\n clear,\n field,\n triggerValidation: (on: FormControlValidationTrigger) => base.triggerValidation(field, on),\n value,\n };\n};\n\nexport const mountTextFieldLifecycle = (options: TextFieldLifecycleOptions): void => {\n const { element, onBlur, onChange, onInput, triggerValidation } = options;\n\n if (onInput) {\n handle(element, 'input', (event: Event) => {\n onInput(event, element.value);\n });\n }\n\n handle(element, 'change', (event: Event) => {\n onChange?.(event, element.value);\n triggerValidation?.('change');\n });\n\n handle(element, 'blur', (event: Event) => {\n onBlur?.(event as FocusEvent);\n triggerValidation?.('blur');\n });\n};\n\nconst parseChoiceFieldValues = (value: string | undefined): string[] => {\n if (!value) return [];\n\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n};\n\nexport const createChoiceFieldControl = <T>(options: ChoiceFieldOptions<T>): ChoiceFieldHandle<T> => {\n const controlContext = resolveControlContext(options);\n const base = createBaseFieldHandle({\n ...controlContext,\n label: options.label,\n labelPlacement: options.labelPlacement,\n name: options.name,\n prefix: options.prefix,\n });\n const selectedItems = signal<T[]>([]);\n const isMultiple = computed(() => Boolean(options.multiple?.value));\n const selectedValues = computed(() => selectedItems.value.map((item) => options.getValue(item)));\n const formValue = computed(() =>\n isMultiple.value ? selectedValues.value.join(',') : (selectedValues.value[0] ?? ''),\n );\n\n const normalizeSelectedItems = (items: T[]): T[] => {\n const normalized = isMultiple.value ? items : items.slice(0, 1);\n const uniqueItems: T[] = [];\n const seen = new Set<string>();\n\n for (const item of normalized) {\n const value = options.getValue(item);\n\n if (seen.has(value)) continue;\n\n seen.add(value);\n uniqueItems.push(item);\n }\n\n return uniqueItems;\n };\n\n const replaceSelectedItems = (items: T[]): void => {\n selectedItems.value = normalizeSelectedItems(items);\n };\n\n const clear = (): void => {\n replaceSelectedItems([]);\n };\n\n const removeValue = (value: string): void => {\n selectedItems.value = selectedItems.value.filter((item) => options.getValue(item) !== value);\n };\n\n const selectItem = (item: T): void => {\n if (isMultiple.value) {\n const value = options.getValue(item);\n\n if (selectedItems.value.some((current) => options.getValue(current) === value)) return;\n\n replaceSelectedItems([...selectedItems.value, item]);\n\n return;\n }\n\n replaceSelectedItems([item]);\n };\n\n const toggleItem = (item: T): void => {\n if (isMultiple.value) {\n const value = options.getValue(item);\n\n if (selectedItems.value.some((current) => options.getValue(current) === value)) {\n removeValue(value);\n\n return;\n }\n\n replaceSelectedItems([...selectedItems.value, item]);\n\n return;\n }\n\n replaceSelectedItems([item]);\n };\n\n const syncControlledValue = (nextValue: unknown): void => {\n const values = parseChoiceFieldValues(typeof nextValue === 'string' ? nextValue : String(nextValue ?? ''));\n\n replaceSelectedItems(values.map((value) => options.mapControlledValue(value)));\n };\n\n const field = defineField(\n {\n disabled: base.disabled,\n value: formValue,\n },\n {\n onReset: () => {\n clear();\n options.onReset?.();\n },\n },\n );\n\n const assistive = createAssistiveState({\n error: options.error,\n helper: options.helper,\n });\n\n watch(\n options.value,\n (next) => {\n syncControlledValue(next);\n },\n { immediate: true },\n );\n\n if (options.multiple) {\n watch(options.multiple, () => syncControlledValue(options.value.value));\n }\n\n return {\n ...base,\n assistive,\n clear,\n field,\n formValue,\n isMultiple,\n isSelected: (value: string) => selectedItems.value.some((item) => options.getValue(item) === value),\n removeValue,\n replaceSelectedItems,\n selectedItems,\n selectedValues,\n selectItem,\n toggleItem,\n triggerValidation: (on: FormControlValidationTrigger) => base.triggerValidation(field, on),\n };\n};\n\nexport const createCheckableStateControl = (options: CheckableStateOptions): CheckableStateHandle => {\n const value = signal('');\n const base = createBaseFieldHandle(options);\n const checked = signal(Boolean(options.checked.value));\n const indeterminate = signal(Boolean(options.indeterminate?.value));\n const assistive = createAssistiveState({ error: options.error, helper: options.helper });\n\n watch(\n options.checked,\n (next) => {\n checked.value = Boolean(next);\n },\n { immediate: true },\n );\n\n if (options.indeterminate) {\n watch(\n options.indeterminate,\n (next) => {\n indeterminate.value = Boolean(next);\n },\n { immediate: true },\n );\n }\n\n const field = defineField(\n {\n disabled: base.disabled,\n toFormValue: (next: string | null) => next,\n value: computed(() => (checked.value ? (options.value.value ?? '') : null)),\n },\n {\n onReset: () => {\n checked.value = Boolean(options.checked.value);\n indeterminate.value = Boolean(options.indeterminate?.value);\n options.onReset?.();\n },\n },\n );\n\n watch(\n options.value,\n (next) => {\n value.value = String(next ?? '');\n },\n { immediate: true },\n );\n\n const createPayload = (event: Event): CheckableChangePayload => ({\n checked: checked.value,\n fieldValue: options.value.value ?? '',\n originalEvent: event,\n });\n\n const toggle = (event: Event): void => {\n if (base.disabled.value) return;\n\n if (options.group) {\n indeterminate.value = false;\n options.group.toggle(options.value.value ?? '', event);\n options.onToggle?.(createPayload(event));\n\n return;\n }\n\n if (options.clearIndeterminateFirst && indeterminate.value) {\n indeterminate.value = false;\n } else {\n checked.value = !checked.value;\n indeterminate.value = false;\n }\n\n options.onToggle?.(createPayload(event));\n };\n\n return {\n ...base,\n assistive,\n checked,\n field,\n indeterminate,\n toggle,\n triggerValidation: (on: FormControlValidationTrigger) => base.triggerValidation(field, on),\n value,\n };\n};\n"],"mappings":"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"}
|