@vielzeug/ore 1.0.5 → 1.2.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 +36 -3
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +1 -1
- package/dist/_dev.js.map +1 -1
- package/dist/aria.cjs +1 -1
- package/dist/aria.cjs.map +1 -1
- package/dist/aria.d.ts +16 -8
- package/dist/aria.d.ts.map +1 -1
- package/dist/aria.js +1 -1
- package/dist/aria.js.map +1 -1
- package/dist/base-element.cjs +1 -1
- package/dist/base-element.cjs.map +1 -1
- package/dist/base-element.d.ts +36 -1
- package/dist/base-element.d.ts.map +1 -1
- package/dist/base-element.js +1 -1
- package/dist/base-element.js.map +1 -1
- package/dist/component-types.d.ts +13 -76
- package/dist/component-types.d.ts.map +1 -1
- package/dist/context.cjs +1 -1
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.ts +11 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -1
- package/dist/context.js.map +1 -1
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.ts +13 -12
- package/dist/define.d.ts.map +1 -1
- package/dist/define.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 +6 -0
- 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/raw.cjs +1 -1
- package/dist/directives/raw.cjs.map +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/when.cjs +1 -1
- package/dist/directives/when.cjs.map +1 -1
- 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/errors.cjs +2 -2
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +23 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/forms/context.cjs +2 -0
- package/dist/forms/context.cjs.map +1 -0
- package/dist/{form-context.d.ts → forms/context.d.ts} +5 -5
- package/dist/forms/context.d.ts.map +1 -0
- package/dist/forms/context.js +2 -0
- package/dist/forms/context.js.map +1 -0
- package/dist/forms/field.cjs +2 -0
- package/dist/forms/field.cjs.map +1 -0
- package/dist/{form-field.d.ts → forms/field.d.ts} +19 -2
- package/dist/forms/field.d.ts.map +1 -0
- package/dist/forms/field.js +2 -0
- package/dist/forms/field.js.map +1 -0
- package/dist/forms/index.d.ts +11 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms.cjs +1 -0
- package/dist/forms.js +1 -0
- package/dist/host-bind.cjs +1 -1
- package/dist/host-bind.cjs.map +1 -1
- package/dist/host-bind.d.ts +8 -2
- package/dist/host-bind.d.ts.map +1 -1
- package/dist/host-bind.js +1 -1
- package/dist/host-bind.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/ore.cjs +2 -2
- package/dist/ore.cjs.map +1 -1
- package/dist/ore.iife.js +2 -2
- package/dist/ore.iife.js.map +1 -1
- package/dist/ore.js +2 -2
- package/dist/ore.js.map +1 -1
- package/dist/props.cjs +1 -1
- package/dist/props.cjs.map +1 -1
- package/dist/props.d.ts.map +1 -1
- package/dist/props.js +1 -1
- package/dist/props.js.map +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.ts +32 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/slots.cjs +1 -1
- package/dist/slots.cjs.map +1 -1
- package/dist/slots.d.ts +12 -1
- package/dist/slots.d.ts.map +1 -1
- package/dist/slots.js +1 -1
- package/dist/slots.js.map +1 -1
- package/dist/template/bindings.cjs +1 -1
- package/dist/template/bindings.cjs.map +1 -1
- package/dist/template/bindings.d.ts.map +1 -1
- package/dist/template/bindings.js +1 -1
- package/dist/template/bindings.js.map +1 -1
- package/dist/template/compiler.cjs +1 -1
- package/dist/template/compiler.cjs.map +1 -1
- package/dist/template/compiler.d.ts +11 -1
- package/dist/template/compiler.d.ts.map +1 -1
- package/dist/template/compiler.js +1 -1
- package/dist/template/compiler.js.map +1 -1
- package/dist/template/instantiator.cjs +1 -1
- package/dist/template/instantiator.cjs.map +1 -1
- package/dist/template/instantiator.d.ts +0 -5
- package/dist/template/instantiator.d.ts.map +1 -1
- package/dist/template/instantiator.js +1 -1
- package/dist/template/instantiator.js.map +1 -1
- package/dist/testing/dom.cjs +2 -0
- package/dist/testing/dom.cjs.map +1 -0
- package/dist/testing/dom.d.ts +22 -0
- package/dist/testing/dom.d.ts.map +1 -0
- package/dist/testing/dom.js +2 -0
- package/dist/testing/dom.js.map +1 -0
- package/dist/testing/form-internals-polyfill.cjs +2 -0
- package/dist/testing/form-internals-polyfill.cjs.map +1 -0
- package/dist/testing/form-internals-polyfill.d.ts +17 -0
- package/dist/testing/form-internals-polyfill.d.ts.map +1 -0
- package/dist/testing/form-internals-polyfill.js +2 -0
- package/dist/testing/form-internals-polyfill.js.map +1 -0
- package/dist/testing/mount.cjs.map +1 -1
- package/dist/testing/mount.d.ts +4 -4
- package/dist/testing/mount.d.ts.map +1 -1
- package/dist/testing/mount.js.map +1 -1
- package/dist/testing/render-hook.cjs +1 -1
- package/dist/testing/render-hook.cjs.map +1 -1
- package/dist/testing/render-hook.d.ts +6 -6
- package/dist/testing/render-hook.d.ts.map +1 -1
- package/dist/testing/render-hook.js +1 -1
- package/dist/testing/render-hook.js.map +1 -1
- package/dist/testing/testing.cjs +1 -1
- package/dist/testing/testing.cjs.map +1 -1
- package/dist/testing/testing.d.ts +7 -1
- package/dist/testing/testing.d.ts.map +1 -1
- package/dist/testing/testing.js +1 -1
- package/dist/testing/testing.js.map +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.js +1 -1
- package/dist/utils/emit.cjs +1 -1
- package/dist/utils/emit.cjs.map +1 -1
- package/dist/utils/emit.d.ts +28 -5
- package/dist/utils/emit.d.ts.map +1 -1
- package/dist/utils/emit.js +1 -1
- package/dist/utils/emit.js.map +1 -1
- package/package.json +12 -5
- package/dist/context-bag.cjs +0 -2
- package/dist/context-bag.cjs.map +0 -1
- package/dist/context-bag.d.ts +0 -12
- package/dist/context-bag.d.ts.map +0 -1
- package/dist/context-bag.js +0 -2
- package/dist/context-bag.js.map +0 -1
- package/dist/form-context.cjs +0 -2
- package/dist/form-context.cjs.map +0 -1
- package/dist/form-context.d.ts.map +0 -1
- package/dist/form-context.js +0 -2
- package/dist/form-context.js.map +0 -1
- package/dist/form-field.cjs +0 -2
- package/dist/form-field.cjs.map +0 -1
- package/dist/form-field.d.ts.map +0 -1
- package/dist/form-field.js +0 -2
- package/dist/form-field.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vielzeug/ore",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Custom element authoring primitives — reactive templates, signals, slots, and automatic lifecycle management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -28,6 +28,12 @@
|
|
|
28
28
|
"import": "./dist/directives.js",
|
|
29
29
|
"require": "./dist/directives.cjs"
|
|
30
30
|
},
|
|
31
|
+
"./forms": {
|
|
32
|
+
"source": "./src/forms/index.ts",
|
|
33
|
+
"types": "./dist/forms/index.d.ts",
|
|
34
|
+
"import": "./dist/forms.js",
|
|
35
|
+
"require": "./dist/forms.cjs"
|
|
36
|
+
},
|
|
31
37
|
"./observers": {
|
|
32
38
|
"source": "./src/observers/index.ts",
|
|
33
39
|
"types": "./dist/observers/index.d.ts",
|
|
@@ -44,8 +50,8 @@
|
|
|
44
50
|
"scripts": {
|
|
45
51
|
"build": "vite build && pnpm run build:bundle && pnpm run build:types",
|
|
46
52
|
"build:types": "tsc -p tsconfig.declarations.json",
|
|
47
|
-
"fix": "eslint --fix src",
|
|
48
|
-
"lint": "eslint src",
|
|
53
|
+
"fix": "eslint --fix src vitest.setup.ts",
|
|
54
|
+
"lint": "eslint src vitest.setup.ts",
|
|
49
55
|
"prepublishOnly": "pnpm run build",
|
|
50
56
|
"preview": "vite preview",
|
|
51
57
|
"test": "vitest",
|
|
@@ -63,9 +69,10 @@
|
|
|
63
69
|
},
|
|
64
70
|
"devDependencies": {
|
|
65
71
|
"@types/node": "^26.1.0",
|
|
72
|
+
"axe-core": "^4.12.1",
|
|
66
73
|
"jsdom": "^29.1.1",
|
|
67
|
-
"typescript": "
|
|
74
|
+
"typescript": "^6.0.3",
|
|
68
75
|
"vite": "^8.1.3",
|
|
69
|
-
"vitest": "^4.1.
|
|
76
|
+
"vitest": "^4.1.10"
|
|
70
77
|
}
|
|
71
78
|
}
|
package/dist/context-bag.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("./runtime.cjs"),t=require("./aria.cjs"),n=require("./context.cjs"),r=require("./host-bind.cjs"),i=require("./slots.cjs"),a=require("./utils/emit.cjs");var o=o=>{let s=i.createSlots(o),c=r.createBind(o);return{aria:t.createAriaFn(),bind:c,el:o,emit:a.createEmitFn(o),inject:n.inject,onCleanup:e.onCleanup,onElement:e.onElement,onEvent:e.onEvent,onMounted:e.onMounted,provide:(e,t)=>n.provideOnElement(o,e,t),slots:s,watch:e.effect}};exports.createContextBag=o;
|
|
2
|
-
//# sourceMappingURL=context-bag.cjs.map
|
package/dist/context-bag.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-bag.cjs","names":[],"sources":["../src/context-bag.ts"],"sourcesContent":["/**\n * Factory for the SetupContextBag — shared between BaseElement and renderHook.\n * Keeps the real component lifecycle and the test harness in sync automatically.\n */\n\nimport type { SetupContextBag } from './component-types';\nimport type { InjectionKey } from './context';\n\nimport { createAriaFn } from './aria';\nimport { inject, provideOnElement } from './context';\nimport { createBind } from './host-bind';\nimport { effect, onCleanup, onElement, onEvent, onMounted, type OnMountedCallback } from './runtime';\nimport { type ComponentSlots, createSlots } from './slots';\nimport { createEmitFn } from './utils/emit';\n\nexport type ContextBagInit = {\n el: HTMLElement;\n mountCallbacks: OnMountedCallback[];\n};\n\nexport const createContextBag = (el: HTMLElement): SetupContextBag<Record<string, never>, string> => {\n const slots = createSlots(el) as ComponentSlots<string>;\n\n const bind = createBind(el);\n\n return {\n aria: createAriaFn(),\n bind,\n el,\n emit: createEmitFn(el),\n inject,\n onCleanup,\n onElement,\n onEvent,\n onMounted,\n provide: <T>(key: InjectionKey<T>, value: T) => provideOnElement(el, key, value),\n slots,\n watch: effect,\n };\n};\n"],"mappings":"wKAoBA,IAAa,EAAoB,GAAoE,CACnG,IAAM,EAAQ,EAAA,YAAY,CAAE,EAEtB,EAAO,EAAA,WAAW,CAAE,EAE1B,MAAO,CACL,KAAM,EAAA,aAAa,EACnB,OACA,KACA,KAAM,EAAA,aAAa,CAAE,EACrB,OAAA,EAAA,OACA,UAAA,EAAA,UACA,UAAA,EAAA,UACA,QAAA,EAAA,QACA,UAAA,EAAA,UACA,SAAa,EAAsB,IAAa,EAAA,iBAAiB,EAAI,EAAK,CAAK,EAC/E,QACA,MAAO,EAAA,MACT,CACF"}
|
package/dist/context-bag.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Factory for the SetupContextBag — shared between BaseElement and renderHook.
|
|
3
|
-
* Keeps the real component lifecycle and the test harness in sync automatically.
|
|
4
|
-
*/
|
|
5
|
-
import type { SetupContextBag } from './component-types';
|
|
6
|
-
import { type OnMountedCallback } from './runtime';
|
|
7
|
-
export type ContextBagInit = {
|
|
8
|
-
el: HTMLElement;
|
|
9
|
-
mountCallbacks: OnMountedCallback[];
|
|
10
|
-
};
|
|
11
|
-
export declare const createContextBag: (el: HTMLElement) => SetupContextBag<Record<string, never>, string>;
|
|
12
|
-
//# sourceMappingURL=context-bag.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-bag.d.ts","sourceRoot":"","sources":["../src/context-bag.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMzD,OAAO,EAAoD,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAIrG,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,WAAW,CAAC;IAChB,cAAc,EAAE,iBAAiB,EAAE,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,IAAI,WAAW,KAAG,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAmB/F,CAAC"}
|
package/dist/context-bag.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{effect as e,onCleanup as t,onElement as n,onEvent as r,onMounted as i}from"./runtime.js";import{createAriaFn as a}from"./aria.js";import{inject as o,provideOnElement as s}from"./context.js";import{createBind as c}from"./host-bind.js";import{createSlots as l}from"./slots.js";import{createEmitFn as u}from"./utils/emit.js";var d=d=>{let f=l(d),p=c(d);return{aria:a(),bind:p,el:d,emit:u(d),inject:o,onCleanup:t,onElement:n,onEvent:r,onMounted:i,provide:(e,t)=>s(d,e,t),slots:f,watch:e}};export{d as createContextBag};
|
|
2
|
-
//# sourceMappingURL=context-bag.js.map
|
package/dist/context-bag.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-bag.js","names":[],"sources":["../src/context-bag.ts"],"sourcesContent":["/**\n * Factory for the SetupContextBag — shared between BaseElement and renderHook.\n * Keeps the real component lifecycle and the test harness in sync automatically.\n */\n\nimport type { SetupContextBag } from './component-types';\nimport type { InjectionKey } from './context';\n\nimport { createAriaFn } from './aria';\nimport { inject, provideOnElement } from './context';\nimport { createBind } from './host-bind';\nimport { effect, onCleanup, onElement, onEvent, onMounted, type OnMountedCallback } from './runtime';\nimport { type ComponentSlots, createSlots } from './slots';\nimport { createEmitFn } from './utils/emit';\n\nexport type ContextBagInit = {\n el: HTMLElement;\n mountCallbacks: OnMountedCallback[];\n};\n\nexport const createContextBag = (el: HTMLElement): SetupContextBag<Record<string, never>, string> => {\n const slots = createSlots(el) as ComponentSlots<string>;\n\n const bind = createBind(el);\n\n return {\n aria: createAriaFn(),\n bind,\n el,\n emit: createEmitFn(el),\n inject,\n onCleanup,\n onElement,\n onEvent,\n onMounted,\n provide: <T>(key: InjectionKey<T>, value: T) => provideOnElement(el, key, value),\n slots,\n watch: effect,\n };\n};\n"],"mappings":"yUAoBA,IAAa,EAAoB,GAAoE,CACnG,IAAM,EAAQ,EAAY,CAAE,EAEtB,EAAO,EAAW,CAAE,EAE1B,MAAO,CACL,KAAM,EAAa,EACnB,OACA,KACA,KAAM,EAAa,CAAE,EACrB,SACA,YACA,YACA,UACA,YACA,SAAa,EAAsB,IAAa,EAAiB,EAAI,EAAK,CAAK,EAC/E,QACA,MAAO,CACT,CACF"}
|
package/dist/form-context.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("./context.cjs");let t=require("@vielzeug/ripple");var n=e.createContext(`ore:form-context`);function r(e={}){let n=(0,t.signal)([]),r=(0,t.signal)(!1),i=(0,t.signal)(!1),a=(0,t.signal)(null);return{clearStatus:()=>{i.value=!1,a.value=null,e.onReset?.()},dirty:i,error:a,markDirty:()=>{i.value=!0},registerField:e=>(n.value=[...n.value,e],()=>{n.value=n.value.filter(t=>t!==e)}),submit:async t=>{if(t?.preventDefault(),!r.value){r.value=!0,a.value=null;try{await e.onSubmit?.(t),i.value=!1}catch(e){a.value=e}finally{r.value=!1}}},submitting:r,valid:(0,t.computed)(()=>n.value.every(e=>e.value))}}exports.FORM_CONTEXT_KEY=n,exports.createFormContext=r;
|
|
2
|
-
//# sourceMappingURL=form-context.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-context.cjs","names":[],"sources":["../src/form-context.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { createContext } from './context';\n\n/**\n * Context shape injected by child field components.\n * Contains only what a field needs — not submit/error/status APIs.\n */\nexport type FormFieldContext = {\n /** Whether any field has been touched (interacted with). Set via markDirty(). */\n readonly dirty: Readable<boolean>;\n markDirty(): void;\n /**\n * Register a field's validity signal with the form context.\n * Returns a cleanup function.\n */\n registerField(validity: Readable<boolean>): () => void;\n};\n\n/**\n * Full form controller returned by `createFormContext`.\n * Extends `FormFieldContext` with submission and status APIs.\n */\nexport type FormController = FormFieldContext & {\n /**\n * Clear `dirty` and `error` status signals and invoke `onReset` if provided.\n * Note: this does not reset individual field values — pass an `onReset` callback\n * to handle value restoration.\n */\n clearStatus(): void;\n /** The last submit error, or null if the last submit succeeded. */\n readonly error: Readable<unknown>;\n /** Submit the form programmatically. */\n submit(e?: Event): Promise<void>;\n /** Whether the form is currently submitting. */\n readonly submitting: Readable<boolean>;\n /** Whether all fields in the form are valid. */\n readonly valid: Readable<boolean>;\n};\n\nexport const FORM_CONTEXT_KEY = createContext<FormFieldContext>('ore:form-context');\n\n/**\n * Create a `FormController` for coordinating form state across child field components.\n * Call `ctx.provide(FORM_CONTEXT_KEY, form)` to make it available to descendants.\n *\n * @example\n * ```ts\n * define('my-form', {\n * setup(_props, ctx) {\n * const form = createFormContext({ onSubmit: async (e) => { ... } });\n * ctx.provide(FORM_CONTEXT_KEY, form);\n * return html`<form @submit=${form.submit}><slot></slot></form>`;\n * }\n * });\n * ```\n */\nexport function createFormContext(\n options: {\n onReset?: () => void;\n onSubmit?: (e?: Event) => void | Promise<void>;\n } = {},\n): FormController {\n const fieldValiditySignals = signal<Array<Readable<boolean>>>([]);\n const submitting = signal(false);\n const dirty = signal(false);\n const error = signal<unknown>(null);\n\n // Note: [].every() is vacuously true, so valid is true when no fields are registered.\n // This is intentional — a form with no fields is considered valid (nothing to invalidate it).\n const valid = computed(() => fieldValiditySignals.value.every((s) => s.value));\n\n const submit = async (e?: Event): Promise<void> => {\n e?.preventDefault();\n\n if (submitting.value) return;\n\n submitting.value = true;\n error.value = null;\n\n try {\n await options.onSubmit?.(e);\n dirty.value = false;\n } catch (err) {\n error.value = err;\n } finally {\n submitting.value = false;\n }\n };\n\n const clearStatus = (): void => {\n dirty.value = false;\n error.value = null;\n options.onReset?.();\n };\n\n const markDirty = (): void => {\n dirty.value = true;\n };\n\n const registerField = (validity: Readable<boolean>): (() => void) => {\n fieldValiditySignals.value = [...fieldValiditySignals.value, validity];\n\n return () => {\n fieldValiditySignals.value = fieldValiditySignals.value.filter((s) => s !== validity);\n };\n };\n\n return { clearStatus, dirty, error, markDirty, registerField, submit, submitting, valid };\n}\n"],"mappings":"mEAwCA,IAAa,EAAmB,EAAA,cAAgC,kBAAkB,EAiBlF,SAAgB,EACd,EAGI,CAAC,EACW,CAChB,IAAM,GAAA,EAAA,EAAA,OAAA,CAAwD,CAAC,CAAC,EAC1D,GAAA,EAAA,EAAA,OAAA,CAAoB,EAAK,EACzB,GAAA,EAAA,EAAA,OAAA,CAAe,EAAK,EACpB,GAAA,EAAA,EAAA,OAAA,CAAwB,IAAI,EA0ClC,MAAO,CAAE,gBAlBuB,CAC9B,EAAM,MAAQ,GACd,EAAM,MAAQ,KACd,EAAQ,UAAU,CACpB,EAcsB,QAAO,QAAO,cAZN,CAC5B,EAAM,MAAQ,EAChB,EAU+C,cARxB,IACrB,EAAqB,MAAQ,CAAC,GAAG,EAAqB,MAAO,CAAQ,MAExD,CACX,EAAqB,MAAQ,EAAqB,MAAM,OAAQ,GAAM,IAAM,CAAQ,CACtF,GAG4D,YApCxC,IAA6B,CACjD,MAAG,eAAe,EAEd,GAAW,MAGf,CADA,EAAW,MAAQ,GACnB,EAAM,MAAQ,KAEd,GAAI,CACF,MAAM,EAAQ,WAAW,CAAC,EAC1B,EAAM,MAAQ,EAChB,OAAS,EAAK,CACZ,EAAM,MAAQ,CAChB,QAAU,CACR,EAAW,MAAQ,EACrB,CATc,CAUhB,EAoBsE,aAAY,OAtC5E,EAAA,EAAA,SAAA,KAAuB,EAAqB,MAAM,MAAO,GAAM,EAAE,KAAK,CAsCM,CAAM,CAC1F"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-context.d.ts","sourceRoot":"","sources":["../src/form-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAInE;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClC,SAAS,IAAI,IAAI,CAAC;IAClB;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC;CACxD,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG;IAC9C;;;;OAIG;IACH,WAAW,IAAI,IAAI,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClC,wCAAwC;IACxC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvC,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,oDAAsD,CAAC;AAEpF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C,GACL,cAAc,CA+ChB"}
|
package/dist/form-context.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{createContext as e}from"./context.js";import{computed as t,signal as n}from"@vielzeug/ripple";var r=e(`ore:form-context`);function i(e={}){let r=n([]),i=n(!1),a=n(!1),o=n(null);return{clearStatus:()=>{a.value=!1,o.value=null,e.onReset?.()},dirty:a,error:o,markDirty:()=>{a.value=!0},registerField:e=>(r.value=[...r.value,e],()=>{r.value=r.value.filter(t=>t!==e)}),submit:async t=>{if(t?.preventDefault(),!i.value){i.value=!0,o.value=null;try{await e.onSubmit?.(t),a.value=!1}catch(e){o.value=e}finally{i.value=!1}}},submitting:i,valid:t(()=>r.value.every(e=>e.value))}}export{r as FORM_CONTEXT_KEY,i as createFormContext};
|
|
2
|
-
//# sourceMappingURL=form-context.js.map
|
package/dist/form-context.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-context.js","names":[],"sources":["../src/form-context.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { createContext } from './context';\n\n/**\n * Context shape injected by child field components.\n * Contains only what a field needs — not submit/error/status APIs.\n */\nexport type FormFieldContext = {\n /** Whether any field has been touched (interacted with). Set via markDirty(). */\n readonly dirty: Readable<boolean>;\n markDirty(): void;\n /**\n * Register a field's validity signal with the form context.\n * Returns a cleanup function.\n */\n registerField(validity: Readable<boolean>): () => void;\n};\n\n/**\n * Full form controller returned by `createFormContext`.\n * Extends `FormFieldContext` with submission and status APIs.\n */\nexport type FormController = FormFieldContext & {\n /**\n * Clear `dirty` and `error` status signals and invoke `onReset` if provided.\n * Note: this does not reset individual field values — pass an `onReset` callback\n * to handle value restoration.\n */\n clearStatus(): void;\n /** The last submit error, or null if the last submit succeeded. */\n readonly error: Readable<unknown>;\n /** Submit the form programmatically. */\n submit(e?: Event): Promise<void>;\n /** Whether the form is currently submitting. */\n readonly submitting: Readable<boolean>;\n /** Whether all fields in the form are valid. */\n readonly valid: Readable<boolean>;\n};\n\nexport const FORM_CONTEXT_KEY = createContext<FormFieldContext>('ore:form-context');\n\n/**\n * Create a `FormController` for coordinating form state across child field components.\n * Call `ctx.provide(FORM_CONTEXT_KEY, form)` to make it available to descendants.\n *\n * @example\n * ```ts\n * define('my-form', {\n * setup(_props, ctx) {\n * const form = createFormContext({ onSubmit: async (e) => { ... } });\n * ctx.provide(FORM_CONTEXT_KEY, form);\n * return html`<form @submit=${form.submit}><slot></slot></form>`;\n * }\n * });\n * ```\n */\nexport function createFormContext(\n options: {\n onReset?: () => void;\n onSubmit?: (e?: Event) => void | Promise<void>;\n } = {},\n): FormController {\n const fieldValiditySignals = signal<Array<Readable<boolean>>>([]);\n const submitting = signal(false);\n const dirty = signal(false);\n const error = signal<unknown>(null);\n\n // Note: [].every() is vacuously true, so valid is true when no fields are registered.\n // This is intentional — a form with no fields is considered valid (nothing to invalidate it).\n const valid = computed(() => fieldValiditySignals.value.every((s) => s.value));\n\n const submit = async (e?: Event): Promise<void> => {\n e?.preventDefault();\n\n if (submitting.value) return;\n\n submitting.value = true;\n error.value = null;\n\n try {\n await options.onSubmit?.(e);\n dirty.value = false;\n } catch (err) {\n error.value = err;\n } finally {\n submitting.value = false;\n }\n };\n\n const clearStatus = (): void => {\n dirty.value = false;\n error.value = null;\n options.onReset?.();\n };\n\n const markDirty = (): void => {\n dirty.value = true;\n };\n\n const registerField = (validity: Readable<boolean>): (() => void) => {\n fieldValiditySignals.value = [...fieldValiditySignals.value, validity];\n\n return () => {\n fieldValiditySignals.value = fieldValiditySignals.value.filter((s) => s !== validity);\n };\n };\n\n return { clearStatus, dirty, error, markDirty, registerField, submit, submitting, valid };\n}\n"],"mappings":"qGAwCA,IAAa,EAAmB,EAAgC,kBAAkB,EAiBlF,SAAgB,EACd,EAGI,CAAC,EACW,CAChB,IAAM,EAAuB,EAAiC,CAAC,CAAC,EAC1D,EAAa,EAAO,EAAK,EACzB,EAAQ,EAAO,EAAK,EACpB,EAAQ,EAAgB,IAAI,EA0ClC,MAAO,CAAE,gBAlBuB,CAC9B,EAAM,MAAQ,GACd,EAAM,MAAQ,KACd,EAAQ,UAAU,CACpB,EAcsB,QAAO,QAAO,cAZN,CAC5B,EAAM,MAAQ,EAChB,EAU+C,cARxB,IACrB,EAAqB,MAAQ,CAAC,GAAG,EAAqB,MAAO,CAAQ,MAExD,CACX,EAAqB,MAAQ,EAAqB,MAAM,OAAQ,GAAM,IAAM,CAAQ,CACtF,GAG4D,YApCxC,IAA6B,CACjD,MAAG,eAAe,EAEd,GAAW,MAGf,CADA,EAAW,MAAQ,GACnB,EAAM,MAAQ,KAEd,GAAI,CACF,MAAM,EAAQ,WAAW,CAAC,EAC1B,EAAM,MAAQ,EAChB,OAAS,EAAK,CACZ,EAAM,MAAQ,CAChB,QAAU,CACR,EAAW,MAAQ,EACrB,CATc,CAUhB,EAoBsE,aAAY,MAtCpE,MAAe,EAAqB,MAAM,MAAO,GAAM,EAAE,KAAK,CAsCM,CAAM,CAC1F"}
|
package/dist/form-field.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("./_dev.cjs"),t=require("./errors.cjs"),n=require("./runtime.cjs");require("@vielzeug/ripple");var r=new WeakMap,i=i=>{let a=i.el??n.getCurrentElement();if(!a.constructor.formAssociated)throw new t.OreApiError(t.ORE_ERRORS.defineFieldRequiresFormAssociated(a.localName));if(r.has(a))throw new t.OreApiError(`useField() was already called on <${a.localName}>. Call it only once per component.`);let o=a.attachInternals();r.set(a,o),n.onCleanup(()=>r.delete(a));let s=i.toFormValue??(e=>e==null?i.emptyStringForNull?``:null:e instanceof File||e instanceof FormData?e:String(e));n.effect(()=>{o.setFormValue(s(i.value.value))});let c=i.disabled;if(c)if(!(`states`in o))e.warn(`useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.`);else{let e=o.states;n.effect(()=>{c.value?e.add(`disabled`):e.delete(`disabled`)})}return{checkValidity:()=>o.checkValidity(),internals:o,reportValidity:()=>o.reportValidity(),setCustomValidity:e=>e?o.setValidity({customError:!0},e):o.setValidity({}),setValidity:o.setValidity.bind(o)}};exports.useField=i;
|
|
2
|
-
//# sourceMappingURL=form-field.cjs.map
|
package/dist/form-field.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-field.cjs","names":[],"sources":["../src/form-field.ts"],"sourcesContent":["import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from './_dev';\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport { effect, getCurrentElement, onCleanup } from './runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getCurrentElement()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n toFormValue?: (value: T) => File | FormData | string | null;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n setCustomValidity: (message: string) => void;\n setValidity: ElementInternals['setValidity'];\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getCurrentElement();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(`useField() was already called on <${host.localName}>. Call it only once per component.`);\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n effect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n effect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n setValidity: internals.setValidity.bind(internals),\n };\n};\n"],"mappings":"+GAOA,IAAM,EAAoB,IAAI,QAgCjB,EAAyB,GAAkD,CACtF,IAAM,EAAO,EAAQ,IAAM,EAAA,kBAAkB,EAG7C,GAAI,CAFS,EAAK,YAER,eACR,MAAM,IAAI,EAAA,YAAY,EAAA,WAAW,kCAAkC,EAAK,SAAS,CAAC,EAGpF,GAAI,EAAkB,IAAI,CAAI,EAC5B,MAAM,IAAI,EAAA,YAAY,qCAAqC,EAAK,UAAU,oCAAoC,EAGhH,IAAM,EAAY,EAAK,gBAAgB,EAEvC,EAAkB,IAAI,EAAM,CAAS,EACrC,EAAA,cAAgB,EAAkB,OAAO,CAAI,CAAC,EAE9C,IAAM,EACJ,EAAQ,cACN,GACI,GAAK,KAAa,EAAQ,mBAAqB,GAAK,KAEpD,aAAa,MAAQ,aAAa,SAAiB,EAEhD,OAAO,CAAC,GAGnB,EAAA,WAAa,CACX,EAAU,aAAa,EAAY,EAAQ,MAAM,KAAK,CAAC,CACzD,CAAC,EAED,IAAM,EAAW,EAAQ,SAEzB,GAAI,EACF,GAAI,EAAE,WAAY,GAChB,EAAA,KACE,8HACF,MACK,CACL,IAAM,EAAS,EAAU,OAEzB,EAAA,WAAa,CACP,EAAS,MAAO,EAAO,IAAI,UAAU,EACpC,EAAO,OAAO,UAAU,CAC/B,CAAC,CACH,CAQF,MAAO,CACL,kBAN0B,EAAU,cAAc,EAOlD,YACA,mBAP2B,EAAU,eAAe,EAQpD,kBAPyB,GACzB,EAAU,EAAU,YAAY,CAAE,YAAa,EAAK,EAAG,CAAO,EAAI,EAAU,YAAY,CAAC,CAAC,EAO1F,YAAa,EAAU,YAAY,KAAK,CAAS,CACnD,CACF"}
|
package/dist/form-field.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-field.d.ts","sourceRoot":"","sources":["../src/form-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAS9D,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI;IAC1C,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5D,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,aAAa,EAAE,MAAM,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC;IAC9B,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,WAAW,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;CAC9C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO,EAAE,SAAS,gBAAgB,CAAC,CAAC,CAAC,KAAG,eA4DpE,CAAC"}
|
package/dist/form-field.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{warn as e}from"./_dev.js";import{ORE_ERRORS as t,OreApiError as n}from"./errors.js";import{effect as r,getCurrentElement as i,onCleanup as a}from"./runtime.js";import"@vielzeug/ripple";var o=new WeakMap,s=s=>{let c=s.el??i();if(!c.constructor.formAssociated)throw new n(t.defineFieldRequiresFormAssociated(c.localName));if(o.has(c))throw new n(`useField() was already called on <${c.localName}>. Call it only once per component.`);let l=c.attachInternals();o.set(c,l),a(()=>o.delete(c));let u=s.toFormValue??(e=>e==null?s.emptyStringForNull?``:null:e instanceof File||e instanceof FormData?e:String(e));r(()=>{l.setFormValue(u(s.value.value))});let d=s.disabled;if(d)if(!(`states`in l))e(`useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.`);else{let e=l.states;r(()=>{d.value?e.add(`disabled`):e.delete(`disabled`)})}return{checkValidity:()=>l.checkValidity(),internals:l,reportValidity:()=>l.reportValidity(),setCustomValidity:e=>e?l.setValidity({customError:!0},e):l.setValidity({}),setValidity:l.setValidity.bind(l)}};export{s as useField};
|
|
2
|
-
//# sourceMappingURL=form-field.js.map
|
package/dist/form-field.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-field.js","names":[],"sources":["../src/form-field.ts"],"sourcesContent":["import { type Readable, type Signal } from '@vielzeug/ripple';\n\nimport { warn } from './_dev';\nimport { OreApiError, ORE_ERRORS } from './errors';\nimport { effect, getCurrentElement, onCleanup } from './runtime';\n\n/** @internal */\nconst internalsRegistry = new WeakMap<HTMLElement, ElementInternals>();\n\nexport type FormFieldOptions<T = unknown> = {\n disabled?: Readable<boolean>;\n /**\n * The host element to attach `ElementInternals` to.\n * Defaults to the element currently being set up via `getCurrentElement()`.\n * Pass this explicitly when calling `useField` from a composable that is\n * not called directly during `setup()` (e.g. a helper factory function).\n */\n el?: HTMLElement;\n /**\n * When `true`, a `null` or `undefined` value is submitted as an empty string\n * (`''`) instead of `null`. This keeps the field's key present in `FormData`\n * even when the value is absent — useful when the server expects the field to\n * always be included.\n *\n * @default false\n */\n emptyStringForNull?: boolean;\n toFormValue?: (value: T) => File | FormData | string | null;\n value: Signal<T> | Readable<T>;\n};\n\nexport type FormFieldHandle = {\n checkValidity: () => boolean;\n readonly internals: ElementInternals;\n reportValidity: () => boolean;\n setCustomValidity: (message: string) => void;\n setValidity: ElementInternals['setValidity'];\n};\n\nexport const useField = <T = unknown>(options: FormFieldOptions<T>): FormFieldHandle => {\n const host = options.el ?? getCurrentElement();\n const ctor = host.constructor as typeof HTMLElement & { formAssociated?: boolean };\n\n if (!ctor.formAssociated) {\n throw new OreApiError(ORE_ERRORS.defineFieldRequiresFormAssociated(host.localName));\n }\n\n if (internalsRegistry.has(host)) {\n throw new OreApiError(`useField() was already called on <${host.localName}>. Call it only once per component.`);\n }\n\n const internals = host.attachInternals();\n\n internalsRegistry.set(host, internals);\n onCleanup(() => internalsRegistry.delete(host));\n\n const toFormValue =\n options.toFormValue ??\n ((v: T): File | FormData | string | null => {\n if (v == null) return options.emptyStringForNull ? '' : null;\n\n if (v instanceof File || v instanceof FormData) return v;\n\n return String(v);\n });\n\n effect(() => {\n internals.setFormValue(toFormValue(options.value.value));\n });\n\n const disabled = options.disabled;\n\n if (disabled) {\n if (!('states' in internals)) {\n warn(\n 'useField(): ElementInternals.states (CustomStateSet) is not available in this environment — disabled state tracking skipped.',\n );\n } else {\n const states = internals.states as CustomStateSet;\n\n effect(() => {\n if (disabled.value) states.add('disabled');\n else states.delete('disabled');\n });\n }\n }\n\n const checkValidity = () => internals.checkValidity();\n const reportValidity = () => internals.reportValidity();\n const setCustomValidity = (message: string) =>\n message ? internals.setValidity({ customError: true }, message) : internals.setValidity({});\n\n return {\n checkValidity,\n internals,\n reportValidity,\n setCustomValidity,\n setValidity: internals.setValidity.bind(internals),\n };\n};\n"],"mappings":"gMAOA,IAAM,EAAoB,IAAI,QAgCjB,EAAyB,GAAkD,CACtF,IAAM,EAAO,EAAQ,IAAM,EAAkB,EAG7C,GAAI,CAFS,EAAK,YAER,eACR,MAAM,IAAI,EAAY,EAAW,kCAAkC,EAAK,SAAS,CAAC,EAGpF,GAAI,EAAkB,IAAI,CAAI,EAC5B,MAAM,IAAI,EAAY,qCAAqC,EAAK,UAAU,oCAAoC,EAGhH,IAAM,EAAY,EAAK,gBAAgB,EAEvC,EAAkB,IAAI,EAAM,CAAS,EACrC,MAAgB,EAAkB,OAAO,CAAI,CAAC,EAE9C,IAAM,EACJ,EAAQ,cACN,GACI,GAAK,KAAa,EAAQ,mBAAqB,GAAK,KAEpD,aAAa,MAAQ,aAAa,SAAiB,EAEhD,OAAO,CAAC,GAGnB,MAAa,CACX,EAAU,aAAa,EAAY,EAAQ,MAAM,KAAK,CAAC,CACzD,CAAC,EAED,IAAM,EAAW,EAAQ,SAEzB,GAAI,EACF,GAAI,EAAE,WAAY,GAChB,EACE,8HACF,MACK,CACL,IAAM,EAAS,EAAU,OAEzB,MAAa,CACP,EAAS,MAAO,EAAO,IAAI,UAAU,EACpC,EAAO,OAAO,UAAU,CAC/B,CAAC,CACH,CAQF,MAAO,CACL,kBAN0B,EAAU,cAAc,EAOlD,YACA,mBAP2B,EAAU,eAAe,EAQpD,kBAPyB,GACzB,EAAU,EAAU,YAAY,CAAE,YAAa,EAAK,EAAG,CAAO,EAAI,EAAU,YAAY,CAAC,CAAC,EAO1F,YAAa,EAAU,YAAY,KAAK,CAAS,CACnD,CACF"}
|