@bach.software/vue-dynamic-form 0.1.2 → 0.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.
Files changed (65) hide show
  1. package/README.md +203 -7
  2. package/dist/examples.cjs.js +12 -0
  3. package/dist/examples.cjs.js.map +1 -0
  4. package/dist/examples.es.js +552 -0
  5. package/dist/examples.es.js.map +1 -0
  6. package/dist/src/components/DynamicForm.vue.d.ts +2 -0
  7. package/dist/src/components/DynamicFormItem.analytics.test.d.ts +1 -0
  8. package/dist/src/components/DynamicFormItem.logic.test.d.ts +1 -0
  9. package/dist/src/components/DynamicFormItem.test-helpers.d.ts +21 -0
  10. package/dist/src/components/DynamicFormItem.validation.test.d.ts +1 -0
  11. package/dist/src/components/DynamicFormItem.vue.d.ts +9 -2
  12. package/dist/src/components/DynamicFormItemArray.logic.test.d.ts +1 -0
  13. package/dist/src/components/DynamicFormItemArray.validation.test.d.ts +1 -0
  14. package/dist/src/components/DynamicFormItemArray.vue.d.ts +7 -2
  15. package/dist/src/components/DynamicFormItemChoice.logic.test.d.ts +1 -0
  16. package/dist/src/components/DynamicFormItemChoice.validation.test.d.ts +1 -0
  17. package/dist/src/components/DynamicFormItemChoice.vue.d.ts +7 -2
  18. package/dist/src/components/DynamicFormTemplate.vue.d.ts +78 -20
  19. package/dist/src/core/defineMetadata.d.ts +31 -7
  20. package/dist/src/core/useDynamicForm.d.ts +14 -0
  21. package/dist/src/core/useFieldArrayExtended.d.ts +16 -0
  22. package/dist/src/core/validation.d.ts +7 -0
  23. package/dist/src/core/validation.test.d.ts +1 -0
  24. package/dist/src/examples/DynamicForm.test.d.ts +1 -0
  25. package/dist/src/examples/TestForm.vue.d.ts +9 -0
  26. package/dist/src/examples/TestFormTemplate.testcases.d.ts +8 -0
  27. package/dist/src/examples/TestFormTemplate.vue.d.ts +75 -0
  28. package/dist/src/examples/components/IconButton.vue.d.ts +10 -0
  29. package/dist/src/examples/index.d.ts +3 -0
  30. package/dist/src/index.d.ts +6 -0
  31. package/dist/src/test-setup.d.ts +1 -0
  32. package/dist/src/types/DynamicFormItemProps.d.ts +56 -1
  33. package/dist/src/types/DynamicFormSettings.d.ts +89 -0
  34. package/dist/src/types/FieldMetadata.d.ts +87 -17
  35. package/dist/src/types/InternalFieldMetadata.d.ts +2 -2
  36. package/dist/src/types/KeyValue.d.ts +3 -0
  37. package/dist/src/types/MetadataConfiguration.d.ts +1 -0
  38. package/dist/src/types/ValidationMessage.d.ts +3 -0
  39. package/dist/src/utils/camelize.d.ts +5 -0
  40. package/dist/src/utils/checkTreeHasValue.d.ts +9 -0
  41. package/dist/src/utils/checkTreeHasValue.test.d.ts +1 -0
  42. package/dist/src/utils/createValidation.d.ts +12 -0
  43. package/dist/src/utils/createValidation.test.d.ts +1 -0
  44. package/dist/src/utils/getFieldLabel.d.ts +16 -0
  45. package/dist/src/utils/normalizePath.d.ts +15 -0
  46. package/dist/src/utils/normalizePath.test.d.ts +1 -0
  47. package/dist/src/utils/overridePath.d.ts +19 -0
  48. package/dist/src/utils/overridePath.test.d.ts +1 -0
  49. package/dist/src/utils/resolveMessage.d.ts +17 -0
  50. package/dist/src/utils/resolveMessage.test.d.ts +1 -0
  51. package/dist/src/utils/setInPath.d.ts +10 -0
  52. package/dist/src/utils/setInPath.test.d.ts +1 -0
  53. package/dist/src/utils/splitValidationFunctions.d.ts +15 -0
  54. package/dist/src/utils/splitValidationFunctions.test.d.ts +1 -0
  55. package/dist/tsconfig.tsbuildinfo +1 -0
  56. package/dist/useDynamicForm-3E1RNkVq.cjs +6 -0
  57. package/dist/useDynamicForm-3E1RNkVq.cjs.map +1 -0
  58. package/dist/useDynamicForm-B6YN35Qb.js +684 -0
  59. package/dist/useDynamicForm-B6YN35Qb.js.map +1 -0
  60. package/dist/vue-dynamic-form.cjs.js +2 -0
  61. package/dist/vue-dynamic-form.cjs.js.map +1 -0
  62. package/dist/vue-dynamic-form.es.js +13 -178
  63. package/dist/vue-dynamic-form.es.js.map +1 -0
  64. package/package.json +17 -9
  65. package/dist/vue-dynamic-form.umd.js +0 -1
