@myparcel-dev/vue-form-builder 1.0.0-beta.53
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/CHANGELOG.md +301 -0
- package/dist/components/FormElement.vue.d.ts +22 -0
- package/dist/components/FormElementWrapper.d.ts +24 -0
- package/dist/components/Fragment.vue.d.ts +17 -0
- package/dist/components/MagicForm.vue.d.ts +67 -0
- package/dist/components/RenderedFormContent.vue.d.ts +2 -0
- package/dist/composables/createFieldHooks.d.ts +5 -0
- package/dist/composables/useElement.d.ts +3 -0
- package/dist/composables/useForm.d.ts +3 -0
- package/dist/composables/useFormBuilder.d.ts +3 -0
- package/dist/composables/useLifecycleHooks.d.ts +10 -0
- package/dist/composables/useTestAttributes.d.ts +3 -0
- package/dist/data/hooks.d.ts +14 -0
- package/dist/deprecated.d.ts +8 -0
- package/dist/form/Field.d.ts +55 -0
- package/dist/form/Form.d.ts +36 -0
- package/dist/hooks/HookManager.d.ts +27 -0
- package/dist/hooks/createHookManager.d.ts +4 -0
- package/dist/hooks/filterMatchingHooks.d.ts +3 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +683 -0
- package/dist/plugin/MyParcelFormBuilderPlugin.d.ts +10 -0
- package/dist/plugin/devtools/createFieldsNodes.d.ts +5 -0
- package/dist/plugin/devtools/createFormNode.d.ts +5 -0
- package/dist/plugin/devtools/getComponentName.d.ts +3 -0
- package/dist/plugin/devtools/setupDevtools.d.ts +3 -0
- package/dist/plugin/devtools/types.d.ts +7 -0
- package/dist/symbols.d.ts +6 -0
- package/dist/types/common.types.d.ts +6 -0
- package/dist/types/component.types.d.ts +17 -0
- package/dist/types/deprecated.types.d.ts +35 -0
- package/dist/types/element.types.d.ts +0 -0
- package/dist/types/field.types.d.ts +199 -0
- package/dist/types/form-builder.types.d.ts +27 -0
- package/dist/types/form.types.d.ts +202 -0
- package/dist/types/hooks.types.d.ts +11 -0
- package/dist/types/other.types.d.ts +0 -0
- package/dist/types/plain-element.types.d.ts +0 -0
- package/dist/types/utils.types.d.ts +14 -0
- package/dist/types/validator.types.d.ts +21 -0
- package/dist/utils/createField.d.ts +3 -0
- package/dist/utils/createForm.d.ts +3 -0
- package/dist/utils/defineField.d.ts +8 -0
- package/dist/utils/defineForm.d.ts +3 -0
- package/dist/utils/generateFieldName.d.ts +4 -0
- package/dist/utils/getDefaultFormConfiguration.d.ts +3 -0
- package/dist/utils/markComponentAsRaw.d.ts +4 -0
- package/dist/utils/normalizeFieldConfiguration.d.ts +12 -0
- package/dist/utils/normalizeFormConfiguration.d.ts +3 -0
- package/dist/utils/toPromise.d.ts +3 -0
- package/dist/utils/useDynamicWatcher.d.ts +4 -0
- package/dist/validators/isRequired.d.ts +4 -0
- package/package.json +51 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { UnwrapNestedRefs } from 'vue';
|
|
2
|
+
import { CustomInspectorNode } from '@vue/devtools-api';
|
|
3
|
+
import { FormInstance } from '../../types/form.types';
|
|
4
|
+
|
|
5
|
+
export declare const createFormNode: (name: string, form: UnwrapNestedRefs<FormInstance>) => CustomInspectorNode;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const PINK_500 = 15485081;
|
|
2
|
+
export declare const BLUE_600 = 2450411;
|
|
3
|
+
export declare const LIME_500 = 8702998;
|
|
4
|
+
export declare const CYAN_400 = 2282478;
|
|
5
|
+
export declare const ORANGE_400 = 16486972;
|
|
6
|
+
export declare const GRAY_100 = 16053493;
|
|
7
|
+
export declare const DARK = 6710886;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InjectionKey } from 'vue';
|
|
2
|
+
import { FormInstance } from './types/form.types';
|
|
3
|
+
import { FieldInstance } from './types/field.types';
|
|
4
|
+
|
|
5
|
+
export declare const INJECT_FORM: InjectionKey<FormInstance>;
|
|
6
|
+
export declare const INJECT_ELEMENT: InjectionKey<FieldInstance<unknown, any>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component } from 'vue';
|
|
2
|
+
import { PromiseOr } from '@myparcel-dev/ts-utils';
|
|
3
|
+
import { FieldInstance } from './field.types';
|
|
4
|
+
|
|
5
|
+
export interface ComponentLifecycleHooks<I extends FieldInstance = FieldInstance> {
|
|
6
|
+
onActivated?(instance: I): PromiseOr<void>;
|
|
7
|
+
onBeforeMount?(instance: I): PromiseOr<void>;
|
|
8
|
+
onBeforeUnmount?(instance: I): PromiseOr<void>;
|
|
9
|
+
onBeforeUpdate?(instance: I): PromiseOr<void>;
|
|
10
|
+
onCreated?(instance: I): PromiseOr<void>;
|
|
11
|
+
onDeactivated?(instance: I): PromiseOr<void>;
|
|
12
|
+
onMounted?(instance: I): PromiseOr<void>;
|
|
13
|
+
onUnmounted?(instance: I): PromiseOr<void>;
|
|
14
|
+
onUpdated?(instance: I): PromiseOr<void>;
|
|
15
|
+
}
|
|
16
|
+
export type ComponentProps = any;
|
|
17
|
+
export type ComponentOrHtmlElement<Props extends ComponentProps = ComponentProps> = string | Component<Props>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { FieldName, FieldSlots, FieldConfiguration, FieldInstance, FieldHooks, CreatedField, ModularCreatedField } from './field.types';
|
|
2
|
+
import { ComponentProps } from './component.types';
|
|
3
|
+
|
|
4
|
+
/** @deprecated use FieldName */
|
|
5
|
+
export type ElementName = FieldName;
|
|
6
|
+
/** @deprecated use FieldSlots */
|
|
7
|
+
export type ElementSlots = FieldSlots;
|
|
8
|
+
/** @deprecated use FieldConfiguration */
|
|
9
|
+
export type BaseElementConfiguration<Props extends ComponentProps = ComponentProps> = FieldConfiguration<unknown, Props>;
|
|
10
|
+
/** @deprecated use FieldConfiguration */
|
|
11
|
+
export type PlainElementConfiguration<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldConfiguration<Type, Props>;
|
|
12
|
+
/** @deprecated use FieldConfiguration */
|
|
13
|
+
export type InteractiveElementConfiguration<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldConfiguration<Type, Props>;
|
|
14
|
+
/** @deprecated use FieldConfiguration * */
|
|
15
|
+
export type AnyElementConfiguration<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldConfiguration<Type, Props>;
|
|
16
|
+
/** @deprecated use FieldConfiguration */
|
|
17
|
+
export type ResolvedElementConfiguration<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldConfiguration<Type, Props>;
|
|
18
|
+
/** @deprecated use FieldHooks */
|
|
19
|
+
export type BaseElementHooks<I extends FieldInstance = FieldInstance> = FieldHooks<unknown, ComponentProps, I>;
|
|
20
|
+
/** @deprecated use FieldConfiguration */
|
|
21
|
+
export type PlainElementHooks<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldHooks<Type, Props>;
|
|
22
|
+
/** @deprecated use FieldConfiguration */
|
|
23
|
+
export type InteractiveElementHooks<Type = unknown, Props extends ComponentProps = ComponentProps, I extends FieldInstance<Type, Props> = FieldInstance<Type, Props>> = FieldHooks<Type, Props, I>;
|
|
24
|
+
/** @deprecated use FieldInstance */
|
|
25
|
+
export type BaseFieldInstance<Props extends ComponentProps = ComponentProps> = FieldInstance<unknown, Props>;
|
|
26
|
+
/** @deprecated use FieldInstance */
|
|
27
|
+
export type PlainElementInstance<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldInstance<Type, Props>;
|
|
28
|
+
/** @deprecated use FieldInstance */
|
|
29
|
+
export type InteractiveElementInstance<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldInstance<Type, Props>;
|
|
30
|
+
/** @deprecated use FieldInstance * */
|
|
31
|
+
export type AnyElementInstance<Type = unknown, Props extends ComponentProps = ComponentProps> = FieldInstance<Type, Props>;
|
|
32
|
+
/** @deprecated use CreatedField */
|
|
33
|
+
export type CreatedElement<Type = unknown, Props extends ComponentProps = ComponentProps> = CreatedField<Type, Props>;
|
|
34
|
+
/** @deprecated use ModularCreatedField */
|
|
35
|
+
export type ModularCreatedElement<Type = unknown, Props extends ComponentProps = ComponentProps> = ModularCreatedField<Type, Props>;
|
|
File without changes
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { ComponentSlots } from 'vue-component-type-helpers';
|
|
2
|
+
import { Ref, ComputedRef, Component, Slots } from 'vue';
|
|
3
|
+
import { UnwrapNestedRefs } from '@vue/reactivity';
|
|
4
|
+
import { PromiseOr, ReadonlyOr } from '@myparcel-dev/ts-utils';
|
|
5
|
+
import { HookManagerInstance } from '../hooks/HookManager';
|
|
6
|
+
import { Validator, ValidateFunction } from './validator.types';
|
|
7
|
+
import { AnyAttributes, FunctionOr } from './utils.types';
|
|
8
|
+
import { FormInstance } from './form.types';
|
|
9
|
+
import { ComponentProps, ComponentOrHtmlElement } from './component.types';
|
|
10
|
+
import { ToRecord } from './common.types';
|
|
11
|
+
|
|
12
|
+
export type FieldName = string;
|
|
13
|
+
export type FieldSlots = Slots;
|
|
14
|
+
export interface CreatedField<Type = unknown, Props extends ComponentProps = ComponentProps> {
|
|
15
|
+
Component: Component<Props>;
|
|
16
|
+
field: FieldConfiguration<Type, Props>;
|
|
17
|
+
ref: Ref<Type>;
|
|
18
|
+
}
|
|
19
|
+
export interface ModularCreatedField<Type = unknown, Props extends ComponentProps = ComponentProps> extends CreatedField<Type, Props> {
|
|
20
|
+
/**
|
|
21
|
+
* Only available when `wrapper` is `false`.
|
|
22
|
+
* @TODO: reflect this in the type
|
|
23
|
+
*/
|
|
24
|
+
Errors: Component;
|
|
25
|
+
/**
|
|
26
|
+
* Only available when `wrapper` is `false`.
|
|
27
|
+
* @TODO: reflect this in the type
|
|
28
|
+
*/
|
|
29
|
+
Label: Component;
|
|
30
|
+
}
|
|
31
|
+
export interface FieldConfiguration<Type = unknown, Props extends ComponentProps = ComponentProps> extends FieldHooks<Type, Props> {
|
|
32
|
+
name: FieldName;
|
|
33
|
+
/**
|
|
34
|
+
* Attributes to be passed to the component.
|
|
35
|
+
*/
|
|
36
|
+
attributes?: AnyAttributes;
|
|
37
|
+
/**
|
|
38
|
+
* HTML element or Vue component. Can be any type of component that renders as a Vue fragment, including JSX
|
|
39
|
+
* templates.
|
|
40
|
+
*/
|
|
41
|
+
component: ComponentOrHtmlElement<Props>;
|
|
42
|
+
/**
|
|
43
|
+
* Name of the field to port errors to.
|
|
44
|
+
*/
|
|
45
|
+
errorsTarget?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Hooks to be registered.
|
|
48
|
+
*/
|
|
49
|
+
hookNames?: ReadonlyOr<string[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Element label.
|
|
52
|
+
*/
|
|
53
|
+
label?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Props to be passed to the component.
|
|
56
|
+
*/
|
|
57
|
+
props?: Props;
|
|
58
|
+
/**
|
|
59
|
+
* Slot content to be passed to the component.
|
|
60
|
+
*/
|
|
61
|
+
slots?: ComponentSlots<never>;
|
|
62
|
+
/**
|
|
63
|
+
* Selector to render the field in.
|
|
64
|
+
* @deprecated
|
|
65
|
+
*/
|
|
66
|
+
teleportSelector?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Visibility of the element. Defaults to true.
|
|
69
|
+
*/
|
|
70
|
+
visible?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Wrap the field in a TableFormGroup. Defaults to true.
|
|
73
|
+
*/
|
|
74
|
+
wrapper?: boolean | Component;
|
|
75
|
+
/**
|
|
76
|
+
* The ref of the field. Will be created if not provided.
|
|
77
|
+
*/
|
|
78
|
+
ref?: Ref<Type>;
|
|
79
|
+
validate?: ValidateFunction<Type, Props>;
|
|
80
|
+
errorMessage?: FunctionOr<string>;
|
|
81
|
+
precedence?: number;
|
|
82
|
+
validators?: Validator<Type, Props>[];
|
|
83
|
+
/**
|
|
84
|
+
* Whether the field is lazy. Defaults to false.
|
|
85
|
+
*/
|
|
86
|
+
lazy?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Whether the element is disabled. Defaults to false.
|
|
89
|
+
*/
|
|
90
|
+
disabled?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Whether the element is optional. Defaults to false.
|
|
93
|
+
*/
|
|
94
|
+
optional?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Whether the element is read-only. Defaults to false.z
|
|
97
|
+
*/
|
|
98
|
+
readOnly?: boolean;
|
|
99
|
+
visibleWhen?(instance: FieldInstance<Type, Props>): PromiseOr<boolean>;
|
|
100
|
+
disabledWhen?(instance: FieldInstance<Type, Props>): PromiseOr<boolean>;
|
|
101
|
+
optionalWhen?(instance: FieldInstance<Type, Props>): PromiseOr<boolean>;
|
|
102
|
+
readOnlyWhen?(instance: FieldInstance<Type, Props>): PromiseOr<boolean>;
|
|
103
|
+
}
|
|
104
|
+
export interface FieldHooks<Type = unknown, Props extends ComponentProps = ComponentProps, I extends FieldInstance<Type, Props> = FieldInstance<Type, Props>> {
|
|
105
|
+
beforeFocus?(instance: I, event: FocusEvent): PromiseOr<void>;
|
|
106
|
+
focus?(instance: I, event: FocusEvent): PromiseOr<void>;
|
|
107
|
+
afterFocus?(instance: I, event: FocusEvent): PromiseOr<void>;
|
|
108
|
+
beforeClick?(instance: I): PromiseOr<void>;
|
|
109
|
+
click?(instance: I, event: MouseEvent): PromiseOr<void>;
|
|
110
|
+
afterClick?(instance: I): PromiseOr<void>;
|
|
111
|
+
beforeBlur?(instance: I, value: Type): PromiseOr<void>;
|
|
112
|
+
blur?(instance: I, event: MouseEvent): PromiseOr<void>;
|
|
113
|
+
afterBlur?(instance: I, value: Type): PromiseOr<void>;
|
|
114
|
+
beforeSanitize?(instance: I, value: Type): PromiseOr<void>;
|
|
115
|
+
afterSanitize?(instance: I, value: Type): PromiseOr<void>;
|
|
116
|
+
beforeUpdate?(instance: I, value: Type, oldValue: Type): PromiseOr<void>;
|
|
117
|
+
afterUpdate?(instance: I, value: Type, oldValueT: Type): PromiseOr<void>;
|
|
118
|
+
beforeValidate?(instance: I, value: Type): PromiseOr<void>;
|
|
119
|
+
afterValidate?(instance: I, value: Type, isValid: boolean): PromiseOr<void>;
|
|
120
|
+
}
|
|
121
|
+
export interface FieldInstance<Type = unknown, Props extends ComponentProps = ComponentProps> extends FieldHooks<Type, Props> {
|
|
122
|
+
ref: Ref<Type>;
|
|
123
|
+
readonly name: FieldName;
|
|
124
|
+
readonly form: FormInstance;
|
|
125
|
+
readonly component: ComponentOrHtmlElement<Props>;
|
|
126
|
+
readonly config: FieldConfiguration<Type, Props>;
|
|
127
|
+
readonly hooks: HookManagerInstance<ToRecord<FieldHooks<Type, Props>>>;
|
|
128
|
+
readonly lazy: boolean;
|
|
129
|
+
readonly wrapper: boolean | Component;
|
|
130
|
+
readonly attributes: UnwrapNestedRefs<AnyAttributes>;
|
|
131
|
+
readonly props: UnwrapNestedRefs<Props>;
|
|
132
|
+
/** @deprecated use template slots */
|
|
133
|
+
readonly slots?: FieldSlots;
|
|
134
|
+
/** @deprecated */
|
|
135
|
+
readonly teleportSelector?: string;
|
|
136
|
+
readonly label?: string;
|
|
137
|
+
readonly errorsTarget?: string;
|
|
138
|
+
readonly errors: Ref<FunctionOr<string>[]>;
|
|
139
|
+
readonly formattedErrors: ComputedRef<string[]>;
|
|
140
|
+
readonly isVisible: Ref<boolean>;
|
|
141
|
+
readonly isDirty: Ref<boolean>;
|
|
142
|
+
readonly isDisabled: Ref<boolean>;
|
|
143
|
+
readonly isOptional: Ref<boolean>;
|
|
144
|
+
readonly isReadOnly: Ref<boolean>;
|
|
145
|
+
readonly isSuspended: Ref<boolean>;
|
|
146
|
+
readonly isTouched: Ref<boolean>;
|
|
147
|
+
/**
|
|
148
|
+
* Determines whether the field is valid.
|
|
149
|
+
*/
|
|
150
|
+
readonly isValid: Ref<boolean>;
|
|
151
|
+
/**
|
|
152
|
+
* Validators used to compute the value of isValid.
|
|
153
|
+
*/
|
|
154
|
+
readonly validators: Ref<Validator<Type, Props>[]>;
|
|
155
|
+
/**
|
|
156
|
+
* Resets the field.
|
|
157
|
+
*/
|
|
158
|
+
reset(): PromiseOr<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Destroys the field.
|
|
161
|
+
*/
|
|
162
|
+
destroy(): Promise<void>;
|
|
163
|
+
/**
|
|
164
|
+
* Validates the field.
|
|
165
|
+
*/
|
|
166
|
+
validate(): Promise<boolean>;
|
|
167
|
+
resetValidation(): void;
|
|
168
|
+
setValue(value: Type): void;
|
|
169
|
+
setDisabled(disabled: boolean): void;
|
|
170
|
+
setOptional(optional: boolean): void;
|
|
171
|
+
setReadOnly(optional: boolean): void;
|
|
172
|
+
addError(error: string): void;
|
|
173
|
+
setVisible(value: boolean): void;
|
|
174
|
+
setInvalid(): void;
|
|
175
|
+
}
|
|
176
|
+
export type ElementProp<Type = unknown, Props = ComponentProps> = UnwrapNestedRefs<FieldInstance<Type, Props>>;
|
|
177
|
+
export interface FieldWrapperProps<Type = unknown, Props = ComponentProps> {
|
|
178
|
+
element: ElementProp<Type, Props>;
|
|
179
|
+
}
|
|
180
|
+
export interface FieldProps<Type = unknown, Props = ComponentProps> extends FieldWrapperProps<Type, Props> {
|
|
181
|
+
modelValue: Type;
|
|
182
|
+
}
|
|
183
|
+
export type FieldEmits<Type = unknown> = (event: 'update:modelValue', value: Type) => void;
|
|
184
|
+
export declare const FIELD_INSTANCE_PROPS_KEYS: readonly ["name", "isVisible", "isDirty", "isDisabled", "isOptional", "isReadOnly", "isSuspended", "isTouched", "isValid"];
|
|
185
|
+
/**
|
|
186
|
+
* The properties of a field instance that are spread into the component.
|
|
187
|
+
* This can be aded to the component props definition to make the field instance available in the component.
|
|
188
|
+
*/
|
|
189
|
+
export type FieldInstanceProps = {
|
|
190
|
+
name?: string;
|
|
191
|
+
isVisible?: boolean;
|
|
192
|
+
isDirty?: boolean;
|
|
193
|
+
isDisabled?: boolean;
|
|
194
|
+
isOptional?: boolean;
|
|
195
|
+
isReadOnly?: boolean;
|
|
196
|
+
isSuspended?: boolean;
|
|
197
|
+
isTouched?: boolean;
|
|
198
|
+
isValid?: boolean;
|
|
199
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { InstanceFormConfiguration, FormInstance, FormValues, FormConfiguration } from './form.types';
|
|
3
|
+
|
|
4
|
+
export type FormBuilder = {
|
|
5
|
+
/**
|
|
6
|
+
* All registered forms.
|
|
7
|
+
*/
|
|
8
|
+
forms: Ref<Record<string, FormInstance>>;
|
|
9
|
+
/**
|
|
10
|
+
* Default settings to apply to newly registered forms.
|
|
11
|
+
*/
|
|
12
|
+
defaults: Ref<InstanceFormConfiguration>;
|
|
13
|
+
on(hook: 'beforeRegister', callback: () => void): void;
|
|
14
|
+
on(hook: 'afterRegister', callback: (form: FormInstance) => void): void;
|
|
15
|
+
/**
|
|
16
|
+
* Register a new form. If a form with the same name already exists, it will be overwritten.
|
|
17
|
+
*/
|
|
18
|
+
register<V extends FormValues = FormValues, N extends string = string>(name: N, config?: FormConfiguration<V>): FormInstance<V>;
|
|
19
|
+
/**
|
|
20
|
+
* Retrieve a previously registered form.
|
|
21
|
+
*/
|
|
22
|
+
getForm<N extends string>(name: N): FormInstance;
|
|
23
|
+
/**
|
|
24
|
+
* Set default settings to apply to newly registered forms.
|
|
25
|
+
*/
|
|
26
|
+
setDefaults(options: Partial<FormConfiguration>): void;
|
|
27
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { Ref, ComputedRef, UnwrapNestedRefs, Component } from 'vue';
|
|
2
|
+
import { ReadonlyOr, PromiseOr } from '@myparcel-dev/ts-utils';
|
|
3
|
+
import { HookManagerInstance, HookUnregisterHandler } from '../hooks/HookManager';
|
|
4
|
+
import { FormHook } from '../data/hooks';
|
|
5
|
+
import { AnyAttributes, FunctionOr } from './utils.types';
|
|
6
|
+
import { FieldConfiguration, FieldInstance } from './field.types';
|
|
7
|
+
import { ComponentOrHtmlElement, ComponentProps } from './component.types';
|
|
8
|
+
import { ToRecord } from './common.types';
|
|
9
|
+
|
|
10
|
+
export type FormValues = Record<string | symbol, any>;
|
|
11
|
+
/**
|
|
12
|
+
* The input configuration for a Form.
|
|
13
|
+
*/
|
|
14
|
+
export interface FormConfiguration<Values extends FormValues = FormValues> extends FormHooks<Values> {
|
|
15
|
+
/**
|
|
16
|
+
* Global configuration for all fields.
|
|
17
|
+
*/
|
|
18
|
+
field?: {
|
|
19
|
+
wrapper?: ComponentOrHtmlElement;
|
|
20
|
+
/**
|
|
21
|
+
* Whether to use the element as a prop on custom elements. Defaults to true. If set to false, your component
|
|
22
|
+
* boilerplate can be more concise and omit the "element" prop without getting it as an extraneous attribute in
|
|
23
|
+
* your html. You can still access the element via injection using useElement().
|
|
24
|
+
*
|
|
25
|
+
* When the value is 'spread', the element will be spread the FieldInstanceProps from the element to the component.
|
|
26
|
+
*
|
|
27
|
+
* @see useElement
|
|
28
|
+
* @see FieldInstanceProps
|
|
29
|
+
*/
|
|
30
|
+
elementProp?: boolean | 'spread';
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Default configuration for all fields.
|
|
34
|
+
*/
|
|
35
|
+
fieldDefaults?: Partial<Omit<FieldConfiguration, 'ref'>>;
|
|
36
|
+
/**
|
|
37
|
+
* Configuration for the form element.
|
|
38
|
+
*/
|
|
39
|
+
form?: {
|
|
40
|
+
/**
|
|
41
|
+
* Attributes to apply to the outer form element.
|
|
42
|
+
*/
|
|
43
|
+
attributes?: AnyAttributes;
|
|
44
|
+
/**
|
|
45
|
+
* Tag to use for the form element. Defaults to 'form'.
|
|
46
|
+
*/
|
|
47
|
+
tag?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Component or html element wrapping all form elements. Defaults to false.
|
|
50
|
+
*/
|
|
51
|
+
wrapper?: ComponentOrHtmlElement;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Names of hooks to register.
|
|
55
|
+
*/
|
|
56
|
+
hookNames?: ReadonlyOr<string[]>;
|
|
57
|
+
/**
|
|
58
|
+
* Values to initialize the form with.
|
|
59
|
+
*/
|
|
60
|
+
initialValues?: Partial<Values>;
|
|
61
|
+
/**
|
|
62
|
+
* Function executed when any label is rendered.
|
|
63
|
+
*/
|
|
64
|
+
renderLabel?: (input: string) => string;
|
|
65
|
+
/**
|
|
66
|
+
* Messages that are used for built-in validations.
|
|
67
|
+
*/
|
|
68
|
+
validationMessages?: Record<'required' | string, FunctionOr<string>>;
|
|
69
|
+
}
|
|
70
|
+
export interface FormHooks<Values extends FormValues = FormValues> {
|
|
71
|
+
beforeSubmit?(form: FormInstance<Values>): PromiseOr<void>;
|
|
72
|
+
afterSubmit?(form: FormInstance<Values>): PromiseOr<void>;
|
|
73
|
+
beforeReset?(form: FormInstance<Values>): PromiseOr<void>;
|
|
74
|
+
afterReset?(form: FormInstance<Values>): PromiseOr<void>;
|
|
75
|
+
beforeValidate?(form: FormInstance<Values>): PromiseOr<void>;
|
|
76
|
+
afterValidate?(form: FormInstance<Values>): PromiseOr<void>;
|
|
77
|
+
beforeAddElement?<T extends keyof Values, Props extends ComponentProps = ComponentProps>(form: FormInstance<Values>, field: FieldInstance<Values[T], Props>): PromiseOr<void>;
|
|
78
|
+
afterAddElement?<T extends keyof Values, Props extends ComponentProps = ComponentProps>(form: FormInstance<Values>, field: FieldInstance<Values[T], Props>): PromiseOr<void>;
|
|
79
|
+
elementChange?<T extends keyof Values, Props extends ComponentProps = ComponentProps>(form: FormInstance<Values>, field: FieldInstance<Values[T], Props>, value: Values[T]): PromiseOr<void>;
|
|
80
|
+
}
|
|
81
|
+
export interface BaseFormInstance<Values extends FormValues = FormValues> {
|
|
82
|
+
/**
|
|
83
|
+
* Form configuration.
|
|
84
|
+
*/
|
|
85
|
+
readonly config: Omit<InstanceFormConfiguration<Values>, 'fields'>;
|
|
86
|
+
/**
|
|
87
|
+
* The outer HTML element.
|
|
88
|
+
*/
|
|
89
|
+
element: HTMLElement;
|
|
90
|
+
/**
|
|
91
|
+
* All fields in the form.
|
|
92
|
+
*/
|
|
93
|
+
readonly fields: Ref<FieldInstance[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Hooks that are registered for this form.
|
|
96
|
+
*/
|
|
97
|
+
readonly hooks: HookManagerInstance<ToRecord<FormHooks>>;
|
|
98
|
+
/**
|
|
99
|
+
* Exposes whether the form is dirty.
|
|
100
|
+
*/
|
|
101
|
+
readonly isDirty: ComputedRef<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* Determines whether the form is valid.
|
|
104
|
+
*/
|
|
105
|
+
readonly isValid: Ref<boolean>;
|
|
106
|
+
/**
|
|
107
|
+
* An object containing all named fields in the form as {name: field} pairs.
|
|
108
|
+
*/
|
|
109
|
+
readonly model: FieldsToModel<Values>;
|
|
110
|
+
/**
|
|
111
|
+
* The name of the form.
|
|
112
|
+
*/
|
|
113
|
+
readonly name: string;
|
|
114
|
+
/**
|
|
115
|
+
* Computed values from all non-disabled fields.
|
|
116
|
+
*/
|
|
117
|
+
readonly values: UnwrapNestedRefs<Values>;
|
|
118
|
+
/**
|
|
119
|
+
* Add a new element to the form.
|
|
120
|
+
*
|
|
121
|
+
* @internal
|
|
122
|
+
*/
|
|
123
|
+
addElement<Type = unknown, Props extends ComponentProps = ComponentProps>(element: FieldConfiguration<Type, Props>): Promise<FieldInstance<Type, Props>>;
|
|
124
|
+
/**
|
|
125
|
+
* Get a field by name.
|
|
126
|
+
*/
|
|
127
|
+
getField<F extends FieldInstance | null = FieldInstance | null>(name: string): F;
|
|
128
|
+
/**
|
|
129
|
+
* Get the value of a field by name.
|
|
130
|
+
* @deprecated use computed values
|
|
131
|
+
*/
|
|
132
|
+
getValue<T = unknown, K extends keyof Values | string = keyof Values>(fieldName: K): K extends keyof Values ? Values[K] : T;
|
|
133
|
+
/**
|
|
134
|
+
* Get values from all non-disabled fields.
|
|
135
|
+
* @deprecated use computed values
|
|
136
|
+
*/
|
|
137
|
+
getValues<T extends FormValues = Values>(): T;
|
|
138
|
+
/**
|
|
139
|
+
* Remove one or more event listeners from the form.
|
|
140
|
+
*/
|
|
141
|
+
off(event: FormHook, callback?: (form: FormInstance<Values>) => void): void;
|
|
142
|
+
/**
|
|
143
|
+
* Add an event listener to the form.
|
|
144
|
+
*/
|
|
145
|
+
on(event: FormHook, callback: (form: FormInstance<Values>) => void): HookUnregisterHandler;
|
|
146
|
+
/**
|
|
147
|
+
* Remove an element from the form by name.
|
|
148
|
+
*
|
|
149
|
+
* @internal
|
|
150
|
+
*/
|
|
151
|
+
removeElement(name: string): void;
|
|
152
|
+
/**
|
|
153
|
+
* Reset all fields to their original state.
|
|
154
|
+
*/
|
|
155
|
+
reset(): PromiseOr<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Destroy the form.
|
|
158
|
+
*/
|
|
159
|
+
destroy(): void;
|
|
160
|
+
/**
|
|
161
|
+
* Set the value of a field by name.
|
|
162
|
+
*/
|
|
163
|
+
setValue<T = unknown, K extends keyof Values | string = keyof Values>(fieldName: K, value: K extends keyof Values ? Values[K] : T): void;
|
|
164
|
+
/**
|
|
165
|
+
* Set values for multiple fields at once.
|
|
166
|
+
*/
|
|
167
|
+
setValues<T extends FormValues = Values>(values: T): void;
|
|
168
|
+
/**
|
|
169
|
+
* Submit the form.
|
|
170
|
+
*/
|
|
171
|
+
submit(): PromiseOr<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Validate all fields in the form.
|
|
174
|
+
*/
|
|
175
|
+
validate(): PromiseOr<boolean>;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Initialized form configuration always contains the following properties.
|
|
179
|
+
*/
|
|
180
|
+
export interface InstanceFormConfiguration<V extends FormValues = FormValues> extends FormConfiguration<V> {
|
|
181
|
+
field: {
|
|
182
|
+
elementProp: boolean | 'spread';
|
|
183
|
+
wrapper?: ComponentOrHtmlElement;
|
|
184
|
+
};
|
|
185
|
+
fieldDefaults: Partial<FieldConfiguration> & {
|
|
186
|
+
attributes: AnyAttributes;
|
|
187
|
+
wrapper: boolean;
|
|
188
|
+
};
|
|
189
|
+
form: {
|
|
190
|
+
attributes: AnyAttributes;
|
|
191
|
+
tag: string;
|
|
192
|
+
wrapper?: ComponentOrHtmlElement;
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
export type FormInstance<Values extends FormValues = FormValues> = BaseFormInstance<Values>;
|
|
196
|
+
export type FieldsToModel<Values extends FormValues> = {
|
|
197
|
+
[K in keyof Values]: FieldInstance<ComponentProps, Values[K]>;
|
|
198
|
+
};
|
|
199
|
+
export interface CreatedForm<Values extends FormValues = FormValues> {
|
|
200
|
+
Component: Component;
|
|
201
|
+
instance: FormInstance<Values>;
|
|
202
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReadonlyOr } from '@myparcel-dev/ts-utils';
|
|
2
|
+
|
|
3
|
+
export type HookCallback = (...args: any[]) => any;
|
|
4
|
+
export type HookManagerConfiguration<HN extends string = string> = {
|
|
5
|
+
hookNames?: ReadonlyOr<HN[]>;
|
|
6
|
+
} & Record<HN, unknown>;
|
|
7
|
+
export type CustomHookItem<HN extends string = string> = {
|
|
8
|
+
name: HN;
|
|
9
|
+
callback: HookCallback;
|
|
10
|
+
};
|
|
11
|
+
export type ResolveHook<HN extends string> = string | `before${Capitalize<HN>}` | `after${Capitalize<HN>}` | HN;
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'vue';
|
|
2
|
+
|
|
3
|
+
export interface SelectOption<Type = string> {
|
|
4
|
+
label: string;
|
|
5
|
+
value: Type;
|
|
6
|
+
}
|
|
7
|
+
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
8
|
+
export type UnionToOverloads<U> = UnionToIntersection<U extends any ? (f: U) => void : never>;
|
|
9
|
+
export type PopUnion<U> = UnionToOverloads<U> extends (a: infer A) => void ? A : never;
|
|
10
|
+
export type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
|
|
11
|
+
export type UnionToArray<T, A extends unknown[] = []> = IsUnion<T> extends true ? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]> : [T, ...A];
|
|
12
|
+
export type FunctionOr<T> = (() => T) | T;
|
|
13
|
+
export type AnyAttributes = HTMLAttributes & Record<string, unknown>;
|
|
14
|
+
export type StringKey<T> = Extract<keyof T, string>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
import { PromiseOr } from '@myparcel-dev/ts-utils';
|
|
3
|
+
import { FunctionOr } from './utils.types';
|
|
4
|
+
import { FieldInstance } from './field.types';
|
|
5
|
+
import { ComponentProps } from './component.types';
|
|
6
|
+
|
|
7
|
+
export type ValidateFunction<Type = unknown, Props extends ComponentProps = ComponentProps> = (field: FieldInstance<Type, Props>, value: Type) => PromiseOr<boolean>;
|
|
8
|
+
export interface WithComputedValidator {
|
|
9
|
+
isValid: ComputedRef<boolean>;
|
|
10
|
+
}
|
|
11
|
+
export interface WithMultiValidator<Type = unknown, Props extends ComponentProps = ComponentProps> {
|
|
12
|
+
validators: Validator<Type, Props>[];
|
|
13
|
+
}
|
|
14
|
+
export interface Validator<Type = unknown, Props extends ComponentProps = ComponentProps> {
|
|
15
|
+
validate: ValidateFunction<Type, Props>;
|
|
16
|
+
errorMessage?: FunctionOr<string>;
|
|
17
|
+
precedence?: number;
|
|
18
|
+
}
|
|
19
|
+
export type ValidatorWithPrecedence<Type = unknown, Props extends ComponentProps = ComponentProps> = Validator<Type, Props> & {
|
|
20
|
+
precedence: number;
|
|
21
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FieldConfiguration } from '../types/field.types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Define a field for use in a form with fields array.
|
|
5
|
+
*
|
|
6
|
+
* @example defineField({name: 'name', component: 'input', props: {type: 'text'}})
|
|
7
|
+
*/
|
|
8
|
+
export declare const defineField: <Type = unknown, Props extends unknown = any, FC extends FieldConfiguration<Type, Props> = FieldConfiguration<Type, Props>>(field: FC) => FC;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FormInstance } from '../types/form.types';
|
|
2
|
+
import { FieldConfiguration } from '../types/field.types';
|
|
3
|
+
import { ComponentProps } from '../types/component.types';
|
|
4
|
+
|
|
5
|
+
type PropsWithDefault = 'visible' | 'wrapper' | 'optional' | 'lazy' | 'disabled' | 'readOnly';
|
|
6
|
+
export type MakeRequired<Type, Keys extends keyof Type> = Omit<Type, Keys> & Required<Pick<Type, Keys>>;
|
|
7
|
+
export type NormalizedFieldConfiguration<Type, Props extends ComponentProps> = MakeRequired<FieldConfiguration<Type, Props>, PropsWithDefault>;
|
|
8
|
+
/**
|
|
9
|
+
* Normalize an input field configuration with default values, optionally from a form configuration.
|
|
10
|
+
*/
|
|
11
|
+
export declare const normalizeFieldConfiguration: <Type = unknown, Props extends unknown = any>(input: FieldConfiguration<Type, Props>, form?: FormInstance) => NormalizedFieldConfiguration<Type, Props>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { FormConfiguration, FormValues, InstanceFormConfiguration } from '../types/form.types';
|
|
2
|
+
|
|
3
|
+
export declare const normalizeFormConfiguration: <V extends FormValues, FC extends Partial<FormConfiguration<V>>>(defaults: InstanceFormConfiguration<V>, config: FC) => InstanceFormConfiguration<V>;
|