@ng-forge/dynamic-forms 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs +79 -6
- package/fesm2022/ng-forge-dynamic-forms-integration.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-ng-forge-dynamic-forms-CZBdtTAU.mjs → ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs} +301 -72
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CMSmISSp.mjs.map +1 -0
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-BM32StxL.mjs → ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-page-field.component-BM32StxL.mjs.map → ng-forge-dynamic-forms-page-field.component-rdGD8A9d.mjs.map} +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-testing-test-button.harness-CbctXjtc.mjs → ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs} +7 -7
- package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-0iXHLraC.mjs.map +1 -0
- package/fesm2022/ng-forge-dynamic-forms-testing.mjs +25 -25
- package/fesm2022/ng-forge-dynamic-forms-testing.mjs.map +1 -1
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-C0I8jf9T.mjs → ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs} +5 -5
- package/fesm2022/{ng-forge-dynamic-forms-text-field.component-C0I8jf9T.mjs.map → ng-forge-dynamic-forms-text-field.component-CDxka2KD.mjs.map} +1 -1
- package/fesm2022/ng-forge-dynamic-forms.mjs +1 -1
- package/package.json +4 -4
- package/types/ng-forge-dynamic-forms-integration.d.ts +225 -9
- package/types/ng-forge-dynamic-forms-testing.d.ts +32 -1
- package/types/ng-forge-dynamic-forms.d.ts +202 -15
- package/fesm2022/ng-forge-dynamic-forms-ng-forge-dynamic-forms-CZBdtTAU.mjs.map +0 -1
- package/fesm2022/ng-forge-dynamic-forms-testing-test-button.harness-CbctXjtc.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FormEvent, FieldDef, FormEventConstructor, BaseCheckedField, BaseValueField, DynamicText, FieldOption, ValidationMessages } from '@ng-forge/dynamic-forms';
|
|
1
|
+
import { FormEvent, FieldDef, FormEventConstructor, BaseCheckedField, BaseValueField, DynamicText, FieldMeta, FieldOption, ValidationMessages } from '@ng-forge/dynamic-forms';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { Signal, Injector, PipeTransform } from '@angular/core';
|
|
3
|
+
import { Signal, Injector, ElementRef, PipeTransform } from '@angular/core';
|
|
4
4
|
import { FieldTree } from '@angular/forms/signals';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -43,6 +43,94 @@ interface DatepickerField<TProps> extends BaseValueField<TProps, Date | string>
|
|
|
43
43
|
startAt?: Date | null;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Autocomplete values for HTML input elements.
|
|
48
|
+
* Based on the WHATWG HTML specification for autofill.
|
|
49
|
+
*
|
|
50
|
+
* @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
|
|
51
|
+
*/
|
|
52
|
+
type AutocompleteValue = 'off' | 'on' | 'name' | 'honorific-prefix' | 'given-name' | 'additional-name' | 'family-name' | 'honorific-suffix' | 'nickname' | 'email' | 'username' | 'new-password' | 'current-password' | 'one-time-code' | 'organization-title' | 'organization' | 'street-address' | 'address-line1' | 'address-line2' | 'address-line3' | 'address-level4' | 'address-level3' | 'address-level2' | 'address-level1' | 'country' | 'country-name' | 'postal-code' | 'cc-name' | 'cc-given-name' | 'cc-additional-name' | 'cc-family-name' | 'cc-number' | 'cc-exp' | 'cc-exp-month' | 'cc-exp-year' | 'cc-csc' | 'cc-type' | 'transaction-currency' | 'transaction-amount' | 'language' | 'bday' | 'bday-day' | 'bday-month' | 'bday-year' | 'sex' | 'tel' | 'tel-country-code' | 'tel-national' | 'tel-area-code' | 'tel-local' | 'tel-extension' | 'impp' | 'url' | 'photo';
|
|
53
|
+
/**
|
|
54
|
+
* Input mode hints for virtual keyboards on mobile devices.
|
|
55
|
+
*
|
|
56
|
+
* @see https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute
|
|
57
|
+
*/
|
|
58
|
+
type InputMode = 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
|
|
59
|
+
/**
|
|
60
|
+
* Enter key hints for virtual keyboards.
|
|
61
|
+
*
|
|
62
|
+
* @see https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-enterkeyhint-attribute
|
|
63
|
+
*/
|
|
64
|
+
type EnterKeyHint = 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
|
|
65
|
+
/**
|
|
66
|
+
* Autocapitalization hints for virtual keyboards.
|
|
67
|
+
*
|
|
68
|
+
* @see https://html.spec.whatwg.org/multipage/interaction.html#attr-autocapitalize
|
|
69
|
+
*/
|
|
70
|
+
type Autocapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
|
|
71
|
+
/**
|
|
72
|
+
* Meta attributes specific to HTML input elements.
|
|
73
|
+
*
|
|
74
|
+
* Extends FieldMeta with input-specific native attributes that can be passed through
|
|
75
|
+
* to the underlying input element.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* // Input field with meta attributes
|
|
80
|
+
* {
|
|
81
|
+
* type: 'input',
|
|
82
|
+
* key: 'email',
|
|
83
|
+
* meta: {
|
|
84
|
+
* autocomplete: 'email',
|
|
85
|
+
* inputmode: 'email',
|
|
86
|
+
* enterkeyhint: 'next',
|
|
87
|
+
* spellcheck: false,
|
|
88
|
+
* 'data-testid': 'email-input'
|
|
89
|
+
* }
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
interface InputMeta extends FieldMeta {
|
|
96
|
+
/**
|
|
97
|
+
* Hint for form autofill behavior.
|
|
98
|
+
*/
|
|
99
|
+
autocomplete?: AutocompleteValue;
|
|
100
|
+
/**
|
|
101
|
+
* Hint for virtual keyboard type on mobile devices.
|
|
102
|
+
*/
|
|
103
|
+
inputmode?: InputMode;
|
|
104
|
+
/**
|
|
105
|
+
* Hint for the enter key label on virtual keyboards.
|
|
106
|
+
*/
|
|
107
|
+
enterkeyhint?: EnterKeyHint;
|
|
108
|
+
/**
|
|
109
|
+
* Whether to enable spellchecking for the input.
|
|
110
|
+
*/
|
|
111
|
+
spellcheck?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Hint for autocapitalization behavior on virtual keyboards.
|
|
114
|
+
*/
|
|
115
|
+
autocapitalize?: Autocapitalize;
|
|
116
|
+
/**
|
|
117
|
+
* Pattern for client-side validation (regex).
|
|
118
|
+
*/
|
|
119
|
+
pattern?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Size hint for the input element (character count).
|
|
122
|
+
*/
|
|
123
|
+
size?: number;
|
|
124
|
+
/**
|
|
125
|
+
* Maximum number of characters allowed.
|
|
126
|
+
*/
|
|
127
|
+
maxlength?: number;
|
|
128
|
+
/**
|
|
129
|
+
* Minimum number of characters required.
|
|
130
|
+
*/
|
|
131
|
+
minlength?: number;
|
|
132
|
+
}
|
|
133
|
+
|
|
46
134
|
/**
|
|
47
135
|
* HTML input types supported by input fields
|
|
48
136
|
*/
|
|
@@ -77,7 +165,7 @@ interface NumberInputField<TProps extends {
|
|
|
77
165
|
type?: string;
|
|
78
166
|
} = InputProps> extends BaseValueField<TProps & {
|
|
79
167
|
type: 'number';
|
|
80
|
-
}, number> {
|
|
168
|
+
}, number, InputMeta> {
|
|
81
169
|
type: 'input';
|
|
82
170
|
props: TProps & {
|
|
83
171
|
type: 'number';
|
|
@@ -92,7 +180,7 @@ interface StringInputField<TProps extends {
|
|
|
92
180
|
type?: string;
|
|
93
181
|
} = InputProps> extends BaseValueField<TProps & {
|
|
94
182
|
type?: StringInputType;
|
|
95
|
-
}, string> {
|
|
183
|
+
}, string, InputMeta> {
|
|
96
184
|
type: 'input';
|
|
97
185
|
props?: TProps & {
|
|
98
186
|
type?: StringInputType;
|
|
@@ -156,12 +244,12 @@ type InputField<TProps extends {
|
|
|
156
244
|
*/
|
|
157
245
|
interface MultiCheckboxField<TValue, TProps = object> extends BaseValueField<TProps, TValue[]> {
|
|
158
246
|
type: 'multi-checkbox';
|
|
159
|
-
options: FieldOption<TValue>[];
|
|
247
|
+
readonly options: readonly FieldOption<TValue>[];
|
|
160
248
|
}
|
|
161
249
|
|
|
162
250
|
interface RadioField<T, TProps> extends BaseValueField<TProps, T> {
|
|
163
251
|
type: 'radio';
|
|
164
|
-
options: FieldOption<T>[];
|
|
252
|
+
readonly options: readonly FieldOption<T>[];
|
|
165
253
|
}
|
|
166
254
|
|
|
167
255
|
interface SelectProps {
|
|
@@ -179,12 +267,75 @@ interface SliderField<TProps> extends BaseValueField<TProps, number> {
|
|
|
179
267
|
step?: number;
|
|
180
268
|
}
|
|
181
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Text wrapping behavior for textarea elements.
|
|
272
|
+
*
|
|
273
|
+
* @see https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-wrap
|
|
274
|
+
*/
|
|
275
|
+
type TextareaWrap = 'hard' | 'soft' | 'off';
|
|
276
|
+
/**
|
|
277
|
+
* Meta attributes specific to HTML textarea elements.
|
|
278
|
+
*
|
|
279
|
+
* Extends FieldMeta with textarea-specific native attributes that can be passed through
|
|
280
|
+
* to the underlying textarea element.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* // Textarea field with meta attributes
|
|
285
|
+
* {
|
|
286
|
+
* type: 'textarea',
|
|
287
|
+
* key: 'description',
|
|
288
|
+
* meta: {
|
|
289
|
+
* wrap: 'soft',
|
|
290
|
+
* spellcheck: true,
|
|
291
|
+
* autocomplete: 'off',
|
|
292
|
+
* 'data-testid': 'description-textarea'
|
|
293
|
+
* }
|
|
294
|
+
* }
|
|
295
|
+
* ```
|
|
296
|
+
*
|
|
297
|
+
* @public
|
|
298
|
+
*/
|
|
299
|
+
interface TextareaMeta extends FieldMeta {
|
|
300
|
+
/**
|
|
301
|
+
* How text should wrap when submitted.
|
|
302
|
+
* - 'hard': Line breaks are inserted to wrap text at cols width
|
|
303
|
+
* - 'soft': Text is wrapped for display but not in submitted value
|
|
304
|
+
* - 'off': No wrapping, horizontal scrolling if needed
|
|
305
|
+
*/
|
|
306
|
+
wrap?: TextareaWrap;
|
|
307
|
+
/**
|
|
308
|
+
* Whether to enable spellchecking for the textarea.
|
|
309
|
+
*/
|
|
310
|
+
spellcheck?: boolean;
|
|
311
|
+
/**
|
|
312
|
+
* Hint for form autofill behavior.
|
|
313
|
+
*/
|
|
314
|
+
autocomplete?: AutocompleteValue;
|
|
315
|
+
/**
|
|
316
|
+
* Hint for autocapitalization behavior on virtual keyboards.
|
|
317
|
+
*/
|
|
318
|
+
autocapitalize?: Autocapitalize;
|
|
319
|
+
/**
|
|
320
|
+
* Hint for the enter key label on virtual keyboards.
|
|
321
|
+
*/
|
|
322
|
+
enterkeyhint?: EnterKeyHint;
|
|
323
|
+
/**
|
|
324
|
+
* Maximum number of characters allowed.
|
|
325
|
+
*/
|
|
326
|
+
maxlength?: number;
|
|
327
|
+
/**
|
|
328
|
+
* Minimum number of characters required.
|
|
329
|
+
*/
|
|
330
|
+
minlength?: number;
|
|
331
|
+
}
|
|
332
|
+
|
|
182
333
|
interface TextareaProps {
|
|
183
334
|
placeholder?: DynamicText;
|
|
184
335
|
rows?: number;
|
|
185
336
|
cols?: number | undefined;
|
|
186
337
|
}
|
|
187
|
-
interface TextareaField<TProps = TextareaProps> extends BaseValueField<TProps, string> {
|
|
338
|
+
interface TextareaField<TProps = TextareaProps> extends BaseValueField<TProps, string, TextareaMeta> {
|
|
188
339
|
type: 'textarea';
|
|
189
340
|
maxLength?: number | undefined;
|
|
190
341
|
}
|
|
@@ -317,11 +468,76 @@ declare function shouldShowErrors<T>(field: Signal<FieldTree<T>>): Signal<boolea
|
|
|
317
468
|
*/
|
|
318
469
|
declare function isEqual(a: unknown, b: unknown): boolean;
|
|
319
470
|
|
|
471
|
+
/**
|
|
472
|
+
* Configuration options for setupMetaTracking.
|
|
473
|
+
*/
|
|
474
|
+
interface MetaTrackingOptions {
|
|
475
|
+
/**
|
|
476
|
+
* CSS selector for target elements within the host.
|
|
477
|
+
* If not provided, meta attributes are applied directly to the host element.
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* // Apply to internal radio inputs
|
|
481
|
+
* selector: 'input[type="radio"]'
|
|
482
|
+
*
|
|
483
|
+
* // Apply to host element (for Shadow DOM components)
|
|
484
|
+
* selector: undefined
|
|
485
|
+
*/
|
|
486
|
+
selector?: string;
|
|
487
|
+
/**
|
|
488
|
+
* Additional signals to track that should trigger re-application of meta.
|
|
489
|
+
* Useful for components where DOM elements are dynamically created (e.g., radio options).
|
|
490
|
+
*
|
|
491
|
+
* @example
|
|
492
|
+
* // Re-apply when options change
|
|
493
|
+
* dependents: [this.options]
|
|
494
|
+
*/
|
|
495
|
+
dependents?: Signal<unknown>[];
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Sets up automatic meta attribute tracking and application for wrapped components.
|
|
499
|
+
*
|
|
500
|
+
* This utility creates an `afterRenderEffect` that applies meta attributes to DOM elements
|
|
501
|
+
* after Angular's render cycle. It efficiently tracks signal dependencies and only re-applies
|
|
502
|
+
* when the meta signal or any dependent signals change.
|
|
503
|
+
*
|
|
504
|
+
* Use this instead of MutationObserver for better performance and integration with Angular's
|
|
505
|
+
* change detection.
|
|
506
|
+
*
|
|
507
|
+
* @param elementRef - Reference to the host element
|
|
508
|
+
* @param meta - Signal containing meta attributes to apply
|
|
509
|
+
* @param options - Configuration options
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```typescript
|
|
513
|
+
* // For a radio group with dynamic options
|
|
514
|
+
* constructor() {
|
|
515
|
+
* setupMetaTracking(inject(ElementRef), this.meta, {
|
|
516
|
+
* selector: 'input[type="radio"]',
|
|
517
|
+
* dependents: [this.options]
|
|
518
|
+
* });
|
|
519
|
+
* }
|
|
520
|
+
*
|
|
521
|
+
* // For a simple checkbox
|
|
522
|
+
* constructor() {
|
|
523
|
+
* setupMetaTracking(inject(ElementRef), this.meta, {
|
|
524
|
+
* selector: 'input[type="checkbox"]'
|
|
525
|
+
* });
|
|
526
|
+
* }
|
|
527
|
+
*
|
|
528
|
+
* // For Shadow DOM components (apply to host)
|
|
529
|
+
* constructor() {
|
|
530
|
+
* setupMetaTracking(inject(ElementRef), this.meta);
|
|
531
|
+
* }
|
|
532
|
+
* ```
|
|
533
|
+
*/
|
|
534
|
+
declare function setupMetaTracking(elementRef: ElementRef<HTMLElement>, meta: Signal<FieldMeta | undefined>, options?: MetaTrackingOptions): void;
|
|
535
|
+
|
|
320
536
|
declare class ValueInArrayPipe implements PipeTransform {
|
|
321
537
|
transform<T>(element: T, array: T[] | undefined): boolean;
|
|
322
538
|
static ɵfac: i0.ɵɵFactoryDeclaration<ValueInArrayPipe, never>;
|
|
323
539
|
static ɵpipe: i0.ɵɵPipeDeclaration<ValueInArrayPipe, "inArray", true>;
|
|
324
540
|
}
|
|
325
541
|
|
|
326
|
-
export { ValueInArrayPipe, buildValueFieldInputs, checkboxFieldMapper, createResolvedErrorsSignal, datepickerFieldMapper, isEqual, optionsFieldMapper, resolveValueFieldContext, shouldShowErrors, valueFieldMapper };
|
|
327
|
-
export type { ButtonField, CheckboxField, DatepickerField, DatepickerProps, EventArgs, FieldWithOptions, InputField, InputProps, InputType, InputTypeToValueType, MultiCheckboxField, RadioField, ResolvedError, SelectField, SelectProps, SliderField, StringInputType, TextareaField, TextareaProps, ToggleField, ValueFieldContext };
|
|
542
|
+
export { ValueInArrayPipe, buildValueFieldInputs, checkboxFieldMapper, createResolvedErrorsSignal, datepickerFieldMapper, isEqual, optionsFieldMapper, resolveValueFieldContext, setupMetaTracking, shouldShowErrors, valueFieldMapper };
|
|
543
|
+
export type { Autocapitalize, AutocompleteValue, ButtonField, CheckboxField, DatepickerField, DatepickerProps, EnterKeyHint, EventArgs, FieldWithOptions, InputField, InputMeta, InputMode, InputProps, InputType, InputTypeToValueType, MetaTrackingOptions, MultiCheckboxField, RadioField, ResolvedError, SelectField, SelectProps, SliderField, StringInputType, TextareaField, TextareaMeta, TextareaProps, TextareaWrap, ToggleField, ValueFieldContext };
|
|
@@ -402,6 +402,37 @@ interface ComponentTestResult<T = unknown> {
|
|
|
402
402
|
fixture: ComponentFixture<T>;
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
/**
|
|
406
|
+
* Type utilities for exhaustive whitelist type testing.
|
|
407
|
+
*
|
|
408
|
+
* These utilities help ensure that type definitions remain stable by detecting
|
|
409
|
+
* when properties are added, removed, or changed.
|
|
410
|
+
*/
|
|
411
|
+
/**
|
|
412
|
+
* Extracts only the required keys from a type.
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```typescript
|
|
416
|
+
* interface Example { a: string; b?: number; }
|
|
417
|
+
* type Required = RequiredKeys<Example>; // 'a'
|
|
418
|
+
* ```
|
|
419
|
+
*/
|
|
420
|
+
type RequiredKeys<T> = {
|
|
421
|
+
[K in keyof T]-?: object extends Pick<T, K> ? never : K;
|
|
422
|
+
}[keyof T];
|
|
423
|
+
/**
|
|
424
|
+
* Extracts only the optional keys from a type.
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```typescript
|
|
428
|
+
* interface Example { a: string; b?: number; }
|
|
429
|
+
* type Optional = OptionalKeys<Example>; // 'b'
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
432
|
+
type OptionalKeys<T> = {
|
|
433
|
+
[K in keyof T]-?: object extends Pick<T, K> ? K : never;
|
|
434
|
+
}[keyof T];
|
|
435
|
+
|
|
405
436
|
declare class TestInputHarness {
|
|
406
437
|
readonly field: _angular_core.InputSignal<FieldTree<string>>;
|
|
407
438
|
readonly key: _angular_core.InputSignal<string>;
|
|
@@ -563,4 +594,4 @@ declare const SPANISH_TEST_TRANSLATIONS: {
|
|
|
563
594
|
declare function createTestTranslationService(initialTranslations?: Record<string, string>): FakeTranslationService;
|
|
564
595
|
|
|
565
596
|
export { DEFAULT_TEST_TRANSLATIONS, DynamicFormTestUtils, FakeTranslationService, FormConfigBuilder, SPANISH_TEST_TRANSLATIONS, TestFormConfigBuilder as SimpleFormConfigBuilder, SimpleTestUtils, TestCheckboxHarness as TestCheckboxHarnessComponent, TestFieldComponent, TestInputHarness as TestInputHarnessComponent, TestSelectHarness as TestSelectHarnessComponent, createMockLogger, createSimpleTestField, createTestFieldContext, createTestFormInjector, createTestTranslationService, delay, provideTestLogger, setupSimpleTest, testMapper };
|
|
566
|
-
export type { ComponentTestConfig, ComponentTestResult, DynamicFormTestConfig, DynamicFormTestResult, MockLogger, SimpleComponentTestConfig, SimpleComponentTestResult, SimpleTestConfig, SimpleTestResult, TestConfig, TestFieldContextConfig, TestFormConfig, TestResult };
|
|
597
|
+
export type { ComponentTestConfig, ComponentTestResult, DynamicFormTestConfig, DynamicFormTestResult, MockLogger, OptionalKeys, RequiredKeys, SimpleComponentTestConfig, SimpleComponentTestResult, SimpleTestConfig, SimpleTestResult, TestConfig, TestFieldContextConfig, TestFormConfig, TestResult };
|