@@ -0,0 +1,21 @@
1
+ import type { mount } from '@vue/test-utils';
2
+ /** Reads the render count for a field from the analytics DOM span. */
3
+ export declare function renderCount(wrapper: ReturnType<typeof mount>, path: string): number;
4
+ /**
5
+ * Accesses the internal `<script setup>` state of the DynamicFormItem for a given field path.
6
+ * Uses `vm.$.setupState` — an internal Vue API that exposes all setup variables, including
7
+ * private `let` declarations that are not exposed via `defineExpose`.
8
+ */
9
+ export declare function setupState(wrapper: ReturnType<typeof mount>, path: string): Record<string, any> | undefined;
10
+ /** Reads the number of times `combinedValidation` was recomputed for a given field. Returns -1 if the field is not found. */
11
+ export declare function constructValidationCount(wrapper: ReturnType<typeof mount>, path: string): number;
12
+ /** Reads the number of times `computedField` was recomputed for a given field. Returns -1 if the field is not found. */
13
+ export declare function fieldComputeCount(wrapper: ReturnType<typeof mount>, path: string): number;
14
+ /** Reads the number of times the `field` computed (bound to `props.fieldMetadata`) was recomputed. Returns -1 if the field is not found. */
15
+ export declare function fieldChangedCount(wrapper: ReturnType<typeof mount>, path: string): number;
16
+ /** Reads the number of times the value watcher fired for a given field. Returns -1 if the field is not found. */
17
+ export declare function valueChangedCount(wrapper: ReturnType<typeof mount>, path: string): number;
18
+ /** Reads the number of times the notify value change fired for a given field. Returns -1 if the field is not found. */
19
+ export declare function notifyValueUpdateCount(wrapper: ReturnType<typeof mount>, path: string): number;
20
+ /** Returns the current vee-validate form values from the TestForm wrapper. */
21
+ export declare function formValues(wrapper: ReturnType<typeof mount>): Record<string, any>;
@@ -1,12 +1,19 @@
1
1
  import type { DynamicFormItemProps } from '../types/DynamicFormItemProps';
2
2
  import type { FieldMetadata } from '../types/FieldMetadata';
3
3
  import type { InternalFieldMetadata } from '../types/InternalFieldMetadata';
4
+ export interface Emit {
5
+ (e: 'update:modelValue', value: unknown): void;
6
+ (e: 'blur', event?: Event | undefined, shouldValidate?: boolean | undefined): void;
7
+ }
4
8
  declare const _default: <InternalMetadata extends InternalFieldMetadata<FieldMetadata>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
5
- props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & DynamicFormItemProps<InternalMetadata> & Partial<{}>> & import("vue").PublicProps;
9
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
10
+ readonly "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
11
+ readonly onBlur?: ((event?: Event | undefined, shouldValidate?: boolean | undefined) => any) | undefined;
12
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:modelValue" | "onBlur"> & DynamicFormItemProps<InternalMetadata> & Partial<{}>> & import("vue").PublicProps;
6
13
  expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
7
14
  attrs: any;
8
15
  slots: {};
9
- emit: {};
16
+ emit: Emit;
10
17
  }>) => import("vue").VNode & {
11
18
  __ctx?: Awaited<typeof __VLS_setup>;
12
19
  };
@@ -1,12 +1,17 @@
1
1
  import type { DynamicFormItemProps } from '../types/DynamicFormItemProps';
2
2
  import type { FieldMetadata } from '../types/FieldMetadata';
3
3
  import type { InternalFieldMetadata } from '../types/InternalFieldMetadata';
4
+ export interface Emit {
5
+ (e: 'update:modelValue', value: unknown): void;
6
+ }
4
7
  declare const _default: <InternalMetadata extends InternalFieldMetadata<FieldMetadata>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
