@iris-ui-kit/vue 0.2.21 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs +14 -5
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.js +2 -2
- package/dist/async.cjs +48 -2
- package/dist/async.cjs.map +1 -1
- package/dist/async.d.cts +27 -3
- package/dist/async.d.ts +27 -3
- package/dist/async.js +1 -1
- package/dist/chunk-25NYWSXP.js +20 -0
- package/dist/chunk-25NYWSXP.js.map +1 -0
- package/dist/{chunk-4FLIW67H.js → chunk-IAG64CHL.js} +21 -28
- package/dist/chunk-IAG64CHL.js.map +1 -0
- package/dist/chunk-NNOF7KUH.js +24 -0
- package/dist/chunk-NNOF7KUH.js.map +1 -0
- package/dist/{chunk-4WQOZ2OV.js → chunk-QQ25RKOO.js} +6 -4
- package/dist/chunk-QQ25RKOO.js.map +1 -0
- package/dist/chunk-SJB5DIIY.js +119 -0
- package/dist/chunk-SJB5DIIY.js.map +1 -0
- package/dist/form.cjs +28 -23
- package/dist/form.cjs.map +1 -1
- package/dist/form.d.cts +3 -2
- package/dist/form.d.ts +3 -2
- package/dist/form.js +2 -1
- package/dist/index.cjs +88 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/machine.cjs +11 -4
- package/dist/machine.cjs.map +1 -1
- package/dist/machine.d.cts +12 -3
- package/dist/machine.d.ts +12 -3
- package/dist/machine.js +1 -1
- package/dist/resource.cjs +7 -3
- package/dist/resource.cjs.map +1 -1
- package/dist/resource.d.cts +10 -1
- package/dist/resource.d.ts +10 -1
- package/dist/resource.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4FLIW67H.js.map +0 -1
- package/dist/chunk-4WQOZ2OV.js.map +0 -1
- package/dist/chunk-TQB5LVOH.js +0 -17
- package/dist/chunk-TQB5LVOH.js.map +0 -1
- package/dist/chunk-XSLBANUV.js +0 -16
- package/dist/chunk-XSLBANUV.js.map +0 -1
- package/dist/chunk-ZY4NLITM.js +0 -73
- package/dist/chunk-ZY4NLITM.js.map +0 -1
package/dist/form.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/form/context.ts","../src/form/Form.ts","../src/form/useForm.ts","../src/form/useField.ts","../src/form/useFieldArray.ts"],"names":["inject","defineComponent","provide","ref","h","createFormStore","onBeforeUnmount","computed","formatPath","getByPath"],"mappings":"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","file":"form.cjs","sourcesContent":["import { inject, type InjectionKey } from 'vue'\nimport type { FormStore, FormValues } from '@iris-ui-kit/core'\n\n/**\n * Provides the active form's {@link FormStore} to descendant fields so\n * `useField` can bind without prop drilling. The generic is erased at the\n * injection boundary; `useField<T>` re-applies the value type at the call site.\n */\nexport const FormInjectionKey: InjectionKey<FormStore<FormValues>> = Symbol('IrisForm')\n\nexport function useFormContext(): FormStore<FormValues> {\n const form = inject(FormInjectionKey, null)\n if (!form) {\n throw new Error('useField / useFormContext must be used within an <IrisForm>')\n }\n return form\n}\n","import { defineComponent, h, provide, ref, type PropType } from 'vue'\nimport type { FormStore, FormValues } from '@iris-ui-kit/core'\nimport { FormInjectionKey } from './context'\n\n/** Focus (and best-effort scroll to) the first errored named control in DOM order. */\nfunction focusFirstError(\n formEl: HTMLElement | null,\n errors: Record<string, string | undefined>,\n): void {\n if (!formEl) return\n const keys = Object.keys(errors)\n if (keys.length === 0) return\n const controls = formEl.querySelectorAll<HTMLElement>(\n 'input[name], select[name], textarea[name], [data-iris-field]',\n )\n for (const el of Array.from(controls)) {\n const name = el.getAttribute('name') ?? el.getAttribute('data-iris-field')\n if (name && keys.includes(name)) {\n el.focus()\n try {\n el.scrollIntoView({ block: 'center' })\n } catch {\n /* scrollIntoView is unavailable in jsdom — focus is the contract */\n }\n return\n }\n }\n}\n\n/**\n * Provides the form store to descendant `useField` calls and wires the native\n * `<form>` submit to `handleSubmit` (with `preventDefault`). Composition:\n *\n * ```html\n * <IrisForm :form=\"f.form\">\n * <IrisFormField label=\"Email\"><IrisInput v-bind=\"email.fieldProps.value\" /></IrisFormField>\n * <IrisButton type=\"submit\" :disabled=\"f.isSubmitting.value\">Save</IrisButton>\n * </IrisForm>\n * ```\n */\nexport const IrisForm = defineComponent({\n name: 'IrisForm',\n props: {\n /** The store from `useForm(...).form`. */\n form: {\n type: Object as PropType<FormStore<FormValues>>,\n required: true,\n },\n },\n setup(props, { slots }) {\n provide(FormInjectionKey, props.form)\n const formRef = ref<HTMLElement | null>(null)\n return () =>\n h(\n 'form',\n {\n ref: formRef,\n 'data-iris-form': '',\n onSubmit: (event: Event) => {\n event.preventDefault()\n // On a failed submit, move focus to the first errored field (a11y).\n void props.form\n .handleSubmit()\n .then(() => focusFirstError(formRef.value, props.form.getState().errors))\n },\n },\n slots.default?.(),\n )\n },\n})\n","import { computed, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport {\n createFormStore,\n type FieldErrors,\n type FieldFlags,\n type FormConfig,\n type FormState,\n type FormStore,\n type FormValues,\n} from '@iris-ui-kit/core'\n\nexport interface UseFormReturn<V extends FormValues> {\n /** The form store — pass to `<IrisForm :form=\"...\">`. */\n form: FormStore<V>\n /** The full reactive state snapshot. */\n state: Ref<FormState<V>>\n values: ComputedRef<V>\n errors: ComputedRef<FieldErrors<V>>\n touched: ComputedRef<FieldFlags<V>>\n dirty: ComputedRef<FieldFlags<V>>\n isSubmitting: ComputedRef<boolean>\n isValidating: ComputedRef<boolean>\n submitCount: ComputedRef<number>\n isValid: ComputedRef<boolean>\n setFieldValue: FormStore<V>['setFieldValue']\n setValues: FormStore<V>['setValues']\n setFieldTouched: FormStore<V>['setFieldTouched']\n setFieldError: FormStore<V>['setFieldError']\n setErrors: FormStore<V>['setErrors']\n validateField: FormStore<V>['validateField']\n validateForm: FormStore<V>['validateForm']\n handleSubmit: FormStore<V>['handleSubmit']\n reset: FormStore<V>['reset']\n}\n\n/**\n * Vue binding for the framework-agnostic form engine. Creates the store in\n * `setup()` (runs once) and bridges it into Vue reactivity via a `ref` updated\n * on each store change, cleaned up on unmount. Because `setup` runs once,\n * `onSubmit` / `validate` closures stay live against reactive state — no\n * stale-callback handling is needed (unlike the React adapter).\n */\nexport function useForm<V extends FormValues>(config: FormConfig<V>): UseFormReturn<V> {\n const form = createFormStore(config)\n const state = ref(form.getState()) as Ref<FormState<V>>\n const unsubscribe = form.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n return {\n form,\n state,\n values: computed(() => state.value.values),\n errors: computed(() => state.value.errors),\n touched: computed(() => state.value.touched),\n dirty: computed(() => state.value.dirty),\n isSubmitting: computed(() => state.value.isSubmitting),\n isValidating: computed(() => state.value.isValidating),\n submitCount: computed(() => state.value.submitCount),\n isValid: computed(() => Object.keys(state.value.errors).length === 0),\n setFieldValue: form.setFieldValue,\n setValues: form.setValues,\n setFieldTouched: form.setFieldTouched,\n setFieldError: form.setFieldError,\n setErrors: form.setErrors,\n validateField: form.validateField,\n validateForm: form.validateForm,\n handleSubmit: form.handleSubmit,\n reset: form.reset,\n }\n}\n","import { computed, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport { formatPath, getByPath, type FormState, type FormValues } from '@iris-ui-kit/core'\nimport { useFormContext } from './context'\n\nexport interface FieldBindProps {\n modelValue: unknown\n 'onUpdate:modelValue': (value: unknown) => void\n invalid: boolean\n onBlur: () => void\n}\n\nexport interface UseFieldReturn<T> {\n name: string\n value: ComputedRef<T>\n error: ComputedRef<string | undefined>\n touched: ComputedRef<boolean>\n dirty: ComputedRef<boolean>\n setValue: (value: T) => void\n setTouched: (touched?: boolean) => void\n /**\n * Bundle for `v-bind` onto a v-model'd Iris control (`IrisInput`,\n * `IrisSelect`, …): wires `modelValue` / `update:modelValue` / `invalid` /\n * `blur`. Use `value` + `setValue` directly for bespoke bindings.\n */\n fieldProps: ComputedRef<FieldBindProps>\n}\n\n/**\n * Binds a single field to the surrounding `<IrisForm>`. `T` is the value type\n * at the call site (the injection erases the form's generic).\n *\n * `name` may be a flat top-level key OR a nested PATH (`'address.city'`,\n * `'items[2].sku'`); a flat key is a 1-segment path and stays back-compatible\n * (v3 R19).\n */\nexport function useField<T = unknown>(name: string): UseFieldReturn<T> {\n const form = useFormContext()\n const state = ref(form.getState()) as Ref<FormState<FormValues>>\n const unsubscribe = form.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n // Canonical key for per-field state lookups (a flat key maps to itself).\n const key = formatPath(name)\n const value = computed(() => getByPath(state.value.values, name) as T)\n const error = computed(() => state.value.errors[key])\n\n return {\n name,\n value,\n error,\n touched: computed(() => Boolean(state.value.touched[key])),\n dirty: computed(() => Boolean(state.value.dirty[key])),\n setValue: (next) => form.setFieldValue(name, next as never),\n setTouched: (touched = true) => form.setFieldTouched(name, touched),\n fieldProps: computed(() => ({\n modelValue: value.value,\n 'onUpdate:modelValue': (next: unknown) => form.setFieldValue(name, next as never),\n invalid: Boolean(error.value),\n onBlur: () => form.setFieldTouched(name, true),\n })),\n }\n}\n","import { computed, onBeforeUnmount, ref, type ComputedRef, type Ref } from 'vue'\nimport type { FormState, FormValues } from '@iris-ui-kit/core'\nimport { useFormContext } from './context'\n\nexport interface UseFieldArrayReturn<T> {\n name: string\n /** Current array value (reactive). */\n fields: ComputedRef<T[]>\n /** Append an item. */\n push: (item: T) => void\n /** Remove the item at `index`. */\n remove: (index: number) => void\n /** Insert `item` at `index` (shifting the rest right). */\n insert: (index: number, item: T) => void\n /** Move the item from `from` to `to`. */\n move: (from: number, to: number) => void\n /** Replace the whole array. */\n replace: (items: T[]) => void\n}\n\n/**\n * Manage a dynamic array field (repeatable rows) inside an `<IrisForm>`. Mutators\n * delegate to the core {@link FormStore} array helpers (`arrayPush`/`arrayInsert`/\n * `arrayRemove`/`arrayMove`), which RE-KEY each element's error/touched/dirty/\n * validating state across the mutation — so a row's per-element validation state\n * FOLLOWS the row when rows are removed or reordered (removing `items[0]` shifts\n * `items[2]`'s error down to `items[1]`). `replace` swaps the whole array.\n */\nexport function useFieldArray<T = unknown>(name: string): UseFieldArrayReturn<T> {\n const form = useFormContext()\n const state = ref(form.getState()) as Ref<FormState<FormValues>>\n const unsubscribe = form.subscribe((next) => {\n state.value = next\n })\n onBeforeUnmount(unsubscribe)\n\n return {\n name,\n fields: computed(\n () => (Array.isArray(state.value.values[name]) ? state.value.values[name] : []) as T[],\n ),\n push: (item) => form.arrayPush(name as never, item as never),\n remove: (index) => form.arrayRemove(name as never, index),\n insert: (index, item) => form.arrayInsert(name as never, index, item as never),\n move: (from, to) => form.arrayMove(name as never, from, to),\n replace: (items) => form.setFieldValue(name, items as never),\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/form/context.ts","../src/form/Form.ts","../src/useStore.ts","../src/form/useForm.ts","../src/form/useField.ts","../src/form/useFieldArray.ts"],"names":["inject","defineComponent","provide","ref","h","shallowRef","onScopeDispose","createFormStore","computed","formatPath","parsePath","getByPath","touched"],"mappings":"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","file":"form.cjs","sourcesContent":["import { inject, type InjectionKey } from 'vue'\nimport type { FormStore, FormValues } from '@iris-ui-kit/core'\n\n/**\n * Provides the active form's {@link FormStore} to descendant fields so\n * `useField` can bind without prop drilling. The generic is erased at the\n * injection boundary; `useField<T>` re-applies the value type at the call site.\n */\nexport const FormInjectionKey: InjectionKey<FormStore<FormValues>> = Symbol('IrisForm')\n\nexport function useFormContext(): FormStore<FormValues> {\n const form = inject(FormInjectionKey, null)\n if (!form) {\n throw new Error('useField / useFormContext must be used within an <IrisForm>')\n }\n return form\n}\n","import { defineComponent, h, provide, ref, type PropType } from 'vue'\nimport type { FormStore, FormValues } from '@iris-ui-kit/core'\nimport { FormInjectionKey } from './context'\n\n/** Focus (and best-effort scroll to) the first errored named control in DOM order. */\nfunction focusFirstError(\n formEl: HTMLElement | null,\n errors: Record<string, string | undefined>,\n): void {\n if (!formEl) return\n const keys = Object.keys(errors)\n if (keys.length === 0) return\n const controls = formEl.querySelectorAll<HTMLElement>(\n 'input[name], select[name], textarea[name], [data-iris-field]',\n )\n for (const el of Array.from(controls)) {\n const name = el.getAttribute('name') ?? el.getAttribute('data-iris-field')\n if (name && keys.includes(name)) {\n el.focus()\n try {\n el.scrollIntoView({ block: 'center' })\n } catch {\n /* scrollIntoView is unavailable in jsdom — focus is the contract */\n }\n return\n }\n }\n}\n\n/**\n * Provides the form store to descendant `useField` calls and wires the native\n * `<form>` submit to `handleSubmit` (with `preventDefault`). Composition:\n *\n * ```html\n * <IrisForm :form=\"f.form\">\n * <IrisFormField label=\"Email\"><IrisInput v-bind=\"email.fieldProps.value\" /></IrisFormField>\n * <IrisButton type=\"submit\" :disabled=\"f.isSubmitting.value\">Save</IrisButton>\n * </IrisForm>\n * ```\n */\nexport const IrisForm = defineComponent({\n name: 'IrisForm',\n props: {\n /** The store from `useForm(...).form`. */\n form: {\n type: Object as PropType<FormStore<FormValues>>,\n required: true,\n },\n },\n setup(props, { slots }) {\n provide(FormInjectionKey, props.form)\n const formRef = ref<HTMLElement | null>(null)\n return () =>\n h(\n 'form',\n {\n ref: formRef,\n 'data-iris-form': '',\n onSubmit: (event: Event) => {\n event.preventDefault()\n // On a failed submit, move focus to the first errored field (a11y).\n void props.form\n .handleSubmit()\n .then(() => focusFirstError(formRef.value, props.form.getState().errors))\n },\n },\n slots.default?.(),\n )\n },\n})\n","import { shallowRef, onScopeDispose, type ShallowRef } from 'vue'\nimport type { ReadonlyStore, Store } from '@iris-ui-kit/core'\n\n/**\n * Bridge a framework-agnostic `@iris-ui-kit/core` store into a Vue ref — updates on\n * every store emission. The mirror of React's `useSyncExternalStore`, Solid's\n * `createSignal`, and Svelte's `readable`. Seeds synchronously from\n * `store.getState()` (SSR-safe); detaches on scope dispose.\n */\nexport function useStore<T>(store: ReadonlyStore<T>): Readonly<ShallowRef<T>> {\n const state = shallowRef(store.getState()) as ShallowRef<T>\n onScopeDispose(store.subscribe((next) => (state.value = next)))\n return state\n}\n\n/**\n * Subscribe to a DERIVED slice of a core store — the ref updates only when\n * `selector(state)` changes per `equals` (default `Object.is`), not on every\n * store emission. Built on {@link Store.subscribeWith}.\n */\nexport function useStoreSelector<T, U>(\n store: Store<T>,\n selector: (state: T) => U,\n equals?: (a: U, b: U) => boolean,\n): Readonly<ShallowRef<U>> {\n const slice = shallowRef(selector(store.getState())) as ShallowRef<U>\n onScopeDispose(store.subscribeWith(selector, (v) => (slice.value = v), equals))\n return slice\n}\n","import { computed, type ComputedRef, type Ref } from 'vue'\nimport {\n createFormStore,\n type FieldErrors,\n type FieldFlags,\n type FormConfig,\n type FormState,\n type FormStore,\n type FormValues,\n} from '@iris-ui-kit/core'\nimport { useStore } from '../useStore'\n\nexport interface UseFormReturn<V extends FormValues> {\n /** The form store — pass to `<IrisForm :form=\"...\">`. */\n form: FormStore<V>\n /** The full reactive state snapshot. */\n state: Ref<FormState<V>>\n values: ComputedRef<V>\n errors: ComputedRef<FieldErrors<V>>\n touched: ComputedRef<FieldFlags<V>>\n dirty: ComputedRef<FieldFlags<V>>\n isSubmitting: ComputedRef<boolean>\n isValidating: ComputedRef<boolean>\n submitCount: ComputedRef<number>\n isValid: ComputedRef<boolean>\n setFieldValue: FormStore<V>['setFieldValue']\n setValues: FormStore<V>['setValues']\n setFieldTouched: FormStore<V>['setFieldTouched']\n setFieldError: FormStore<V>['setFieldError']\n setErrors: FormStore<V>['setErrors']\n validateField: FormStore<V>['validateField']\n validateForm: FormStore<V>['validateForm']\n handleSubmit: FormStore<V>['handleSubmit']\n reset: FormStore<V>['reset']\n}\n\n/**\n * Vue binding for the framework-agnostic form engine. Creates the store in\n * `setup()` (runs once) and bridges it into Vue reactivity via `useStore` (a\n * shallow snapshot ref updated on each store change, detached on scope\n * dispose). Because `setup` runs once,\n * `onSubmit` / `validate` closures stay live against reactive state — no\n * stale-callback handling is needed (unlike the React adapter).\n */\nexport function useForm<V extends FormValues>(config: FormConfig<V>): UseFormReturn<V> {\n const form = createFormStore(config)\n\n // Whole-state bridge via the shared `useStore` (shallow, detached on scope\n // dispose — identical to the old `onBeforeUnmount` for setup-scope consumers,\n // and correct for nested scopes too). The published `state: Ref<FormState<V>>`\n // type is unchanged (R5); the runtime is a shallow snapshot — the store is the\n // only write path (it always was), so this localized cast is type-only. The\n // per-field narrowing payoff comes from `useField` / `useFieldArray`; the\n // form-level computeds below are whole-form aggregates by design.\n const state = useStore(form.store) as unknown as Ref<FormState<V>>\n\n return {\n form,\n state,\n values: computed(() => state.value.values),\n errors: computed(() => state.value.errors),\n touched: computed(() => state.value.touched),\n dirty: computed(() => state.value.dirty),\n isSubmitting: computed(() => state.value.isSubmitting),\n isValidating: computed(() => state.value.isValidating),\n submitCount: computed(() => state.value.submitCount),\n isValid: computed(() => Object.keys(state.value.errors).length === 0),\n setFieldValue: form.setFieldValue,\n setValues: form.setValues,\n setFieldTouched: form.setFieldTouched,\n setFieldError: form.setFieldError,\n setErrors: form.setErrors,\n validateField: form.validateField,\n validateForm: form.validateForm,\n handleSubmit: form.handleSubmit,\n reset: form.reset,\n }\n}\n","import { computed, type ComputedRef } from 'vue'\nimport { formatPath, getByPath, parsePath } from '@iris-ui-kit/core'\nimport { useFormContext } from './context'\nimport { useStoreSelector } from '../useStore'\n\nexport interface FieldBindProps {\n modelValue: unknown\n 'onUpdate:modelValue': (value: unknown) => void\n invalid: boolean\n onBlur: () => void\n}\n\nexport interface UseFieldReturn<T> {\n name: string\n value: ComputedRef<T>\n error: ComputedRef<string | undefined>\n touched: ComputedRef<boolean>\n dirty: ComputedRef<boolean>\n setValue: (value: T) => void\n setTouched: (touched?: boolean) => void\n /**\n * Bundle for `v-bind` onto a v-model'd Iris control (`IrisInput`,\n * `IrisSelect`, …): wires `modelValue` / `update:modelValue` / `invalid` /\n * `blur`. Use `value` + `setValue` directly for bespoke bindings.\n */\n fieldProps: ComputedRef<FieldBindProps>\n}\n\n/**\n * Binds a single field to the surrounding `<IrisForm>`. `T` is the value type\n * at the call site (the injection erases the form's generic).\n *\n * `name` may be a flat top-level key OR a nested PATH (`'address.city'`,\n * `'items[2].sku'`); a flat key is a 1-segment path and stays back-compatible\n * (v3 R19).\n */\nexport function useField<T = unknown>(name: string): UseFieldReturn<T> {\n const form = useFormContext()\n\n // Canonical key for per-field state lookups (a flat key maps to itself).\n const key = formatPath(name)\n // Hoisted once — selectors run on every store emission (core `subscribeWith`).\n const segments = parsePath(name)\n\n // Four narrow per-field slices, each Object.is-gated by core `subscribeWith`.\n // Core writes use structural sharing (`setByPath`, per-key flag spread-copies),\n // so an unrelated keystroke does NOT move these refs and this field's computeds\n // do not invalidate (previously a whole-form deep `ref` re-ran every field's\n // computeds on every emission). Selectors are allocation-free by construction.\n const valueSlice = useStoreSelector(form.store, (s) => getByPath(s.values, segments) as T)\n const errorSlice = useStoreSelector(form.store, (s) => s.errors[key])\n const touchedSlice = useStoreSelector(form.store, (s) => Boolean(s.touched[key]))\n const dirtySlice = useStoreSelector(form.store, (s) => Boolean(s.dirty[key]))\n\n // computed wrappers keep the published ComputedRef<T> member types exactly as\n // declared (a bare shallow ref is not assignable to ComputedRef in Vue 3.4+),\n // and each computed invalidates only when its own slice actually moves.\n const value = computed(() => valueSlice.value)\n const error = computed(() => errorSlice.value)\n const touched = computed(() => touchedSlice.value)\n const dirty = computed(() => dirtySlice.value)\n\n return {\n name,\n value,\n error,\n touched,\n dirty,\n setValue: (next) => form.setFieldValue(name, next as never),\n setTouched: (touched = true) => form.setFieldTouched(name, touched),\n fieldProps: computed(() => ({\n modelValue: value.value,\n 'onUpdate:modelValue': (next: unknown) => form.setFieldValue(name, next as never),\n invalid: Boolean(error.value),\n onBlur: () => form.setFieldTouched(name, true),\n })),\n }\n}\n","import { computed, type ComputedRef } from 'vue'\nimport { useFormContext } from './context'\nimport { useStoreSelector } from '../useStore'\n\nexport interface UseFieldArrayReturn<T> {\n name: string\n /** Current array value (reactive). */\n fields: ComputedRef<T[]>\n /** Append an item. */\n push: (item: T) => void\n /** Remove the item at `index`. */\n remove: (index: number) => void\n /** Insert `item` at `index` (shifting the rest right). */\n insert: (index: number, item: T) => void\n /** Move the item from `from` to `to`. */\n move: (from: number, to: number) => void\n /** Replace the whole array. */\n replace: (items: T[]) => void\n}\n\n/**\n * Manage a dynamic array field (repeatable rows) inside an `<IrisForm>`. Mutators\n * delegate to the core {@link FormStore} array helpers (`arrayPush`/`arrayInsert`/\n * `arrayRemove`/`arrayMove`), which RE-KEY each element's error/touched/dirty/\n * validating state across the mutation — so a row's per-element validation state\n * FOLLOWS the row when rows are removed or reordered (removing `items[0]` shifts\n * `items[2]`'s error down to `items[1]`). `replace` swaps the whole array.\n */\nexport function useFieldArray<T = unknown>(name: string): UseFieldArrayReturn<T> {\n const form = useFormContext()\n\n // One narrow slice for the whole array, Object.is-gated by core `subscribeWith`.\n // CRITICAL: the selector must not allocate — `(s) => s.values[name] ?? []` would\n // mint a fresh [] per emission and defeat the Object.is gate — so the `[]`\n // fallback lives in the computed wrapper (re-evaluated only when the raw slice\n // moves). Array mutations produce a fresh array (correct re-render); untouched\n // rows are unaffected.\n const raw = useStoreSelector(form.store, (s) => s.values[name])\n const fields = computed(() => (Array.isArray(raw.value) ? raw.value : []) as T[])\n\n return {\n name,\n fields,\n push: (item) => form.arrayPush(name as never, item as never),\n remove: (index) => form.arrayRemove(name as never, index),\n insert: (index, item) => form.arrayInsert(name as never, index, item as never),\n move: (from, to) => form.arrayMove(name as never, from, to),\n replace: (items) => form.setFieldValue(name, items as never),\n }\n}\n"]}
|
package/dist/form.d.cts
CHANGED
|
@@ -54,8 +54,9 @@ interface UseFormReturn<V extends FormValues> {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Vue binding for the framework-agnostic form engine. Creates the store in
|
|
57
|
-
* `setup()` (runs once) and bridges it into Vue reactivity via
|
|
58
|
-
* on each store change,
|
|
57
|
+
* `setup()` (runs once) and bridges it into Vue reactivity via `useStore` (a
|
|
58
|
+
* shallow snapshot ref updated on each store change, detached on scope
|
|
59
|
+
* dispose). Because `setup` runs once,
|
|
59
60
|
* `onSubmit` / `validate` closures stay live against reactive state — no
|
|
60
61
|
* stale-callback handling is needed (unlike the React adapter).
|
|
61
62
|
*/
|
package/dist/form.d.ts
CHANGED
|
@@ -54,8 +54,9 @@ interface UseFormReturn<V extends FormValues> {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Vue binding for the framework-agnostic form engine. Creates the store in
|
|
57
|
-
* `setup()` (runs once) and bridges it into Vue reactivity via
|
|
58
|
-
* on each store change,
|
|
57
|
+
* `setup()` (runs once) and bridges it into Vue reactivity via `useStore` (a
|
|
58
|
+
* shallow snapshot ref updated on each store change, detached on scope
|
|
59
|
+
* dispose). Because `setup` runs once,
|
|
59
60
|
* `onSubmit` / `validate` closures stay live against reactive state — no
|
|
60
61
|
* stale-callback handling is needed (unlike the React adapter).
|
|
61
62
|
*/
|
package/dist/form.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { FormInjectionKey, IrisForm, useField, useFieldArray, useForm, useFormContext } from './chunk-
|
|
1
|
+
export { FormInjectionKey, IrisForm, useField, useFieldArray, useForm, useFormContext } from './chunk-IAG64CHL.js';
|
|
2
|
+
import './chunk-75GSYEJS.js';
|
|
2
3
|
//# sourceMappingURL=form.js.map
|
|
3
4
|
//# sourceMappingURL=form.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -226,14 +226,21 @@ function useSkin() {
|
|
|
226
226
|
errors: engine.errors
|
|
227
227
|
};
|
|
228
228
|
}
|
|
229
|
-
function useMachine(machine) {
|
|
229
|
+
function useMachine(machine, options = {}) {
|
|
230
230
|
const state = vue.ref(machine.store.getState());
|
|
231
231
|
const unsubscribe = machine.store.subscribe((next) => {
|
|
232
232
|
state.value = next;
|
|
233
233
|
});
|
|
234
|
-
vue.
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
vue.onScopeDispose(
|
|
235
|
+
() => {
|
|
236
|
+
unsubscribe();
|
|
237
|
+
if (options.stopOnUnmount !== false) machine.stop();
|
|
238
|
+
},
|
|
239
|
+
// failSilently: outside any effect scope there is nothing to dispose —
|
|
240
|
+
// registering is a no-op and must not emit the "no active effect scope"
|
|
241
|
+
// dev warning. Within a component/effectScope this arg changes nothing.
|
|
242
|
+
true
|
|
243
|
+
);
|
|
237
244
|
return { state, send: machine.send };
|
|
238
245
|
}
|
|
239
246
|
var FormInjectionKey = /* @__PURE__ */ Symbol("IrisForm");
|
|
@@ -293,11 +300,7 @@ var IrisForm = vue.defineComponent({
|
|
|
293
300
|
});
|
|
294
301
|
function useForm(config) {
|
|
295
302
|
const form = core.createFormStore(config);
|
|
296
|
-
const state =
|
|
297
|
-
const unsubscribe = form.subscribe((next) => {
|
|
298
|
-
state.value = next;
|
|
299
|
-
});
|
|
300
|
-
vue.onBeforeUnmount(unsubscribe);
|
|
303
|
+
const state = useStore(form.store);
|
|
301
304
|
return {
|
|
302
305
|
form,
|
|
303
306
|
state,
|
|
@@ -322,22 +325,24 @@ function useForm(config) {
|
|
|
322
325
|
}
|
|
323
326
|
function useField(name) {
|
|
324
327
|
const form = useFormContext();
|
|
325
|
-
const state = vue.ref(form.getState());
|
|
326
|
-
const unsubscribe = form.subscribe((next) => {
|
|
327
|
-
state.value = next;
|
|
328
|
-
});
|
|
329
|
-
vue.onBeforeUnmount(unsubscribe);
|
|
330
328
|
const key = core.formatPath(name);
|
|
331
|
-
const
|
|
332
|
-
const
|
|
329
|
+
const segments = core.parsePath(name);
|
|
330
|
+
const valueSlice = useStoreSelector(form.store, (s) => core.getByPath(s.values, segments));
|
|
331
|
+
const errorSlice = useStoreSelector(form.store, (s) => s.errors[key]);
|
|
332
|
+
const touchedSlice = useStoreSelector(form.store, (s) => Boolean(s.touched[key]));
|
|
333
|
+
const dirtySlice = useStoreSelector(form.store, (s) => Boolean(s.dirty[key]));
|
|
334
|
+
const value = vue.computed(() => valueSlice.value);
|
|
335
|
+
const error = vue.computed(() => errorSlice.value);
|
|
336
|
+
const touched = vue.computed(() => touchedSlice.value);
|
|
337
|
+
const dirty = vue.computed(() => dirtySlice.value);
|
|
333
338
|
return {
|
|
334
339
|
name,
|
|
335
340
|
value,
|
|
336
341
|
error,
|
|
337
|
-
touched
|
|
338
|
-
dirty
|
|
342
|
+
touched,
|
|
343
|
+
dirty,
|
|
339
344
|
setValue: (next) => form.setFieldValue(name, next),
|
|
340
|
-
setTouched: (
|
|
345
|
+
setTouched: (touched2 = true) => form.setFieldTouched(name, touched2),
|
|
341
346
|
fieldProps: vue.computed(() => ({
|
|
342
347
|
modelValue: value.value,
|
|
343
348
|
"onUpdate:modelValue": (next) => form.setFieldValue(name, next),
|
|
@@ -348,16 +353,11 @@ function useField(name) {
|
|
|
348
353
|
}
|
|
349
354
|
function useFieldArray(name) {
|
|
350
355
|
const form = useFormContext();
|
|
351
|
-
const
|
|
352
|
-
const
|
|
353
|
-
state.value = next;
|
|
354
|
-
});
|
|
355
|
-
vue.onBeforeUnmount(unsubscribe);
|
|
356
|
+
const raw = useStoreSelector(form.store, (s) => s.values[name]);
|
|
357
|
+
const fields = vue.computed(() => Array.isArray(raw.value) ? raw.value : []);
|
|
356
358
|
return {
|
|
357
359
|
name,
|
|
358
|
-
fields
|
|
359
|
-
() => Array.isArray(state.value.values[name]) ? state.value.values[name] : []
|
|
360
|
-
),
|
|
360
|
+
fields,
|
|
361
361
|
push: (item) => form.arrayPush(name, item),
|
|
362
362
|
remove: (index) => form.arrayRemove(name, index),
|
|
363
363
|
insert: (index, item) => form.arrayInsert(name, index, item),
|
|
@@ -465,8 +465,31 @@ function useI18n() {
|
|
|
465
465
|
};
|
|
466
466
|
}
|
|
467
467
|
function useAsyncResource(fetcher, options = {}) {
|
|
468
|
+
const holder = {
|
|
469
|
+
// isRef-only resolution. NEVER toValue() here: the element type is itself
|
|
470
|
+
// a function, so toValue(fetcher) would *invoke the fetcher at setup*
|
|
471
|
+
// (spurious request) and toValue(getter) would do the same. isRef narrows
|
|
472
|
+
// to the only unambiguous reactive form: ref(fetcher) / computed(() =>
|
|
473
|
+
// fetcher) / shallowRef(fetcher) — a ComputedRef IS a Ref.
|
|
474
|
+
// F3 elision point — the ONE explicit narrowing cast: after the isRef
|
|
475
|
+
// guard the else arm is `F | (() => F)`, and the bare-getter arm's return
|
|
476
|
+
// `F` (a function) is not assignable to `F` (TS2322). No runtime
|
|
477
|
+
// discriminant distinguishes a plain fetcher from a bare getter (both are
|
|
478
|
+
// functions), so the cast encodes exactly the documented F3 ambiguity and
|
|
479
|
+
// adds no unsafety beyond F3.
|
|
480
|
+
current: vue.isRef(fetcher) ? fetcher.value : fetcher
|
|
481
|
+
};
|
|
482
|
+
if (vue.isRef(fetcher)) {
|
|
483
|
+
vue.watch(
|
|
484
|
+
fetcher,
|
|
485
|
+
(next) => {
|
|
486
|
+
holder.current = next;
|
|
487
|
+
},
|
|
488
|
+
{ flush: "sync" }
|
|
489
|
+
);
|
|
490
|
+
}
|
|
468
491
|
const config = "initialData" in options ? { initialData: options.initialData } : {};
|
|
469
|
-
const resource = core.createAsyncResource(
|
|
492
|
+
const resource = core.createAsyncResource((...params) => holder.current(...params), config);
|
|
470
493
|
const state = vue.ref(resource.getState());
|
|
471
494
|
const unsubscribe = resource.subscribe((next) => {
|
|
472
495
|
state.value = next;
|
|
@@ -494,7 +517,30 @@ function useAsyncResource(fetcher, options = {}) {
|
|
|
494
517
|
};
|
|
495
518
|
}
|
|
496
519
|
function usePaginatedResource(fetcher, options = {}) {
|
|
497
|
-
const
|
|
520
|
+
const holder = {
|
|
521
|
+
// isRef-only resolution. NEVER toValue() here: the element type is itself
|
|
522
|
+
// a function, so toValue(fetcher) would *invoke the fetcher at setup*
|
|
523
|
+
// (spurious request) and toValue(getter) would do the same. isRef narrows
|
|
524
|
+
// to the only unambiguous reactive form: ref(fetcher) / computed(() =>
|
|
525
|
+
// fetcher) / shallowRef(fetcher) — a ComputedRef IS a Ref.
|
|
526
|
+
// F3 elision point — the ONE explicit narrowing cast: after the isRef
|
|
527
|
+
// guard the else arm is `F | (() => F)`, and the bare-getter arm's return
|
|
528
|
+
// `F` (a function) is not assignable to `F` (TS2322). No runtime
|
|
529
|
+
// discriminant distinguishes a plain fetcher from a bare getter (both are
|
|
530
|
+
// functions), so the cast encodes exactly the documented F3 ambiguity and
|
|
531
|
+
// adds no unsafety beyond F3.
|
|
532
|
+
current: vue.isRef(fetcher) ? fetcher.value : fetcher
|
|
533
|
+
};
|
|
534
|
+
if (vue.isRef(fetcher)) {
|
|
535
|
+
vue.watch(
|
|
536
|
+
fetcher,
|
|
537
|
+
(next) => {
|
|
538
|
+
holder.current = next;
|
|
539
|
+
},
|
|
540
|
+
{ flush: "sync" }
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
const resource = core.createPaginatedResource((query) => holder.current(query), {
|
|
498
544
|
pageSize: options.pageSize,
|
|
499
545
|
mode: options.mode
|
|
500
546
|
});
|
|
@@ -530,10 +576,14 @@ function usePaginatedResource(fetcher, options = {}) {
|
|
|
530
576
|
};
|
|
531
577
|
}
|
|
532
578
|
function useResourceController(config) {
|
|
533
|
-
const controller = core.createResourceController(config);
|
|
579
|
+
const controller = core.createResourceController({ ...config, immediate: false });
|
|
580
|
+
const immediate = config.immediate !== false;
|
|
581
|
+
if (immediate) {
|
|
582
|
+
vue.onMounted(() => void controller.load());
|
|
583
|
+
}
|
|
584
|
+
vue.onScopeDispose(() => controller.destroy());
|
|
534
585
|
const state = vue.shallowRef(controller.getState());
|
|
535
|
-
vue.
|
|
536
|
-
vue.onBeforeUnmount(() => controller.destroy());
|
|
586
|
+
vue.onScopeDispose(controller.subscribe((next) => state.value = next));
|
|
537
587
|
return { ...controller, state };
|
|
538
588
|
}
|
|
539
589
|
function useDataSource(config) {
|
|
@@ -2484,7 +2534,9 @@ var IrisAdminTabs = vue.defineComponent({
|
|
|
2484
2534
|
onClick: (e) => {
|
|
2485
2535
|
e.stopPropagation();
|
|
2486
2536
|
close(tab.key);
|
|
2487
|
-
const root = e.currentTarget.closest(
|
|
2537
|
+
const root = e.currentTarget.closest(
|
|
2538
|
+
'[role="tablist"]'
|
|
2539
|
+
);
|
|
2488
2540
|
void vue.nextTick(() => focusTab(root, props.nav.getState().activeKey));
|
|
2489
2541
|
}
|
|
2490
2542
|
},
|
|
@@ -6406,12 +6458,13 @@ var IrisList = vue.defineComponent({
|
|
|
6406
6458
|
"data-iris-list-index": index,
|
|
6407
6459
|
"data-iris-list-item": "",
|
|
6408
6460
|
"data-state": selected ? "selected" : active ? "active" : "idle",
|
|
6461
|
+
"data-hovered": hoveredIndex.value === index ? "true" : "false",
|
|
6409
6462
|
onClick: item.disabled ? void 0 : onClick,
|
|
6410
6463
|
onFocus,
|
|
6411
|
-
|
|
6464
|
+
onMouseenter: () => {
|
|
6412
6465
|
hoveredIndex.value = index;
|
|
6413
6466
|
},
|
|
6414
|
-
|
|
6467
|
+
onMouseleave: () => {
|
|
6415
6468
|
if (hoveredIndex.value === index) hoveredIndex.value = -1;
|
|
6416
6469
|
},
|
|
6417
6470
|
style: baseStyle
|