@ngx-formbar/core 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +42 -0
- package/fesm2022/ngx-formbar-core.mjs +2429 -0
- package/fesm2022/ngx-formbar-core.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/components/form/ngxfb-form.component.d.ts +28 -0
- package/lib/composables/computed-value.d.ts +8 -0
- package/lib/composables/disabled.state.d.ts +36 -0
- package/lib/composables/dynamic-label.d.ts +9 -0
- package/lib/composables/dynamic-title.d.ts +9 -0
- package/lib/composables/hidden.state.d.ts +68 -0
- package/lib/composables/readonly.state.d.ts +19 -0
- package/lib/composables/testId.d.ts +16 -0
- package/lib/composables/update-strategy.d.ts +20 -0
- package/lib/composables/validators.d.ts +22 -0
- package/lib/config/config.d.ts +7 -0
- package/lib/config/provide-formbar.d.ts +38 -0
- package/lib/directives/ngxfb-abstract-control.directive.d.ts +53 -0
- package/lib/directives/ngxfb-block.directive.d.ts +124 -0
- package/lib/directives/ngxfb-control.directive.d.ts +203 -0
- package/lib/directives/ngxfb-group.directive.d.ts +253 -0
- package/lib/helper/control-container-view-providers.d.ts +33 -0
- package/lib/index.d.ts +23 -0
- package/lib/services/component-registration.service.d.ts +8 -0
- package/lib/services/configuration.service.d.ts +8 -0
- package/lib/services/expression.service.d.ts +148 -0
- package/lib/services/form.service.d.ts +10 -0
- package/lib/services/validator-registration.service.d.ts +10 -0
- package/lib/tokens/component-registrations.d.ts +2 -0
- package/lib/tokens/component-resolver.d.ts +3 -0
- package/lib/tokens/default-update-strategy.d.ts +3 -0
- package/lib/tokens/global-config.d.ts +5 -0
- package/lib/tokens/validator-registrations.d.ts +8 -0
- package/lib/tokens/validator-resolver.d.ts +3 -0
- package/lib/types/component-resolver.type.d.ts +4 -0
- package/lib/types/content.type.d.ts +137 -0
- package/lib/types/expression.type.d.ts +2 -0
- package/lib/types/form.type.d.ts +4 -0
- package/lib/types/functions.type.d.ts +4 -0
- package/lib/types/global-configuration.type.d.ts +4 -0
- package/lib/types/provide.type.d.ts +42 -0
- package/lib/types/registration.type.d.ts +18 -0
- package/lib/types/validation.type.d.ts +59 -0
- package/lib/types/validator-resolver.type.d.ts +6 -0
- package/package.json +52 -0
- package/public-api.d.ts +1 -0
- package/schematics/block/files/__componentName@dasherize__.component.html.template +1 -0
- package/schematics/block/files/__componentName@dasherize__.component.ts.template +29 -0
- package/schematics/block/files/__interfaceName@dasherize__.type.ts.template +6 -0
- package/schematics/block/index.d.ts +3 -0
- package/schematics/block/index.js +11 -0
- package/schematics/block/index.js.map +1 -0
- package/schematics/block/schema.json +62 -0
- package/schematics/collection.json +31 -0
- package/schematics/control/files/__componentName@dasherize__.component.html.template +0 -0
- package/schematics/control/files/__componentName@dasherize__.component.ts.template +29 -0
- package/schematics/control/files/__interfaceName@dasherize__.type.ts.template +6 -0
- package/schematics/control/index.d.ts +3 -0
- package/schematics/control/index.js +11 -0
- package/schematics/control/index.js.map +1 -0
- package/schematics/control/schema.json +61 -0
- package/schematics/group/files/__componentName@dasherize__.component.html.template +5 -0
- package/schematics/group/files/__componentName@dasherize__.component.ts.template +29 -0
- package/schematics/group/files/__interfaceName@dasherize__.type.ts.template +5 -0
- package/schematics/group/index.d.ts +3 -0
- package/schematics/group/index.js +11 -0
- package/schematics/group/index.js.map +1 -0
- package/schematics/group/schema.json +62 -0
- package/schematics/ng-add/files/config-registrations/async-validator-registrations.ts.template +4 -0
- package/schematics/ng-add/files/config-registrations/component-registrations.ts.template +4 -0
- package/schematics/ng-add/files/config-registrations/index.ts.template +3 -0
- package/schematics/ng-add/files/config-registrations/validator-registrations.ts.template +4 -0
- package/schematics/ng-add/files/helper/block.host-directive.ts.template +6 -0
- package/schematics/ng-add/files/helper/control.host-directive.ts.template +6 -0
- package/schematics/ng-add/files/helper/group.host-directive.ts.template +6 -0
- package/schematics/ng-add/files/helper/index.ts.template +4 -0
- package/schematics/ng-add/files/helper/view-provider.ts.template +9 -0
- package/schematics/ng-add/files/provider-config/config/__providerConfigFileName__.ts.template +9 -0
- package/schematics/ng-add/files/provider-config/inline/__providerConfigFileName__.ts.template +8 -0
- package/schematics/ng-add/files/provider-config/token/__providerConfigFileName__.ts.template +4 -0
- package/schematics/ng-add/files/schematics-config/__schematicConfigFileName__.json.template +1 -0
- package/schematics/ng-add/files/token-registrations/async-validator-registrations.ts.template +8 -0
- package/schematics/ng-add/files/token-registrations/component-registrations.ts.template +8 -0
- package/schematics/ng-add/files/token-registrations/index.ts.template +3 -0
- package/schematics/ng-add/files/token-registrations/validator-registrations.ts.template +8 -0
- package/schematics/ng-add/helper.d.ts +11 -0
- package/schematics/ng-add/helper.js +198 -0
- package/schematics/ng-add/helper.js.map +1 -0
- package/schematics/ng-add/index.d.ts +3 -0
- package/schematics/ng-add/index.js +68 -0
- package/schematics/ng-add/index.js.map +1 -0
- package/schematics/ng-add/rules/create-config-registration-files.rule.d.ts +3 -0
- package/schematics/ng-add/rules/create-config-registration-files.rule.js +32 -0
- package/schematics/ng-add/rules/create-config-registration-files.rule.js.map +1 -0
- package/schematics/ng-add/rules/create-formbar-registration-config.rule.d.ts +3 -0
- package/schematics/ng-add/rules/create-formbar-registration-config.rule.js +30 -0
- package/schematics/ng-add/rules/create-formbar-registration-config.rule.js.map +1 -0
- package/schematics/ng-add/rules/create-helper-files.rule.d.ts +6 -0
- package/schematics/ng-add/rules/create-helper-files.rule.js +22 -0
- package/schematics/ng-add/rules/create-helper-files.rule.js.map +1 -0
- package/schematics/ng-add/rules/create-schematics-config.rule.d.ts +3 -0
- package/schematics/ng-add/rules/create-schematics-config.rule.js +42 -0
- package/schematics/ng-add/rules/create-schematics-config.rule.js.map +1 -0
- package/schematics/ng-add/rules/create-token-registration-files.rule.d.ts +3 -0
- package/schematics/ng-add/rules/create-token-registration-files.rule.js +32 -0
- package/schematics/ng-add/rules/create-token-registration-files.rule.js.map +1 -0
- package/schematics/ng-add/rules/include-templates.rule.d.ts +3 -0
- package/schematics/ng-add/rules/include-templates.rule.js +11 -0
- package/schematics/ng-add/rules/include-templates.rule.js.map +1 -0
- package/schematics/ng-add/rules/install-dependencies.rule.d.ts +2 -0
- package/schematics/ng-add/rules/install-dependencies.rule.js +12 -0
- package/schematics/ng-add/rules/install-dependencies.rule.js.map +1 -0
- package/schematics/ng-add/rules/update-app-config.rule.d.ts +3 -0
- package/schematics/ng-add/rules/update-app-config.rule.js +48 -0
- package/schematics/ng-add/rules/update-app-config.rule.js.map +1 -0
- package/schematics/ng-add/rules/update-schematics-config.rule.d.ts +6 -0
- package/schematics/ng-add/rules/update-schematics-config.rule.js +28 -0
- package/schematics/ng-add/rules/update-schematics-config.rule.js.map +1 -0
- package/schematics/ng-add/schema.d.ts +23 -0
- package/schematics/ng-add/schema.js +3 -0
- package/schematics/ng-add/schema.js.map +1 -0
- package/schematics/ng-add/schema.json +81 -0
- package/schematics/register/component-info.type.d.ts +11 -0
- package/schematics/register/component-info.type.js +3 -0
- package/schematics/register/component-info.type.js.map +1 -0
- package/schematics/register/discover-components.d.ts +19 -0
- package/schematics/register/discover-components.js +267 -0
- package/schematics/register/discover-components.js.map +1 -0
- package/schematics/register/index.d.ts +3 -0
- package/schematics/register/index.js +49 -0
- package/schematics/register/index.js.map +1 -0
- package/schematics/register/register-components.d.ts +3 -0
- package/schematics/register/register-components.js +38 -0
- package/schematics/register/register-components.js.map +1 -0
- package/schematics/register/schema.d.ts +14 -0
- package/schematics/register/schema.js +3 -0
- package/schematics/register/schema.js.map +1 -0
- package/schematics/register/schema.json +44 -0
- package/schematics/shared/ast/decorators.d.ts +9 -0
- package/schematics/shared/ast/decorators.js +182 -0
- package/schematics/shared/ast/decorators.js.map +1 -0
- package/schematics/shared/ast/imports.d.ts +3 -0
- package/schematics/shared/ast/imports.js +93 -0
- package/schematics/shared/ast/imports.js.map +1 -0
- package/schematics/shared/ast/parse.d.ts +3 -0
- package/schematics/shared/ast/parse.js +17 -0
- package/schematics/shared/ast/parse.js.map +1 -0
- package/schematics/shared/ast/registrations.d.ts +22 -0
- package/schematics/shared/ast/registrations.js +654 -0
- package/schematics/shared/ast/registrations.js.map +1 -0
- package/schematics/shared/ast/types.d.ts +3 -0
- package/schematics/shared/ast/types.js +58 -0
- package/schematics/shared/ast/types.js.map +1 -0
- package/schematics/shared/file.d.ts +4 -0
- package/schematics/shared/file.js +60 -0
- package/schematics/shared/file.js.map +1 -0
- package/schematics/shared/helper.d.ts +2 -0
- package/schematics/shared/helper.js +29 -0
- package/schematics/shared/helper.js.map +1 -0
- package/schematics/shared/rules/create-component.rule.d.ts +3 -0
- package/schematics/shared/rules/create-component.rule.js +15 -0
- package/schematics/shared/rules/create-component.rule.js.map +1 -0
- package/schematics/shared/rules/register-control.rule.d.ts +3 -0
- package/schematics/shared/rules/register-control.rule.js +30 -0
- package/schematics/shared/rules/register-control.rule.js.map +1 -0
- package/schematics/shared/rules/register-type-map.rule.d.ts +3 -0
- package/schematics/shared/rules/register-type-map.rule.js +46 -0
- package/schematics/shared/rules/register-type-map.rule.js.map +1 -0
- package/schematics/shared/rules/register-type-token.rule.d.ts +3 -0
- package/schematics/shared/rules/register-type-token.rule.js +49 -0
- package/schematics/shared/rules/register-type-token.rule.js.map +1 -0
- package/schematics/shared/rules/scaffold-and-register.rule.d.ts +3 -0
- package/schematics/shared/rules/scaffold-and-register.rule.js +134 -0
- package/schematics/shared/rules/scaffold-and-register.rule.js.map +1 -0
- package/schematics/shared/schema.d.ts +32 -0
- package/schematics/shared/schema.js +3 -0
- package/schematics/shared/schema.js.map +1 -0
- package/schematics/tests/generators.spec.d.ts +1 -0
- package/schematics/tests/generators.spec.js +450 -0
- package/schematics/tests/generators.spec.js.map +1 -0
- package/schematics/tests/helper.d.ts +20 -0
- package/schematics/tests/helper.js +275 -0
- package/schematics/tests/helper.js.map +1 -0
- package/schematics/tests/ng-add.spec.d.ts +1 -0
- package/schematics/tests/ng-add.spec.js +380 -0
- package/schematics/tests/ng-add.spec.js.map +1 -0
- package/schematics/tests/register.spec.d.ts +1 -0
- package/schematics/tests/register.spec.js +340 -0
- package/schematics/tests/register.spec.js.map +1 -0
- package/schematics/tests/workspace-setup.d.ts +21 -0
- package/schematics/tests/workspace-setup.js +255 -0
- package/schematics/tests/workspace-setup.js.map +1 -0
- package/shared/ast.d.ts +10 -0
- package/shared/ast.js +93 -0
- package/shared/ast.js.map +1 -0
- package/shared/constants.d.ts +16 -0
- package/shared/constants.js +20 -0
- package/shared/constants.js.map +1 -0
- package/shared/shared-config.type.d.ts +20 -0
- package/shared/shared-config.type.js +3 -0
- package/shared/shared-config.type.js.map +1 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Expression } from './expression.type';
|
|
2
|
+
/**
|
|
3
|
+
* The foundation for all form controls and groups. It defines a common set of options
|
|
4
|
+
* that control registration, validation, visibility, and behavior of the form elements.
|
|
5
|
+
*/
|
|
6
|
+
export interface NgxFbBaseContent {
|
|
7
|
+
/**
|
|
8
|
+
* Specifies the kind of form control. Determines what control is used and what
|
|
9
|
+
* additional properties are available.
|
|
10
|
+
*/
|
|
11
|
+
type: string;
|
|
12
|
+
/**
|
|
13
|
+
* A string expression that determines when the control should be hidden.
|
|
14
|
+
* This condition is evaluated at runtime against the whole form object.
|
|
15
|
+
*/
|
|
16
|
+
hidden?: Expression<boolean>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extends the base content with validation and control state management properties.
|
|
20
|
+
* Used as a base for both form controls and groups.
|
|
21
|
+
*/
|
|
22
|
+
export interface NgxFbAbstractControl extends NgxFbBaseContent {
|
|
23
|
+
/**
|
|
24
|
+
* Array of strings representing names of synchronous validators that apply to the control.
|
|
25
|
+
* These can be registered globally with a validator registration object.
|
|
26
|
+
*/
|
|
27
|
+
validators?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Similar to validators, but for asynchronous validation logic that may involve
|
|
30
|
+
* API calls or other deferred operations.
|
|
31
|
+
*/
|
|
32
|
+
asyncValidators?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Defines whether the control should be disabled. Can be a boolean value or a
|
|
35
|
+
* string expression that evaluates against the form object.
|
|
36
|
+
*/
|
|
37
|
+
disabled?: Expression<boolean> | boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Specifies how to handle the control when hidden: 'keep' (remains in form model)
|
|
40
|
+
* or 'remove' (removed from form model).
|
|
41
|
+
*/
|
|
42
|
+
hideStrategy?: HideStrategy;
|
|
43
|
+
/**
|
|
44
|
+
* Determines how the control's value is handled when visibility changes:
|
|
45
|
+
* 'last' (preserves last value), 'default' (reverts to default value),
|
|
46
|
+
* or 'reset' (clears value).
|
|
47
|
+
*/
|
|
48
|
+
valueStrategy?: ValueStrategy;
|
|
49
|
+
/**
|
|
50
|
+
* Indicates if the control is read-only (displayed but not modifiable).
|
|
51
|
+
* Accepts either a boolean value or a string expression for dynamic evaluation.
|
|
52
|
+
*/
|
|
53
|
+
readonly?: Expression<boolean> | boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Specifies when to update the control's value: 'change' (as user types, default),
|
|
56
|
+
* 'blur' (when control loses focus), or 'submit' (when form is submitted).
|
|
57
|
+
*/
|
|
58
|
+
updateOn?: UpdateStrategy;
|
|
59
|
+
/**
|
|
60
|
+
* A value that is automatically derived and set for the control.
|
|
61
|
+
* It will overwrite user input if one of its dependencies changes.
|
|
62
|
+
*/
|
|
63
|
+
computedValue?: Expression<unknown>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Specifies when to update the control's value:
|
|
67
|
+
* - 'change': as user types (default)
|
|
68
|
+
* - 'blur': when control loses focus
|
|
69
|
+
* - 'submit': when form is submitted
|
|
70
|
+
*/
|
|
71
|
+
export type UpdateStrategy = 'change' | 'blur' | 'submit' | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* Represents a group of controls that can be nested within a form.
|
|
74
|
+
*/
|
|
75
|
+
export interface NgxFbFormGroup<T extends NgxFbBaseContent = NgxFbContent> extends NgxFbAbstractControl {
|
|
76
|
+
/**
|
|
77
|
+
* Specifies a title for the group
|
|
78
|
+
*/
|
|
79
|
+
title?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Dynamic title that can be evaluated from form data
|
|
82
|
+
*/
|
|
83
|
+
dynamicTitle?: Expression<string>;
|
|
84
|
+
/**
|
|
85
|
+
* Object mapping keys to NgxFbContent that configure the controls of the group
|
|
86
|
+
*/
|
|
87
|
+
controls: Record<string, T>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Represents an individual form control with label and value properties.
|
|
91
|
+
*/
|
|
92
|
+
export interface NgxFbControl extends NgxFbAbstractControl {
|
|
93
|
+
/**
|
|
94
|
+
* Specifies the label for the control
|
|
95
|
+
*/
|
|
96
|
+
label?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Dynamic label that can be evaluated from form data
|
|
99
|
+
*/
|
|
100
|
+
dynamicLabel?: Expression<string>;
|
|
101
|
+
/**
|
|
102
|
+
* Default value for the control. Should be overwritten with the proper value type of the control.
|
|
103
|
+
*/
|
|
104
|
+
defaultValue?: unknown;
|
|
105
|
+
/**
|
|
106
|
+
* Whether this control can have a null value. Used to set the same property through the reactive forms API.
|
|
107
|
+
*/
|
|
108
|
+
nonNullable?: boolean;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Represents a block element that doesn't behave like a form control.
|
|
112
|
+
* Used for UI elements that aren't part of the form model.
|
|
113
|
+
*/
|
|
114
|
+
export interface NgxFbBlock extends NgxFbBaseContent {
|
|
115
|
+
/**
|
|
116
|
+
* Required property for TypeScript to properly do type narrowing
|
|
117
|
+
*/
|
|
118
|
+
isControl: false;
|
|
119
|
+
[key: string]: unknown;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Union type representing all possible content types that can be used in a form.
|
|
123
|
+
*/
|
|
124
|
+
export type NgxFbContent = NgxFbFormGroup | NgxFbControl | NgxFbBlock;
|
|
125
|
+
/**
|
|
126
|
+
* Specifies how to handle the control when hidden:
|
|
127
|
+
* - 'keep': control remains in form model
|
|
128
|
+
* - 'remove': control is removed from form model
|
|
129
|
+
*/
|
|
130
|
+
export type HideStrategy = 'keep' | 'remove';
|
|
131
|
+
/**
|
|
132
|
+
* Determines how the control's value is handled when visibility changes:
|
|
133
|
+
* - 'last': preserves last value
|
|
134
|
+
* - 'default': reverts to default value
|
|
135
|
+
* - 'reset': clears value
|
|
136
|
+
*/
|
|
137
|
+
export type ValueStrategy = 'last' | 'default' | 'reset';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { NgxFbBaseContent, ValueStrategy } from './content.type';
|
|
2
|
+
export type SimpleFunction = () => void;
|
|
3
|
+
export type ValueHandleFunction = (valueStrategy?: ValueStrategy) => void;
|
|
4
|
+
export type TestIdBuilderFn = (content: NgxFbBaseContent, name: string, parentTestId?: string) => string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ComponentRegistrationConfig } from './registration.type';
|
|
2
|
+
import { AsyncValidatorConfig, RegistrationRecord, ValidatorConfig } from './validation.type';
|
|
3
|
+
import { UpdateStrategy } from './content.type';
|
|
4
|
+
import { NgxFbGlobalConfiguration } from './global-configuration.type';
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for registering and providing components and validators in Ngx Formbar
|
|
7
|
+
*
|
|
8
|
+
* @template S - Type extending RegistrationRecord for synchronous validators
|
|
9
|
+
* @template A - Type extending RegistrationRecord for asynchronous validators
|
|
10
|
+
*
|
|
11
|
+
* @property componentRegistrations - Optional mapping of control types to component implementations
|
|
12
|
+
* @property validatorRegistrations - Optional configuration for synchronous validators
|
|
13
|
+
* @property asyncValidatorRegistrations - Optional configuration for asynchronous validators
|
|
14
|
+
* @property updateOn - (Optional) Specifies when to update the control's value
|
|
15
|
+
* @property globalConfig - (Optional) Configuration that is used for all controls
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Define custom form components and validators
|
|
19
|
+
* const formbarConfig: FormbarConfig<SyncValidators, AsyncValidators> = {
|
|
20
|
+
* componentRegistrations:
|
|
21
|
+
* {
|
|
22
|
+
* 'text-input': TextInputComponent
|
|
23
|
+
* 'address-group': AddressGroupComponent
|
|
24
|
+
* },
|
|
25
|
+
* validatorRegistrations: {
|
|
26
|
+
* 'min-chars': [Validators.minLength(3)],
|
|
27
|
+
* letter: [letterValidator],
|
|
28
|
+
* combined: ['min-chars', Validators.required, 'letter'],
|
|
29
|
+
* }
|
|
30
|
+
* asyncValidatorRegistrations: {
|
|
31
|
+
* async: [asyncValidator],
|
|
32
|
+
* 'async-group': [asyncGroupValidator],
|
|
33
|
+
* },
|
|
34
|
+
* };
|
|
35
|
+
*/
|
|
36
|
+
export interface FormbarConfig<S extends RegistrationRecord, A extends RegistrationRecord> {
|
|
37
|
+
componentRegistrations?: ComponentRegistrationConfig;
|
|
38
|
+
validatorRegistrations?: ValidatorConfig<S>;
|
|
39
|
+
asyncValidatorRegistrations?: AsyncValidatorConfig<A>;
|
|
40
|
+
updateOn?: UpdateStrategy;
|
|
41
|
+
globalConfig?: NgxFbGlobalConfiguration;
|
|
42
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Type } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for registering component types
|
|
4
|
+
*
|
|
5
|
+
* Used to map string type identifiers to component implementations
|
|
6
|
+
* for dynamic rendering.
|
|
7
|
+
*/
|
|
8
|
+
export type ComponentRegistrationConfig = Record<string, Type<unknown>>;
|
|
9
|
+
/**
|
|
10
|
+
* Strategy for handling component states
|
|
11
|
+
*
|
|
12
|
+
* Determines how visibility, disabled, and other component states
|
|
13
|
+
* are managed.
|
|
14
|
+
*
|
|
15
|
+
* - 'auto': Formbar automatically manages the state
|
|
16
|
+
* - 'manual': The component/host manages the state itself
|
|
17
|
+
*/
|
|
18
|
+
export type StateHandling = 'auto' | 'manual';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { AsyncValidatorFn, ValidatorFn } from '@angular/forms';
|
|
2
|
+
/**
|
|
3
|
+
* Base record type for validator registrations
|
|
4
|
+
*
|
|
5
|
+
* Represents a key-value store where keys are validator identifiers
|
|
6
|
+
* and values are the validator implementations
|
|
7
|
+
*/
|
|
8
|
+
export type RegistrationRecord = Record<string, unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* Utility type that extracts string keys from a validator registration
|
|
11
|
+
*
|
|
12
|
+
* Used to ensure type safety when referencing validators by their string identifiers
|
|
13
|
+
*
|
|
14
|
+
* @template Registration - A record type containing registered validators
|
|
15
|
+
*/
|
|
16
|
+
export type ValidatorKey<Registration extends RegistrationRecord> = Extract<keyof Registration, string>;
|
|
17
|
+
/**
|
|
18
|
+
* Configuration for synchronous form validators
|
|
19
|
+
*
|
|
20
|
+
* Maps validator identifiers to arrays of validator definitions which can be:
|
|
21
|
+
* - Direct validator functions (ValidatorFn)
|
|
22
|
+
* - References to other validators by their string identifiers
|
|
23
|
+
*
|
|
24
|
+
* @template T - Record type containing registered validators
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Define validator configurations
|
|
28
|
+
* const validatorConfig: ValidatorConfig<MyValidators> = {
|
|
29
|
+
* required: [Validators.required],
|
|
30
|
+
* email: [Validators.email],
|
|
31
|
+
* password: [Validators.minLength(8), 'required'],
|
|
32
|
+
* // Reference other validators or combine them
|
|
33
|
+
* profile: ['required', 'email', customProfileValidator]
|
|
34
|
+
* };
|
|
35
|
+
*/
|
|
36
|
+
export type ValidatorConfig<T extends RegistrationRecord> = {
|
|
37
|
+
[K in keyof T]: (ValidatorFn | ValidatorKey<T>)[];
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Configuration for asynchronous form validators
|
|
41
|
+
*
|
|
42
|
+
* Maps validator identifiers to arrays of async validator definitions which can be:
|
|
43
|
+
* - Direct async validator functions (AsyncValidatorFn)
|
|
44
|
+
* - References to other validators by their string identifiers
|
|
45
|
+
*
|
|
46
|
+
* @template T - Record type containing registered validators
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Define async validator configurations
|
|
50
|
+
* const asyncValidatorConfig: AsyncValidatorConfig<MyAsyncValidators> = {
|
|
51
|
+
* uniqueEmail: [emailUniquenessValidator],
|
|
52
|
+
* serverCheck: [serverValidationFn],
|
|
53
|
+
* // Reference other validators or combine them
|
|
54
|
+
* complexCheck: ['uniqueEmail', customAsyncValidator]
|
|
55
|
+
* };
|
|
56
|
+
*/
|
|
57
|
+
export type AsyncValidatorConfig<T extends RegistrationRecord> = {
|
|
58
|
+
[K in keyof T]: (AsyncValidatorFn | ValidatorKey<T>)[];
|
|
59
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Signal } from '@angular/core';
|
|
2
|
+
import { AsyncValidatorFn, ValidatorFn } from '@angular/forms';
|
|
3
|
+
export interface ValidatorResolver {
|
|
4
|
+
registrations: Signal<ReadonlyMap<string, ValidatorFn[]>>;
|
|
5
|
+
asyncRegistrations: Signal<ReadonlyMap<string, AsyncValidatorFn[]>>;
|
|
6
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ngx-formbar/core",
|
|
3
|
+
"version": "0.11.0",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/cdk": "^19.0.0",
|
|
6
|
+
"@angular/common": "^19.0.0",
|
|
7
|
+
"@angular/core": "^19.0.0"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"acorn": "^8.14.1",
|
|
11
|
+
"eval-estree-expression": "^3.0.0",
|
|
12
|
+
"tslib": "^2.3.0"
|
|
13
|
+
},
|
|
14
|
+
"schematics": "./schematics/collection.json",
|
|
15
|
+
"ng-add": {
|
|
16
|
+
"save": true
|
|
17
|
+
},
|
|
18
|
+
"private": false,
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"keywords": [
|
|
25
|
+
"angular",
|
|
26
|
+
"typescript",
|
|
27
|
+
"reactive-forms",
|
|
28
|
+
"json-form"
|
|
29
|
+
],
|
|
30
|
+
"author": {
|
|
31
|
+
"name": "Alexander Pahn",
|
|
32
|
+
"email": "alexander.pahn@outlook.com"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/TheNordicOne/ngx-formbar.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/TheNordicOne/ngx-formbar/issues"
|
|
40
|
+
},
|
|
41
|
+
"module": "fesm2022/ngx-formbar-core.mjs",
|
|
42
|
+
"typings": "index.d.ts",
|
|
43
|
+
"exports": {
|
|
44
|
+
"./package.json": {
|
|
45
|
+
"default": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
".": {
|
|
48
|
+
"types": "./index.d.ts",
|
|
49
|
+
"default": "./fesm2022/ngx-formbar-core.mjs"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/public-api.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Component, Signal, inject } from '@angular/core';<% if (!hasViewProviderHelper) { %>
|
|
2
|
+
import { ControlContainer } from '@angular/forms';<% } %>
|
|
3
|
+
import { NgxfbBlockDirective } from '@ngx-formbar/core';
|
|
4
|
+
import { <%= classify(interfaceName) %> } from './<%= dasherize(interfaceName) %>.type';<% if (hasViewProviderHelper) { %>
|
|
5
|
+
import { <%= viewProviderIdentifier %> } from '<%= viewProviderHelperPath %>';<% } %><% if (hasHostDirectiveHelper) { %>
|
|
6
|
+
import { <%= hostDirectiveIdentifier %> } from '<%= hostDirectiveHelperPath %>';<% } %>
|
|
7
|
+
|
|
8
|
+
@Component({
|
|
9
|
+
selector: 'app-<%= dasherize(componentName) %>',
|
|
10
|
+
imports: [],
|
|
11
|
+
templateUrl: './<%= dasherize(componentName) %>.component.html',
|
|
12
|
+
viewProviders: <% if (hasViewProviderHelper) { %><%= viewProviderIdentifier %><% } else { %>[
|
|
13
|
+
{
|
|
14
|
+
provide: ControlContainer,
|
|
15
|
+
useFactory: () => inject(ControlContainer, { skipSelf: true }),
|
|
16
|
+
}
|
|
17
|
+
]<% } %>,
|
|
18
|
+
hostDirectives: <% if (hasHostDirectiveHelper) { %>[<%= hostDirectiveIdentifier %>]<% } else { %>[
|
|
19
|
+
{
|
|
20
|
+
directive: NgxfbBlockDirective,
|
|
21
|
+
inputs: ['content', 'name'],
|
|
22
|
+
}
|
|
23
|
+
]<% } %>,
|
|
24
|
+
})
|
|
25
|
+
export class <%= classify(componentClassName) %> {
|
|
26
|
+
private readonly block = inject(NgxfbBlockDirective<<%= classify(interfaceName) %>>);
|
|
27
|
+
readonly content: Signal<<%= classify(interfaceName) %>> = this.block.content;
|
|
28
|
+
}
|
|
29
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.block = block;
|
|
4
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const scaffold_and_register_rule_1 = require("../shared/rules/scaffold-and-register.rule");
|
|
6
|
+
function block(options) {
|
|
7
|
+
return () => {
|
|
8
|
+
return (0, schematics_1.chain)([(0, scaffold_and_register_rule_1.scaffoldAndRegister)(options, 'block')]);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/core/automation/schematics/block/index.ts"],"names":[],"mappings":";;AAIA,sBAIC;AARD,2DAAyD;AACzD,2FAAiF;AAGjF,SAAgB,KAAK,CAAC,OAAe;IACnC,OAAO,GAAG,EAAE;QACV,OAAO,IAAA,kBAAK,EAAC,CAAC,IAAA,gDAAmB,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "NgxFormbarBlock",
|
|
4
|
+
"title": "Scaffold Block",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"description": "The name of the component that this control will use. Defaults to the key if not provided.",
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"key": {
|
|
12
|
+
"description": "The name of the key that this control will be associated with.",
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"path": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"format": "path",
|
|
18
|
+
"description": "The path to create the component.",
|
|
19
|
+
"visible": false,
|
|
20
|
+
"$default": {
|
|
21
|
+
"$source": "workingDirectory"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"project": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "The name of the project.",
|
|
27
|
+
"$default": {
|
|
28
|
+
"$source": "projectName"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"interfaceSuffix": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "The suffix of the interface. Defaults to 'Control'",
|
|
34
|
+
"default": "Control"
|
|
35
|
+
},
|
|
36
|
+
"componentSuffix": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "The suffix of the component. Defaults to 'Control'",
|
|
39
|
+
"default": "Control"
|
|
40
|
+
},
|
|
41
|
+
"hostDirectiveHelperPath": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Path to the hostDirective helper"
|
|
44
|
+
},
|
|
45
|
+
"skipRegistration": {
|
|
46
|
+
"type": "boolean",
|
|
47
|
+
"description": "Skip automatic registration"
|
|
48
|
+
},
|
|
49
|
+
"viewProviderHelperPath": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "Path to the viewProvider helper"
|
|
52
|
+
},
|
|
53
|
+
"schematicsConfig": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"description": "Path of the configuration that is to be used by this schematic"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"required": [
|
|
59
|
+
"key"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
|
|
3
|
+
"schematics": {
|
|
4
|
+
"ng-add": {
|
|
5
|
+
"description": "Add ngx-formbar to the project.",
|
|
6
|
+
"factory": "./ng-add/index#ngAdd",
|
|
7
|
+
"schema": "./ng-add/schema.json",
|
|
8
|
+
"hidden": true
|
|
9
|
+
},
|
|
10
|
+
"control": {
|
|
11
|
+
"description": "Scaffolds a new control and registers it.",
|
|
12
|
+
"factory": "./control/index#control",
|
|
13
|
+
"schema": "./control/schema.json"
|
|
14
|
+
},
|
|
15
|
+
"group": {
|
|
16
|
+
"description": "Scaffolds a new group and registers it.",
|
|
17
|
+
"factory": "./group/index#group",
|
|
18
|
+
"schema": "./group/schema.json"
|
|
19
|
+
},
|
|
20
|
+
"block": {
|
|
21
|
+
"description": "Scaffolds a new block and registers it.",
|
|
22
|
+
"factory": "./block/index#block",
|
|
23
|
+
"schema": "./block/schema.json"
|
|
24
|
+
},
|
|
25
|
+
"register": {
|
|
26
|
+
"description": "Searches for all components and registers them",
|
|
27
|
+
"factory": "./register/index#register",
|
|
28
|
+
"schema": "./register/schema.json"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Component, Signal, inject } from '@angular/core';
|
|
2
|
+
import { ReactiveFormsModule<% if (!hasViewProviderHelper) { %>, ControlContainer<% } %> } from '@angular/forms';
|
|
3
|
+
import { NgxfbControlDirective } from '@ngx-formbar/core';
|
|
4
|
+
import { <%= interfaceName %> } from './<%= dasherize(interfaceName) %>.type';<% if (hasViewProviderHelper) { %>
|
|
5
|
+
import { <%= viewProviderIdentifier %> } from '<%= viewProviderHelperPath %>';<% } %><% if (hasHostDirectiveHelper) { %>
|
|
6
|
+
import { <%= hostDirectiveIdentifier %> } from '<%= hostDirectiveHelperPath %>';<% } %>
|
|
7
|
+
|
|
8
|
+
@Component({
|
|
9
|
+
selector: 'app-<%= dasherize(componentName) %>',
|
|
10
|
+
imports: [ReactiveFormsModule],
|
|
11
|
+
templateUrl: './<%= dasherize(componentName) %>.component.html',
|
|
12
|
+
viewProviders: <% if (hasViewProviderHelper) { %><%= viewProviderIdentifier %><% } else { %>[
|
|
13
|
+
{
|
|
14
|
+
provide: ControlContainer,
|
|
15
|
+
useFactory: () => inject(ControlContainer, { skipSelf: true }),
|
|
16
|
+
}
|
|
17
|
+
]<% } %>,
|
|
18
|
+
hostDirectives: <% if (hasHostDirectiveHelper) { %>[<%= hostDirectiveIdentifier %>]<% } else { %>[
|
|
19
|
+
{
|
|
20
|
+
directive: NgxfbControlDirective,
|
|
21
|
+
inputs: ['content', 'name'],
|
|
22
|
+
}
|
|
23
|
+
]<% } %>,
|
|
24
|
+
})
|
|
25
|
+
export class <%= classify(componentClassName) %> {
|
|
26
|
+
private readonly control = inject(NgxfbControlDirective<<%= interfaceName %>>);
|
|
27
|
+
readonly content: Signal<<%= interfaceName %>> = this.control.content;
|
|
28
|
+
readonly name: Signal<string> = this.control.name;
|
|
29
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.control = control;
|
|
4
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const scaffold_and_register_rule_1 = require("../shared/rules/scaffold-and-register.rule");
|
|
6
|
+
function control(options) {
|
|
7
|
+
return () => {
|
|
8
|
+
return (0, schematics_1.chain)([(0, scaffold_and_register_rule_1.scaffoldAndRegister)(options, 'control')]);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/core/automation/schematics/control/index.ts"],"names":[],"mappings":";;AAIA,0BAIC;AARD,2DAAyD;AACzD,2FAAiF;AAGjF,SAAgB,OAAO,CAAC,OAAe;IACrC,OAAO,GAAG,EAAE;QACV,OAAO,IAAA,kBAAK,EAAC,CAAC,IAAA,gDAAmB,EAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "NgxFormbarControl",
|
|
4
|
+
"title": "Scaffold Control",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"description": "The name of the component that this control will use. Defaults to the key if not provided.",
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"key": {
|
|
12
|
+
"description": "The name of the key that this control will be associated with.",
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"path": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"format": "path",
|
|
18
|
+
"description": "The path to create the component.",
|
|
19
|
+
"visible": false,
|
|
20
|
+
"$default": {
|
|
21
|
+
"$source": "workingDirectory"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"project": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "The name of the project.",
|
|
27
|
+
"$default": {
|
|
28
|
+
"$source": "projectName"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"interfaceSuffix": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "The suffix of the interface. Defaults to 'Control'",
|
|
34
|
+
"default": "Control"
|
|
35
|
+
},
|
|
36
|
+
"componentSuffix": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "The suffix of the component. Defaults to 'Control'",
|
|
39
|
+
"default": "Control"
|
|
40
|
+
},
|
|
41
|
+
"hostDirectiveHelperPath": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Path to the hostDirective helper"
|
|
44
|
+
},
|
|
45
|
+
"skipRegistration": {
|
|
46
|
+
"type": "boolean",
|
|
47
|
+
"description": "Skip automatic registration"
|
|
48
|
+
},
|
|
49
|
+
"viewProviderHelperPath": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "Path to the viewProvider helper"
|
|
52
|
+
},
|
|
53
|
+
"schematicsConfig": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"description": "Path of the configuration that is to be used by this schematic"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"required": [
|
|
59
|
+
"key"
|
|
60
|
+
]
|
|
61
|
+
}
|