5
- props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & DynamicFormItemProps<InternalMetadata> & Partial<{}>> & import("vue").PublicProps;
8
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
9
+ readonly "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
10
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:modelValue"> & DynamicFormItemProps<InternalMetadata> & Partial<{}>> & import("vue").PublicProps;
6
11
  expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
7
12
  attrs: any;
8
13
  slots: {};
9
- emit: {};
14
+ emit: Emit;
10
15
  }>) => import("vue").VNode & {
11
16
  __ctx?: Awaited<typeof __VLS_setup>;
12
17
  };
@@ -1,12 +1,17 @@
1
1
  import type { DynamicFormItemProps } from '../types/DynamicFormItemProps';
2
2
  import type { FieldMetadata } from '../types/FieldMetadata';
3
3
  import type { InternalFieldMetadata } from '../types/InternalFieldMetadata';
4
+ export interface Emit {
5
+ (e: 'update:modelValue', value: unknown): void;
6
+ }
4
7
  declare const _default: <InternalMetadata extends InternalFieldMetadata<FieldMetadata>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
5
- props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & DynamicFormItemProps<InternalMetadata> & Partial<{}>> & import("vue").PublicProps;
8
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
9
+ readonly "onUpdate:modelValue"?: ((value: unknown) => any) | undefined;
10
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:modelValue"> & DynamicFormItemProps<InternalMetadata> & Partial<{}>> & import("vue").PublicProps;
6
11
  expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
7
12
  attrs: any;
8
13
  slots: {};
9
- emit: {};
14
+ emit: Emit;
10
15
  }>) => import("vue").VNode & {
11
16
  __ctx?: Awaited<typeof __VLS_setup>;
12
17
  };
@@ -1,36 +1,94 @@
1
+ import type { FieldContext as _FieldContext } from 'vee-validate';
2
+ import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
1
3
  import type { FieldMetadata } from '../types/FieldMetadata';
2
4
  import type { MetadataConfiguration } from '../types/MetadataConfiguration';
5
+ export interface FieldContext<TValue = unknown> extends _FieldContext<TValue> {
6
+ /**
7
+ * Whether this field (or any of its descendants) has a value.
8
+ * Lazily evaluated — only computed when accessed, so safe to use on deep field trees.
9
+ */
10
+ hasValue: ComputedRef<boolean>;
11
+ }
3
12
  export interface DynamicFormConfigurationProps<TMetadataConfiguration extends MetadataConfiguration> {
4
- type?: TMetadataConfiguration['fieldTypes'][number] | 'default';
13
+ /**
14
+ * Use defineMetadata to create a strongly-typed metadata configuration.
15
+ * This metadata configuration can be provided here to type the DynamicFormTemplate component.
16
+ */
5
17
  metadataConfiguration: TMetadataConfiguration;
6
- field?: FieldMetadata<TMetadataConfiguration['fieldTypes'][number], TMetadataConfiguration['extendedProperties']>;
18
+ }
19
+ export interface LimitedFieldContext {
20
+ errors: Ref<string[]>;
21
+ errorMessage: Ref<string | undefined>;
22
+ label?: MaybeRefOrGetter<string | undefined>;
23
+ }
24
+ /**
25
+ * We define the attributes here instead of the props. This way the user don't see them
26
+ * when using the DynamicFormConfiguration component.
27
+ * The attributes will be passed internally by the other components of the library.
28
+ */
29
+ export interface Attributes<TMetadataConfiguration extends MetadataConfiguration> {
30
+ type: TMetadataConfiguration['fieldTypes'][number] | 'default' | 'array' | 'choice';
31
+ /**
32
+ * The metadata that you configured for this field
33
+ */
34
+ fieldMetadata: FieldMetadata<TMetadataConfiguration['fieldTypes'][number], TMetadataConfiguration['extendedProperties']>;
35
+ /**
36
+ * Indicates if a field is required.
37
+ */
38
+ required: boolean;
39
+ /**
40
+ * Indicates whether a field is disabled
41
+ */
42
+ disabled: boolean;
43
+ /**
44
+ * If the field is part of an arrayField, this is its index in the array
45
+ */
46
+ index: number;
47
+ /**
48
+ * If the field is part of an arrayField, this boolean lets you know whether
49
+ * new items can be added. For example: when the maxOccurs is 2 and there are already
50
+ * 2 items, this will be false.
51
+ */
52
+ canAddItems: boolean;
53
+ /**
54
+ * If the field is part of an arrayField, this boolean lets you konw whether
55
+ * an item can be removed. For example: when the minOccurs is 2 and there are already
56
+ * 2 items, this will be false.
57
+ */
58
+ canRemoveItems: boolean;
59
+ /**
60
+ * if the field is part of an arrayField, this method will add another item.
61
+ */
62
+ addItem: () => void;
63
+ /**
64
+ * if the field is part of an arrayField, this method will remove an item.
65
+ */
66
+ removeItem: () => void;
67
+ }
68
+ export interface ItemAttributes<TMetadataConfiguration extends MetadataConfiguration, FieldType extends string = string> extends Attributes<TMetadataConfiguration> {
69
+ /**
70
+ * The extended Vee-Validate context, coming from the useField.
71
+ * A computed hasValue is added, indicating whether the current field or any of its children
72
+ * has a value.
73
+ */
74
+ fieldContext: FieldContext<FieldType extends keyof TMetadataConfiguration['valueTypes'] ? TMetadataConfiguration['valueTypes'][FieldType] : unknown>;
75
+ }
76
+ export interface ArrayChoiceAttributes<TMetadataConfiguration extends MetadataConfiguration> extends Attributes<TMetadataConfiguration> {
77
+ fieldContext: LimitedFieldContext;
7
78
  }
8
79
  declare const _default: <TMetadataConfiguration extends MetadataConfiguration>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
9
80
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & DynamicFormConfigurationProps<TMetadataConfiguration> & Partial<{}>> & import("vue").PublicProps;
10
81
  expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
11
82
  attrs: any;
12
83
  slots: {
13
- default: (props: {
14
- field: NonNullable<FieldMetadata<TMetadataConfiguration["fieldTypes"][number], TMetadataConfiguration["extendedProperties"]> | undefined>;
15
- type: "default" | TMetadataConfiguration["fieldTypes"][number] | undefined;
16
- }) => any;
84
+ default: (props: ItemAttributes<TMetadataConfiguration, string>) => any;
17
85
  } & {
18
- 'default-input': (props: {
19
- field: NonNullable<FieldMetadata<TMetadataConfiguration["fieldTypes"][number], TMetadataConfiguration["extendedProperties"]> | undefined>;
20
- }) => any;
86
+ 'default-input': (props: ItemAttributes<TMetadataConfiguration, string>) => any;
21
87
  } & {
22
- array: (props: {
23
- field: NonNullable<FieldMetadata<TMetadataConfiguration["fieldTypes"][number], TMetadataConfiguration["extendedProperties"]> | undefined>;
24
- }) => any;
88
+ array: (props: ArrayChoiceAttributes<TMetadataConfiguration>) => any;
25
89
  } & {
26
- choice: (props: {
27
- field: NonNullable<FieldMetadata<TMetadataConfiguration["fieldTypes"][number], TMetadataConfiguration["extendedProperties"]> | undefined>;
28
- }) => any;
29
- } & { [K in TMetadataConfiguration["fieldTypes"][number]]: (props: {
30
- field: NonNullable<FieldMetadata<TMetadataConfiguration["fieldTypes"][number], TMetadataConfiguration["extendedProperties"]> | undefined>;
31
- }) => any; } & { [K_1 in `${TMetadataConfiguration["fieldTypes"][number]}-input`]: (props: {
32
- field: NonNullable<FieldMetadata<TMetadataConfiguration["fieldTypes"][number], TMetadataConfiguration["extendedProperties"]> | undefined>;
33
- }) => any; };
90
+ choice: (props: ArrayChoiceAttributes<TMetadataConfiguration>) => any;
91
+ } & { [K in TMetadataConfiguration["fieldTypes"][number]]: (props: ItemAttributes<TMetadataConfiguration, K>) => any; } & { [K_1 in `${TMetadataConfiguration["fieldTypes"][number]}-input`]: (props: ItemAttributes<TMetadataConfiguration, K_1 extends `${infer FieldType}-input` ? FieldType : never>) => any; };
34
92
  emit: {};
35
93
  }>) => import("vue").VNode & {
36
94
  __ctx?: Awaited<typeof __VLS_setup>;
@@ -1,10 +1,34 @@
1
1
  /**
2
- * Creates metadata based on your configuration.
3
- * @param fieldTypes an array of fields that you would like to define. (Note: you can't use 'input' or 'children', they're reserved)
4
- * @param extendedProperties extra properties that you would like to include in your metadata
5
- * @returns a metadata object that can be passed to the DynamicFormTemplate component
2
+ * Helps you to create a metadata configuration with strongly-typed field definitions.
3
+ * Field value types are directly inferred from the provided type interface.
4
+ *
5
+ * Simply pass an interface where keys are field names and values are the expected value types.
6
+ * Use `never` for fields that don't hold values (like headings).
7
+ * Note: you can't use the following reserved field names: 'input', 'children', 'choice', 'array'.
8
+ *
9
+ * Use the extended properties to add custom metadata to each field definition. *
10
+ * @returns Typed configuration object for DynamicFormTemplate consumption
11
+ *
12
+ * @example
13
+ * const config = defineMetadata<
14
+ * {
15
+ * text: string;
16
+ * checkbox: boolean;
17
+ * age: number;
18
+ * address: { street: string; city: string };
19
+ * heading: never;
20
+ * },
21
+ * {
22
+ * // This will add a label and options property to each field's metadata
23
+ * label?: string;
24
+ * options?: Array<{ key: string; value: string }>;
25
+ * }
26
+ * >();
6
27
  */
7
- export declare function defineMetadata<ExtendedProperties extends object, const FieldTypes extends readonly string[]>(fieldTypes: FieldTypes, extendedProperties: ExtendedProperties): {
8
- fieldTypes: readonly ("text" | Exclude<FieldTypes[number], "children" | "choice" | "input" | "array" | "text">)[];
9
- extendedProperties: ExtendedProperties;
28
+ export declare function defineMetadata<const FieldValueTypes extends Record<string, any>, ExtendedFieldProperties extends object = object>(): {
29
+ fieldTypes: readonly ("default" | Exclude<keyof FieldValueTypes, "children" | "choice" | "array" | "input">)[];
30
+ extendedProperties: ExtendedFieldProperties;
31
+ valueTypes: FieldValueTypes & {
32
+ default: string;
33
+ };
10
34
  };
@@ -0,0 +1,14 @@
1
+ import type { PartialDeep } from 'type-fest';
2
+ import type { FlattenAndSetPathsType, FormContext, GenericObject, Path, PathValue } from 'vee-validate';
3
+ import type { MaybeRef, MaybeRefOrGetter, Ref } from 'vue';
4
+ export interface FormOptions<TValues extends GenericObject> {
5
+ initialValues?: PartialDeep<TValues> | undefined | null;
6
+ initialErrors?: FlattenAndSetPathsType<TValues, string | undefined>;
7
+ initialTouched?: FlattenAndSetPathsType<TValues, boolean>;
8
+ validateOnMount?: boolean;
9
+ keepValuesOnUnmount?: MaybeRef<boolean>;
10
+ name?: string;
11
+ }
12
+ export declare function useDynamicForm<TValues extends GenericObject = GenericObject>(opts?: FormOptions<TValues>): FormContext<TValues> & {
13
+ useFieldValue: <TPath extends Path<TValues>>(path?: MaybeRefOrGetter<TPath>) => Ref<PathValue<TValues, TPath>>;
14
+ };
@@ -0,0 +1,16 @@
1
+ import type { MaybeRefOrGetter } from 'vue';
2
+ /**
3
+ * Extended useFieldArray, with the childrens values included.
4
+ */
5
+ export declare function useFieldArrayExtended(arrayPath: MaybeRefOrGetter<string>): {
6
+ remove(idx: number): void;
7
+ replace(newArray: unknown[]): void;
8
+ update(idx: number, value: unknown): void;
9
+ push(value: unknown): void;
10
+ swap(indexA: number, indexB: number): void;
11
+ insert(idx: number, value: unknown): void;
12
+ prepend(value: unknown): void;
13
+ move(oldIdx: number, newIdx: number): void;
14
+ fields: import("vue").Ref<import("vee-validate").FieldEntry<unknown>[], import("vee-validate").FieldEntry<unknown>[]>;
15
+ values: import("vue").ComputedRef<unknown[]>;
16
+ };
@@ -0,0 +1,7 @@
1
+ export { resolveMessage } from '../utils/resolveMessage';
2
+ export type ValidationRule = 'xsd_required' | 'xsd_minOccurs' | 'xsd_choiceMinOccurs' | 'xsd_minLength' | 'xsd_maxLength' | 'xsd_pattern' | 'xsd_minInclusive' | 'xsd_maxInclusive' | 'xsd_minExclusive' | 'xsd_maxExclusive' | 'xsd_enumeration' | 'xsd_length' | 'xsd_whiteSpace' | 'xsd_fractionDigits' | 'xsd_totalDigits';
3
+ /**
4
+ * Maps each rule to its semantic parameter name, enabling named placeholder
5
+ * interpolation (e.g. `{length}`, `{min}`) alongside positional `{0}` in messages.
6
+ */
7
+ export declare const ruleParamNames: Partial<Record<ValidationRule, string>>;
@@ -0,0 +1 @@
1
+ import '../core/validation';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { Metadata } from './TestFormTemplate.vue';
2
+ import type { DynamicFormSettings } from '../types/DynamicFormSettings';
3
+ export interface Props {
4
+ metadata: Metadata[];
5
+ settings?: DynamicFormSettings;
6
+ showDebugState?: boolean;
7
+ }
8
+ declare const _default: import("vue").DefineComponent<Props, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import type { Metadata } from './TestFormTemplate.vue';
2
+ import type { DynamicFormSettings } from '../types/DynamicFormSettings';
3
+ export declare const defaultTestCase: import("vue").Raw<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>>;
4
+ export declare const arrayTestCase: import("vue").Raw<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>>;
5
+ export declare const groupTestCase: import("vue").Raw<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>>;
6
+ export declare const choiceTestCase: import("vue").Raw<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>>;
7
+ export declare const individualTestCase: import("vue").Raw<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>>;
8
+ export declare function createTestCase(metadata: Metadata[], settings?: DynamicFormSettings): import("vue").Raw<import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>>;
@@ -0,0 +1,75 @@
1
+ import type { GetMetadataType } from '../types/GetMetadataType';
2
+ export type Metadata = GetMetadataType<typeof metadata>;
3
+ export interface Props {
4
+ /**
5
+ * Free to decide what attributes you want to pass internally between your templates.
6
+ * You can add any attribute to a <slot /> and then it will be accessible in props.slotProps.
7
+ */
8
+ slotProps?: {
9
+ hideLabel?: boolean;
10
+ /** Example on how to keep track of the levels */
11
+ level?: number;
12
+ /** Helps identifying that we're below a choice field, so if we're rendering an array we can adjust our layout */
13
+ belowChoiceField?: boolean;
14
+ };
15
+ }
16
+ declare const metadata: {
17
+ fieldTypes: readonly ("default" | "checkbox" | "select" | "text" | "textBoundByVModel" | "selectBoundByVModel" | "checkboxBoundByVModel" | "heading")[];
18
+ extendedProperties: {
19
+ description?: string;
20
+ options?: {
21
+ key: string;
22
+ value: string;
23
+ }[];
24
+ fullWidth?: boolean;
25
+ disabled?: boolean;
26
+ };
27
+ valueTypes: {
28
+ text: string;
29
+ textBoundByVModel: string;
30
+ select: string;
31
+ selectBoundByVModel: string;
32
+ checkbox: boolean;
33
+ checkboxBoundByVModel: boolean;
34
+ heading: never;
35
+ } & {
36
+ default: string;
37
+ };
38
+ };
39
+ declare var __VLS_21: {
40
+ level: number;
41
+ }, __VLS_24: {
42
+ level: number;
43
+ belowChoiceField: boolean;
44
+ }, __VLS_34: {
45
+ level: number;
46
+ }, __VLS_36: {}, __VLS_45: {
47
+ hideLabel: boolean;
48
+ }, __VLS_62: {
49
+ level: number;
50
+ }, __VLS_64: {}, __VLS_73: {};
51
+ type __VLS_Slots = {} & {
52
+ default?: (props: typeof __VLS_21) => any;
53
+ } & {
54
+ default?: (props: typeof __VLS_24) => any;
55
+ } & {
56
+ default?: (props: typeof __VLS_34) => any;
57
+ } & {
58
+ default?: (props: typeof __VLS_36) => any;
59
+ } & {
60
+ default?: (props: typeof __VLS_45) => any;
61
+ } & {
62
+ default?: (props: typeof __VLS_62) => any;
63
+ } & {
64
+ default?: (props: typeof __VLS_64) => any;
65
+ } & {
66
+ attributes?: (props: typeof __VLS_73) => any;
67
+ };
68
+ declare const __VLS_component: import("vue").DefineComponent<Props, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
69
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
70
+ export default _default;
71
+ type __VLS_WithSlots<T, S> = T & {
72
+ new (): {
73
+ $slots: S;
74
+ };
75
+ };
@@ -0,0 +1,10 @@
1
+ interface Props {
2
+ icon: 'plus' | 'minus';
3
+ color?: 'blue' | 'red';
4
+ }
5
+ declare const _default: import("vue").DefineComponent<Props, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
6
+ click: () => any;
7
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
8
+ onClick?: (() => any) | undefined;
9
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export * from './TestFormTemplate.testcases';
2
+ export { default as TestFormTemplate } from './TestFormTemplate.vue';
3
+ export { type Metadata } from './TestFormTemplate.vue';
@@ -4,7 +4,13 @@ export { default as DynamicFormItemArray } from './components/DynamicFormItemArr
4
4
  export { default as DynamicFormItemChoice } from './components/DynamicFormItemChoice.vue';
5
5
  export { default as DynamicFormTemplate } from './components/DynamicFormTemplate.vue';
6
6
  export * from './core/defineMetadata';
7
+ export * from './core/useDynamicForm';
8
+ export * from './core/useFieldArrayExtended';
9
+ export * from './core/validation';
7
10
  export * from './types/DynamicFormItemProps';
11
+ export * from './types/DynamicFormSettings';
8
12
  export * from './types/FieldMetadata';
9
13
  export * from './types/GetMetadataType';
14
+ export * from './types/MetadataConfiguration';
10
15
  export * from './types/RequireOnly';
16
+ export * from './types/ValidationMessage';
@@ -0,0 +1 @@
1
+ export {};
@@ -9,5 +9,60 @@ export interface DynamicFormItemProps<InternalMetadata extends InternalFieldMeta
9
9
  choice?: ((props: object) => any) | undefined;
10
10
  array?: ((props: object) => any) | undefined;
11
11
  }>;
12
- field: InternalMetadata;
12
+ fieldMetadata: InternalMetadata;
13
+ /**
14
+ * In case a parent can occur multiple times, its path will have an index in it.
15
+ * This needs to be passed to the child items so they can adjust their own path accordingly.
16
+ *
17
+ * Example scenario:
18
+ * - field.path = root.collections.item.nested.deepItems
19
+ * - pathOverride = root.collections[3]
20
+ * - Result: root.collections[3].item.nested.deepItems
21
+ * Full path specification is unnecessary; partial override suffices.
22
+ */
23
+ pathOverride?: string;
24
+ /**
25
+ * Runtime adjustment of minimum occurrence constraint for this field.
26
+ * Controls requirement level: 0 makes optional, 1 enforces presence, higher values demand repetition.
27
+ *
28
+ * For example: Conditional sections where child validation activates only after
29
+ * user interaction with any descendant field.
30
+ */
31
+ minOccursOverride?: number;
32
+ /**
33
+ * Runtime adjustment of maximum occurrence constraint for this field.
34
+ * Values exceeding 1 transform the field into a repeatable collection with multiple instances.
35
+ *
36
+ * For example: Within choice groups, disable add button when any option
37
+ * reaches the shared occurrence limit.
38
+ */
39
+ maxOccursOverride?: number;
40
+ /**
41
+ * In case this field is part of a array field, it needs to co-operate with that array field and
42
+ * mark all children optional if no value has been filled in.
43
+ */
44
+ partOfArrayField?: boolean;
45
+ /**
46
+ * In case this field is part of a choice field, it needs to co-operate with that choice field and
47
+ * behave differently in some situations.
48
+ */
49
+ partOfChoiceField?: boolean;
50
+ /**
51
+ * We check the maxOccurs to see if the field is an Array. If we want to override this, we can do so with this property.
52
+ * In case the field is a child of a choice field, it needs to be made repeatable and we can set this to true.
53
+ */
54
+ isArrayOverride?: 'auto' | 'array' | 'single';
55
+ /**
56
+ * In case this item is part of a field array, we need some extra info
57
+ */
58
+ index?: number;
59
+ canAddItems?: boolean;
60
+ canRemoveItems?: boolean;
61
+ addItem?: () => void;
62
+ removeItem?: (index?: number) => void;
63
+ /**
64
+ * You can provide additional attributes to the slots in your template. They will be passed to the
65
+ * component below.
66
+ */
67
+ slotProps?: object;
13
68
  }
@@ -0,0 +1,89 @@
1
+ import type { ValidationMessage } from '../types/ValidationMessage';
2
+ export declare const dynamicFormSettingsKey: unique symbol;
3
+ export interface DynamicFormSettings {
4
+ /**
5
+ * Enables diagnostic data output via concealed DOM elements for reactivity testing
6
+ */
7
+ analytics?: boolean;
8
+ /**
9
+ * In case of a complex type the value is stored in a value property, i.e. { value: 'the actual value' }
10
+ * Use complexTypeValueProperty to change the property name, for example 'myValue' will result in { myValue: 'the actual value' }
11
+ */
12
+ complexTypeValueProperty?: string;
13
+ /**
14
+ * When true, validates fields on every value change.
15
+ * When false, only validates on submit.
16
+ *
17
+ * Defaults to true.
18
+ */
19
+ validateOnValueUpdate?: boolean;
20
+ /**
21
+ * When true, validates fields on every value change after the first submit.
22
+ * When false, listen to the validateOnValueUpdate.
23
+ *
24
+ * Defaults to false.
25
+ */
26
+ validateOnValueUpdateAfterSubmit?: boolean;
27
+ /**
28
+ * When true, validates fields on blur.
29
+ *
30
+ * Defaults to false.
31
+ */
32
+ validateOnBlur?: boolean;
33
+ /**
34
+ * When true, validates fields on every value change when the field has an error.
35
+ *
36
+ * Defaults to false.
37
+ */
38
+ validateWhenInError?: boolean;
39
+ /**
40
+ * Use this setting to override the default text of the validation messages.
41
+ *
42
+ * Each message accepts either a `string` template or a `(ctx) => string` function.
43
+ *
44
+ * String templates support the following placeholders:
45
+ * - `{field}` — the field label
46
+ * - `{value}` — the current field value
47
+ * - `{0}`, `{1}`, ... — rule params by position (e.g. `{0}` = the limit value)
48
+ * - Named params where supported (e.g. `{min}`, `{max}`)
49
+ *
50
+ * Examples:
51
+ * ```ts
52
+ * required: 'The {field} field is required'
53
+ * minLength: 'The {field} must be at least {0} characters'
54
+ * minLength: (ctx) => `${ctx.field} is too short`
55
+ * ```
56
+ */
57
+ messages?: {
58
+ /** XSD: required. Available placeholders: `{field}` */
59
+ required?: ValidationMessage;
60
+ /** XSD: minOccurs. Available placeholders: `{field}`, `{0}` or `{min}` (min number of filled items) */
61
+ minOccurs?: ValidationMessage;
62
+ /** XSD: choiceMinOccurs. Available placeholders: `{field}`, `{0}` or `{min}` (min number of filled items) */
63
+ choiceMinOccurs?: ValidationMessage;
64
+ /** XSD: minLength. Available placeholders: `{field}`, `{0}` or `{length}` (min length) */
65
+ minLength?: ValidationMessage;
66
+ /** XSD: maxLength. Available placeholders: `{field}`, `{0}` or `{length}` (max length) */
67
+ maxLength?: ValidationMessage;
68
+ /** XSD: length. Available placeholders: `{field}`, `{0}` or `{length}` (exact length) */
69
+ length?: ValidationMessage;
70
+ /** XSD: pattern. Available placeholders: `{field}`, `{0}` or `{pattern}` (regex pattern) */
71
+ pattern?: ValidationMessage;
72
+ /** XSD: minInclusive. Available placeholders: `{field}`, `{0}` or `{min}` (min value, inclusive) */
73
+ minInclusive?: ValidationMessage;
74
+ /** XSD: maxInclusive. Available placeholders: `{field}`, `{0}` or `{max}` (max value, inclusive) */
75
+ maxInclusive?: ValidationMessage;
76
+ /** XSD: minExclusive. Available placeholders: `{field}`, `{0}` or `{min}` (min value, exclusive) */
77
+ minExclusive?: ValidationMessage;
78
+ /** XSD: maxExclusive. Available placeholders: `{field}`, `{0}` or `{max}` (max value, exclusive) */
79
+ maxExclusive?: ValidationMessage;
80
+ /** XSD: enumeration. Available placeholders: `{field}` */
81
+ enumeration?: ValidationMessage;
82
+ /** XSD: whiteSpace. Available placeholders: `{field}`, `{0}` or `{mode}` (preserve | replace | collapse) */
83
+ whiteSpace?: ValidationMessage;
84
+ /** XSD: fractionDigits. Available placeholders: `{field}`, `{0}` or `{digits}` (max decimal places) */
85
+ fractionDigits?: ValidationMessage;
86
+ /** XSD: totalDigits. Available placeholders: `{field}`, `{0}` or `{digits}` (max total digits) */
87
+ totalDigits?: ValidationMessage;
88
+ };
89
+ }