@ng-simplicity/forms-core 1.1.2 → 1.1.4

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/index.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- import * as rxjs from 'rxjs';
2
1
  import { Subject, Subscription, Observable, BehaviorSubject } from 'rxjs';
3
2
  import * as i0 from '@angular/core';
4
- import { OnInit, OnDestroy, Signal, Type, InjectionToken, Injector, ViewContainerRef, ChangeDetectorRef } from '@angular/core';
3
+ import { OnInit, OnDestroy, Signal, Type, InjectionToken, Injector, ViewContainerRef, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';
5
4
  import * as _angular_forms from '@angular/forms';
6
- import { ValidatorFn, UntypedFormControl, FormGroup, AbstractControl, UntypedFormGroup, UntypedFormArray, FormArray } from '@angular/forms';
5
+ import { ValidatorFn, AbstractControl, UntypedFormControl, FormGroup, UntypedFormGroup, UntypedFormArray, FormArray } from '@angular/forms';
7
6
  import * as _ng_simplicity_forms_core from '@ng-simplicity/forms-core';
8
7
  import * as i1 from '@angular/common';
9
8
 
@@ -39,8 +38,8 @@ type NgsFormsFormErrorKeyValueMap = {
39
38
 
40
39
  /** One option of a radio group or select. */
41
40
  interface NgsFormsFormInputOption {
42
- /** Value written to the form control when the option is chosen. */
43
- id: string;
41
+ /** Value written to the form control when the option is chosen. Numbers stay numbers. */
42
+ id: string | number;
44
43
  /** Text shown to the user. */
45
44
  label: string;
46
45
  /** Renders the option but prevents choosing it. */
@@ -55,10 +54,9 @@ interface NgsFormsFormItemConfigBase {
55
54
  */
56
55
  uuid?: string;
57
56
  /**
58
- * Static visibility flag.
57
+ * Static visibility flag. `false` keeps the item out of the form, as if `visible$` had emitted `false`.
59
58
  *
60
- * @notImplemented
61
- * @remarks Reserved for future use: the renderer currently ignores it. Use `visible$` to show or hide an item.
59
+ * @remarks Ignored when `visible$` is also set.
62
60
  */
63
61
  visible?: boolean;
64
62
  /**
@@ -74,10 +72,14 @@ interface NgsFormsFormItemConfigBase {
74
72
  */
75
73
  visible$?: Observable<boolean>;
76
74
  /**
77
- * Initial component state for this item.
75
+ * Initial component state for this item, read by input components through `commonState()`.
78
76
  *
79
- * @notImplemented
80
- * @remarks Reserved for future use.
77
+ * @remarks Applied when the component is first created, unless state for this item's `uuid` was already set.
78
+ * It takes precedence over state set by `name` and over global state.
79
+ * @example
80
+ * ```ts
81
+ * initialState: { displayMode: 'summary', showEditToggle: true }
82
+ * ```
81
83
  */
82
84
  initialState?: any;
83
85
  }
@@ -109,17 +111,19 @@ interface NgsFormsFormItemConfigBaseItemWithNameAndValidators extends NgsFormsFo
109
111
  */
110
112
  errorMessageMap?: NgsFormsFormErrorKeyValueMap;
111
113
  /**
112
- * Static disabled flag.
114
+ * Static disabled flag. `true` disables the item's control (and, for groups and arrays, every control inside).
113
115
  *
114
- * @notImplemented
115
- * @remarks Reserved for future use: the built-in components do not read it yet.
116
+ * @remarks Ignored when `disabled$` is also set. Disabled controls are left out of `NgsFormsService.formValue$`
117
+ * and skip validation, which is how Angular reactive forms treat them.
116
118
  */
117
119
  disabled?: boolean;
118
120
  /**
119
- * Stream that controls the disabled state.
121
+ * Stream that controls the disabled state. Each emission disables (`true`) or enables (`false`) the control.
120
122
  *
121
- * @notImplemented
122
- * @remarks Reserved for future use: the built-in components do not read it yet.
123
+ * @example
124
+ * ```ts
125
+ * disabled$: this.forms.formValue$.pipe(map((v) => !v?.profile?.hasCompany))
126
+ * ```
123
127
  */
124
128
  disabled$?: Observable<boolean>;
125
129
  /**
@@ -128,29 +132,23 @@ interface NgsFormsFormItemConfigBaseItemWithNameAndValidators extends NgsFormsFo
128
132
  validators?: Array<ValidatorFn>;
129
133
  /**
130
134
  * Stream of validator arrays. Each emission replaces the control's validators, which lets rules depend on other
131
- * values in the form. Ignored when `validators` is also set.
132
- *
133
- * @remarks The control's validity is recalculated on its next value change, so call `updateValueAndValidity()`
134
- * yourself if you need the new rules to apply immediately.
135
+ * values in the form. The control is re-validated on each emission. Ignored when `validators` is also set.
135
136
  */
136
137
  validators$?: Observable<Array<ValidatorFn>>;
137
138
  }
138
139
  /** Base configuration for a labelled input control. */
139
140
  interface NgsFormsFormItemConfigBaseInput extends NgsFormsFormItemConfigBaseItemWithNameAndValidators {
140
141
  /**
141
- * Optional element id.
142
+ * Element id for the input. When omitted the component generates a unique one.
142
143
  *
143
- * @notImplemented
144
- * @remarks Reserved for future use: the built-in components generate their own ids.
144
+ * @remarks Must be unique on the page, so avoid it inside form array rows.
145
145
  */
146
146
  id?: string;
147
147
  /** Label text shown next to or above the control. */
148
148
  label: string;
149
149
  /**
150
- * Initial value.
151
- *
152
- * @notImplemented
153
- * @remarks Reserved for future use. Set initial values with `NgsFormsService.patchValue()` after the form renders.
150
+ * Initial value of the control. Applied when the control is created, including when a `visible$` item is shown
151
+ * again.
154
152
  */
155
153
  value?: unknown;
156
154
  }
@@ -194,9 +192,22 @@ interface NgsFormsFormItem<T extends NgsFormsFormItemConfigBase> {
194
192
  config: T;
195
193
  }
196
194
 
195
+ /**
196
+ * State that components read through `commonState()`. Set it with `globalState` / `initialState` in the config, or
197
+ * at runtime with `NgsFormsService.updateGlobalState()` and `updateComponentState()`.
198
+ *
199
+ * @remarks The built-in theme components do not read these yet. They are a contract for your own components.
200
+ */
197
201
  interface NgsFormsCommonComponentState {
202
+ /**
203
+ * `input` shows the editable control. `summary` shows a compact, read-only display of the current value, for
204
+ * example to save space on small screens.
205
+ */
198
206
  displayMode?: 'input' | 'summary';
207
+ /** Whether to show a control that lets the user switch between `summary` and `input`. */
199
208
  showEditToggle?: boolean;
209
+ /** Your own keys. Read them from `commonState()` in custom components. */
210
+ [key: string]: unknown;
200
211
  }
201
212
 
202
213
  interface NgsFormsGlobalFormState extends NgsFormsCommonComponentState {
@@ -222,19 +233,30 @@ interface NgsFormsFormConfig<T = NgsFormsFormItem<any>> {
222
233
  * @remarks Reserved for future use: values currently update on every change.
223
234
  */
224
235
  inputUpdateDebounce: number;
225
- /** Initial state shared by every component in the form. */
236
+ /**
237
+ * Initial state shared by every component in the form. Applied each time `setFormConfig()` is called; change it
238
+ * later with `NgsFormsService.updateGlobalState()`.
239
+ */
226
240
  globalState: NgsFormsGlobalFormState;
227
241
  /**
228
242
  * The root item, usually an `NgsFormsFormGroupComponent`, whose form group backs the whole form.
229
243
  */
230
244
  root: T;
231
245
  /**
232
- * Initial form state.
246
+ * Initial state for individual components, keyed by item `uuid` or control `name`.
233
247
  *
234
- * @notImplemented
235
- * @remarks Reserved for future use.
248
+ * @remarks Applied each time `setFormConfig()` is called, together with `globalState`. Same as calling
249
+ * `NgsFormsService.updateComponentState(key, state)` for each entry before the form renders.
250
+ * @example
251
+ * ```ts
252
+ * initialState: { email: { displayMode: 'input' } }
253
+ * ```
236
254
  */
237
- initialState?: any;
255
+ initialState?: {
256
+ [componentKey: string]: NgsFormsCommonComponentState & {
257
+ [key: string]: any;
258
+ };
259
+ };
238
260
  }
239
261
 
240
262
  /**
@@ -246,7 +268,10 @@ interface NgsFormsFormConfig<T = NgsFormsFormItem<any>> {
246
268
  declare abstract class NgsFormsBaseClassFormComponent<T extends NgsFormsFormItemConfigBase> extends NgsSubscriber {
247
269
  /** Registry key the component is registered under. */
248
270
  static key: string;
249
- /** Unique id for this component instance, handy for `id` and `for` attributes. */
271
+ /**
272
+ * Element id for this component, handy for `id` and `for` attributes. The config's `id` when it sets one,
273
+ * otherwise a generated unique id.
274
+ */
250
275
  id: string;
251
276
  /** The item's configuration. */
252
277
  protected config: T;
@@ -258,12 +283,17 @@ declare abstract class NgsFormsBaseClassFormComponent<T extends NgsFormsFormItem
258
283
  }
259
284
 
260
285
  /**
261
- * Base class for items that own a form control. Creates the control, applies `validators` / `validators$`,
262
- * registers it with the parent group under `config.name` and keeps `errorMessage` up to date.
286
+ * Base class for items that own a form control. Creates the control (seeded with `value` when the config has one),
287
+ * applies `validators` / `validators$` and `disabled` / `disabled$`, registers it with the parent group under
288
+ * `config.name` and keeps `errorMessage` up to date.
289
+ *
290
+ * @typeParam T - The item's config type.
291
+ * @typeParam C - The type of `control`. Inputs use the default `UntypedFormControl`; groups and arrays set it in
292
+ * their constructor to an `UntypedFormGroup` or `UntypedFormArray`.
263
293
  */
264
- declare class NgsFormsFormItemWithVisibleAndValidatorsBase<T extends NgsFormsFormItemConfigBaseItemWithNameAndValidators> extends NgsFormsBaseClassFormComponent<T> implements OnInit, OnDestroy {
294
+ declare class NgsFormsFormItemWithVisibleAndValidatorsBase<T extends NgsFormsFormItemConfigBaseItemWithNameAndValidators, C extends AbstractControl = UntypedFormControl> extends NgsFormsBaseClassFormComponent<T> implements OnInit, OnDestroy {
265
295
  /** The item's form control. Bind it with `[formControl]`. */
266
- control: UntypedFormControl | undefined;
296
+ control: C | undefined;
267
297
  /**
268
298
  * Message for the control's first error, taken from `errorMessageMap`. Empty while the control is valid, or
269
299
  * before it is touched, dirty or submitted.
@@ -274,12 +304,18 @@ declare class NgsFormsFormItemWithVisibleAndValidatorsBase<T extends NgsFormsFor
274
304
  private changeDetectorRef;
275
305
  /** Whether the form has been marked as submitted with `NgsFormsService.setIsSubmitted()`. */
276
306
  readonly submitted: Signal<boolean>;
307
+ /** The latest value of `disabled` / `disabled$`, or `undefined` when the config sets neither. */
308
+ private disabledFromConfig;
277
309
  ngOnInit(): void;
310
+ /** Whether the control currently has `Validators.required` or `Validators.requiredTrue`. */
311
+ get isRequired(): boolean;
278
312
  private updateErrorMessage;
279
313
  ngOnDestroy(): void;
280
314
  private bindValidators;
281
- static ɵfac: i0.ɵɵFactoryDeclaration<NgsFormsFormItemWithVisibleAndValidatorsBase<any>, never>;
282
- static ɵdir: i0.ɵɵDirectiveDeclaration<NgsFormsFormItemWithVisibleAndValidatorsBase<any>, never, never, {}, {}, never, never, true, never>;
315
+ private bindDisabled;
316
+ private applyDisabled;
317
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgsFormsFormItemWithVisibleAndValidatorsBase<any, any>, never>;
318
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NgsFormsFormItemWithVisibleAndValidatorsBase<any, any>, never, never, {}, {}, never, never, true, never>;
283
319
  }
284
320
 
285
321
  /**
@@ -321,12 +357,19 @@ declare class NgsFormsInternalService {
321
357
  [key: string]: any;
322
358
  }>;
323
359
  setIsSubmitted(isSubmitted: boolean): void;
360
+ /** `true` when no rendered control fails its validators. A form whose controls are all disabled counts as valid. */
324
361
  checkIsValid(): boolean;
325
362
  setFormData(formConfig: NgsFormsFormConfig): void;
326
363
  private mergeState;
327
- updateGlobalState(state: NgsFormsGlobalFormState): void;
328
- updateComponentState(componentKey: string, state: any): void;
329
- subscribeToState(uuid: string, name?: string): rxjs.Observable<any>;
364
+ /** Sets a component's state from its config's `initialState`, unless state for `uuid` already exists. */
365
+ seedComponentState(uuid: string, initialState: any): void;
366
+ updateGlobalState(state: Partial<NgsFormsGlobalFormState>): void;
367
+ updateComponentState(componentKey: string, state: Partial<NgsFormsCommonComponentState>): void;
368
+ /**
369
+ * Merged state for one component: its own (by `uuid`), then by `name`, then global.
370
+ * `initialState` seeds the component's own state unless state for `uuid` already exists.
371
+ */
372
+ subscribeToState(uuid: string, name?: string, initialState?: any): Observable<NgsFormsCommonComponentState>;
330
373
  static ɵfac: i0.ɵɵFactoryDeclaration<NgsFormsInternalService, never>;
331
374
  static ɵprov: i0.ɵɵInjectableDeclaration<NgsFormsInternalService>;
332
375
  }
@@ -349,10 +392,6 @@ declare class NgsFormsInternalService {
349
392
  * ```
350
393
  */
351
394
  declare class NgsFormsService implements OnDestroy {
352
- /**
353
- * @internal
354
- */
355
- attempt: number;
356
395
  /**
357
396
  * Emits the root form group's value every time it changes. Combine with `toSignal()` to read it in a template.
358
397
  *
@@ -362,8 +401,12 @@ declare class NgsFormsService implements OnDestroy {
362
401
  /** The latest value emitted by `formValue$`. */
363
402
  formValue: any;
364
403
  private internalFormService;
365
- private formGroupSubscriptions;
404
+ private formGroupBinding;
366
405
  private formGroup;
406
+ /** The config from the latest `setFormConfig()` call, re-applied when `<ngs-form>` (re)connects. */
407
+ private lastConfig;
408
+ private missingFormTimer;
409
+ private destroyed;
367
410
  /** `true` once the user has changed any control in the form. */
368
411
  get dirty(): boolean;
369
412
  /** `true` when every rendered control passes its validators. Hidden items are not validated. */
@@ -373,14 +416,21 @@ declare class NgsFormsService implements OnDestroy {
373
416
  /**
374
417
  * Renders a form from `formConfig`, replacing any form that is already shown and resetting the submitted state.
375
418
  *
376
- * @remarks It is safe to call before `<ngs-form>` has initialised (for example in `ngOnInit`): the call is retried
377
- * every 25 ms for about half a second until the form component is available.
419
+ * @remarks It is safe to call before `<ngs-form>` has initialised (for example in `ngOnInit`): the latest config
420
+ * is kept and applied as soon as the form component connects, and also when it is destroyed and created again
421
+ * (inside an `@if` or a tab, for example). An error is logged if no form has connected after half a second.
378
422
  */
379
423
  setFormConfig(formConfig: NgsFormsFormConfig): void;
380
424
  /**
381
425
  * @internal
382
426
  */
383
427
  setInternalService(internalFormsService: NgsFormsInternalService): void;
428
+ /**
429
+ * @internal
430
+ * Disconnects `internalFormsService` when its `<ngs-form>` is destroyed. Does nothing if another form has
431
+ * connected since.
432
+ */
433
+ clearInternalService(internalFormsService: NgsFormsInternalService): void;
384
434
  /**
385
435
  * Marks the form as submitted (or not). While submitted, every invalid control shows its error message even if
386
436
  * the user never touched it.
@@ -391,9 +441,9 @@ declare class NgsFormsService implements OnDestroy {
391
441
  * Merges `state` into the state of one component, identified by its `uuid` or control `name`.
392
442
  * Components read the merged result through `commonState`.
393
443
  */
394
- updateComponentState(componentKey: string, state: any): void;
444
+ updateComponentState(componentKey: string, state: Partial<NgsFormsCommonComponentState>): void;
395
445
  /** Merges `state` into the state shared by every component in the form. */
396
- updateGlobalState(state: any): void;
446
+ updateGlobalState(state: Partial<NgsFormsGlobalFormState>): void;
397
447
  ngOnDestroy(): void;
398
448
  /**
399
449
  * Patches values into the form, using the same shape as `formValue$` (including the root group name).
@@ -418,11 +468,10 @@ declare abstract class NgsFormsBaseClassFormInputComponent<T extends NgsFormsFor
418
468
  /** Merged state for this component: its own state, then state by name, then global state. */
419
469
  readonly commonState: Signal<NgsFormsCommonComponentState>;
420
470
  /**
421
- * Switches between input and summary display.
422
- *
423
- * @notImplemented
471
+ * Switches this component between `input` and `summary` display by updating its own state.
472
+ * With no argument it flips the current mode.
424
473
  */
425
- toggleDisplayMode(setTo: 'summary' | 'input'): void;
474
+ toggleDisplayMode(setTo?: 'summary' | 'input'): void;
426
475
  static ɵfac: i0.ɵɵFactoryDeclaration<NgsFormsBaseClassFormInputComponent<any>, never>;
427
476
  static ɵdir: i0.ɵɵDirectiveDeclaration<NgsFormsBaseClassFormInputComponent<any>, never, never, {}, {}, never, never, true, never>;
428
477
  }
@@ -453,7 +502,7 @@ declare class NgsFormsBaseClassFormItemInputWithOptionsComponent<T extends NgsFo
453
502
  * <ngs-form></ngs-form>
454
503
  * ```
455
504
  */
456
- declare class NgsFormComponent {
505
+ declare class NgsFormComponent implements OnDestroy {
457
506
  private readonly ngsInternalFormsService;
458
507
  readonly ngsFormsService: NgsFormsService;
459
508
  readonly formGroup: i0.Signal<_angular_forms.FormGroup<any> | undefined>;
@@ -464,6 +513,7 @@ declare class NgsFormComponent {
464
513
  root: _ng_simplicity_forms_core.NgsFormsFormItem<any>;
465
514
  }[]>;
466
515
  constructor();
516
+ ngOnDestroy(): void;
467
517
  static ɵfac: i0.ɵɵFactoryDeclaration<NgsFormComponent, never>;
468
518
  static ɵcmp: i0.ɵɵComponentDeclaration<NgsFormComponent, "ngs-form", never, {}, {}, never, never, true, never>;
469
519
  }
@@ -474,8 +524,18 @@ declare const NGS_FORMS_ITEM_DATA: InjectionToken<unknown>;
474
524
  * @internal
475
525
  */
476
526
  declare const NGS_FORMS_CONTROL_ADD_REMOVE_FN: InjectionToken<unknown>;
477
- /** Injection token for the row index when a component is rendered inside a form array list. */
478
- declare const NGS_FORMS_ITEM_INDEX: InjectionToken<unknown>;
527
+ /**
528
+ * Injection token for the row index when a component is rendered inside a form array list.
529
+ *
530
+ * @remarks This is the index the row had when the component was created. Rows before it can be removed later,
531
+ * so to find a row's current position use `NGS_FORMS_ARRAY_ROW` with `formArray.controls.indexOf(row)`.
532
+ */
533
+ declare const NGS_FORMS_ITEM_INDEX: InjectionToken<number>;
534
+ /**
535
+ * Injection token for the `UntypedFormGroup` of the form array row a component is rendered in. Unlike
536
+ * `NGS_FORMS_ITEM_INDEX`, it stays correct when earlier rows are removed.
537
+ */
538
+ declare const NGS_FORMS_ARRAY_ROW: InjectionToken<UntypedFormGroup>;
479
539
  type FormControlAddRemoveFn = (control: AbstractControl, controlName: string) => void;
480
540
  /**
481
541
  * @internal
@@ -539,12 +599,20 @@ declare class NgsFormItemController extends NgsSubscriber {
539
599
  private readonly addRemoveControlFn?;
540
600
  private readonly index?;
541
601
  private readonly changeDetectorRef?;
602
+ private readonly arrayRow?;
542
603
  private componentRef;
543
- private parentVisibility;
544
604
  private lastVisible;
545
- constructor(injector: Injector, viewContainerRef: ViewContainerRef, itemData: NgsFormsFormItem<any>, addRemoveControlFn?: INgsFormsFormControlAddRemove | undefined, index?: number | undefined, changeDetectorRef?: ChangeDetectorRef | undefined);
605
+ /** Incremented whenever a scheduled create becomes stale (hidden again, or destroyed). */
606
+ private createToken;
607
+ private destroyed;
608
+ constructor(injector: Injector, viewContainerRef: ViewContainerRef, itemData: NgsFormsFormItem<any>, addRemoveControlFn?: INgsFormsFormControlAddRemove | undefined, index?: number | undefined, changeDetectorRef?: ChangeDetectorRef | undefined, arrayRow?: UntypedFormGroup | undefined);
546
609
  destroy(): void;
547
610
  private bindVisibility;
611
+ /**
612
+ * Creates the component in a microtask. A create that is overtaken by a later visibility change or by
613
+ * `destroy()` before it runs is dropped.
614
+ */
615
+ private scheduleCreate;
548
616
  private create;
549
617
  private detach;
550
618
  }
@@ -555,7 +623,7 @@ declare class NgsFormItemController extends NgsSubscriber {
555
623
  * @remarks Use it inside custom container components to render child items:
556
624
  * `<ng-container [ngs-form-item]="item" [ngs-form-group]="group"></ng-container>`.
557
625
  */
558
- declare class NgsFormsFormItemDirective implements OnInit, OnDestroy {
626
+ declare class NgsFormsFormItemDirective implements OnInit, OnChanges, OnDestroy {
559
627
  /** The item to render. */
560
628
  itemData: NgsFormsFormItem<any> | undefined;
561
629
  /** Form group that the item's control is added to. */
@@ -563,7 +631,8 @@ declare class NgsFormsFormItemDirective implements OnInit, OnDestroy {
563
631
  /** Form array that the item's control is added to. */
564
632
  formArray?: UntypedFormArray;
565
633
  /**
566
- * Index of the item inside a form array row, provided to children as `NGS_FORMS_ITEM_INDEX`.
634
+ * Index of the item inside a form array row, provided to children as `NGS_FORMS_ITEM_INDEX`. When it is set, the
635
+ * `ngs-form-group` is also provided to children as `NGS_FORMS_ARRAY_ROW`.
567
636
  */
568
637
  index?: number;
569
638
  controller: NgsFormItemController | undefined;
@@ -571,7 +640,10 @@ declare class NgsFormsFormItemDirective implements OnInit, OnDestroy {
571
640
  private readonly injector;
572
641
  private readonly changeDetectorRef;
573
642
  private readonly formComponentRegistryService;
643
+ private initialized;
574
644
  ngOnInit(): void;
645
+ ngOnChanges(changes: SimpleChanges): void;
646
+ private build;
575
647
  ngOnDestroy(): void;
576
648
  static ɵfac: i0.ɵɵFactoryDeclaration<NgsFormsFormItemDirective, never>;
577
649
  static ɵdir: i0.ɵɵDirectiveDeclaration<NgsFormsFormItemDirective, "[ngs-form-item]", never, { "itemData": { "alias": "ngs-form-item"; "required": false; }; "formGroup": { "alias": "ngs-form-group"; "required": false; }; "formArray": { "alias": "ngs-form-array"; "required": false; }; "index": { "alias": "ngs-form-index"; "required": false; }; }, {}, never, never, true, never>;
@@ -639,7 +711,7 @@ declare class NgsFormsRowComponent extends NgsFormsBaseClassFormComponent<NgsFor
639
711
  * })
640
712
  * ```
641
713
  */
642
- declare class NgsFormsFormGroupComponent extends NgsFormsFormItemWithVisibleAndValidatorsBase<NgsFormsFormGroupConfig> implements OnInit {
714
+ declare class NgsFormsFormGroupComponent extends NgsFormsFormItemWithVisibleAndValidatorsBase<NgsFormsFormGroupConfig, UntypedFormGroup> implements OnInit {
643
715
  static key: string;
644
716
  /** Creates a `form-group` item. */
645
717
  static create(config: NgsFormsFormGroupConfig): NgsFormsFormItem<NgsFormsFormGroupConfig>;
@@ -663,13 +735,6 @@ interface NgsFormItemArrayAddItemConfig extends NgsFormsFormItemConfigBase {
663
735
  buttonClass?: string;
664
736
  /** Class of an `<i>` icon shown before the label, for example `bi bi-plus`. */
665
737
  buttonIcon?: string;
666
- /**
667
- * Callback after a row is added.
668
- *
669
- * @notImplemented
670
- * @remarks Reserved for future use.
671
- */
672
- onAddItem?: () => void;
673
738
  }
674
739
 
675
740
  /** Configuration for `NgsFormsFormArrayContainerComponent`. */
@@ -699,7 +764,7 @@ interface NgsFormItemArrayConfig extends NgsFormsFormItemConfigBaseItemWithNameA
699
764
  * @remarks Registry key: `form-array`. Put an `NgsFormsFormArrayListComponent` inside `items` to render the rows,
700
765
  * and `NgsFormsFormArrayAddItemComponent` / `NgsFormsFormArrayRemoveItemComponent` to let users change them.
701
766
  */
702
- declare class NgsFormsFormArrayContainerComponent extends NgsFormsFormItemWithVisibleAndValidatorsBase<NgsFormItemArrayConfig> {
767
+ declare class NgsFormsFormArrayContainerComponent extends NgsFormsFormItemWithVisibleAndValidatorsBase<NgsFormItemArrayConfig, UntypedFormArray> {
703
768
  private formArrayService;
704
769
  static key: string;
705
770
  constructor(formArrayService: NgsFormsFormArrayInternalService);
@@ -719,6 +784,8 @@ declare class NgsFormsFormArrayInternalService implements OnDestroy {
719
784
  readonly formArray: UntypedFormArray;
720
785
  /** Emits after a row is added or removed. */
721
786
  readonly itemsChanged: Subject<void>;
787
+ /** Emits the index of a row right after it is removed. */
788
+ readonly rowRemoved: Subject<number>;
722
789
  constructor();
723
790
  ngOnDestroy(): void;
724
791
  /** Removes the row at `index`, unless that would go below `minItems`. */
@@ -763,7 +830,14 @@ declare class NgsFormsFormArrayListComponent extends NgsFormsBaseClassFormCompon
763
830
  internalArrayService: NgsFormsFormArrayInternalService;
764
831
  myFormArray: FormArray<any>;
765
832
  private changeDetectorRef;
833
+ private elementRef;
834
+ private injector;
766
835
  ngOnInit(): void;
836
+ /**
837
+ * When the focused element (usually the row's Remove button) was removed with its row, moves focus to the
838
+ * same kind of control in the row that took its place, so keyboard users are not sent back to the top of the page.
839
+ */
840
+ private restoreFocusAfterRemove;
767
841
  /** Creates a `form-array-list` item. */
768
842
  static create(config: NgsFormsFormArrayListConfig): NgsFormsFormItem<NgsFormsFormArrayListConfig>;
769
843
  castToFormGroup(control: AbstractControl): UntypedFormGroup;
@@ -786,12 +860,11 @@ interface NgsFormItemArrayRemoveItemConfig extends NgsFormsFormItemConfigBase {
786
860
  /** Class of an `<i>` icon shown before the label, for example `bi bi-trash`. */
787
861
  buttonIcon?: string;
788
862
  /**
789
- * Callback after a row is removed.
790
- *
791
- * @notImplemented
792
- * @remarks Reserved for future use.
863
+ * Accessible name of the button, so screen reader users can tell the rows' buttons apart. A function receives
864
+ * the row's zero-based index.
865
+ * @defaultValue `${buttonText} item ${index + 1}`, for example `Remove item 2`
793
866
  */
794
- onRemoveItem?: () => void;
867
+ ariaLabel?: string | ((index: number) => string);
795
868
  }
796
869
 
797
870
  /**
@@ -800,14 +873,19 @@ interface NgsFormItemArrayRemoveItemConfig extends NgsFormsFormItemConfigBase {
800
873
  * @remarks Registry key: `form-array-remove-item`. Place it inside the `templateItem` of an
801
874
  * `NgsFormsFormArrayListComponent` so each row gets one.
802
875
  */
803
- declare class NgsFormsFormArrayRemoveItemComponent extends NgsFormsBaseClassFormComponent<NgsFormItemArrayRemoveItemConfig> {
876
+ declare class NgsFormsFormArrayRemoveItemComponent extends NgsFormsBaseClassFormComponent<NgsFormItemArrayRemoveItemConfig> implements OnInit {
804
877
  static key: string;
805
878
  internalArrayService: NgsFormsFormArrayInternalService;
806
879
  private elementRef;
807
880
  private indexFromDi;
808
- /** Index of the row this button belongs to. */
881
+ private row;
882
+ private changeDetectorRef;
883
+ /** Accessible name of the button, from `ariaLabel` or `${buttonText} item ${index + 1}`. */
884
+ get ariaLabel(): string;
885
+ /** Current index of the row this button belongs to. */
809
886
  get myIndex(): number;
810
887
  constructor();
888
+ ngOnInit(): void;
811
889
  /** Creates a `form-array-remove-item` item. */
812
890
  static create(config: NgsFormItemArrayRemoveItemConfig): NgsFormsFormItem<NgsFormItemArrayRemoveItemConfig>;
813
891
  removeItem(): void;
@@ -862,22 +940,43 @@ declare class NgsFormsHtmlContentComponent extends NgsFormsBaseClassFormComponen
862
940
  static ɵcmp: i0.ɵɵComponentDeclaration<NgsFormsHtmlContentComponent, "ngs-form-component-html-content", never, {}, {}, never, never, true, never>;
863
941
  }
864
942
 
943
+ /** Configuration for `NgsFormsFormSectionComponent`. */
865
944
  interface NgsFormsFormSectionConfig extends NgsFormsFormItemContainerConfigBase {
945
+ /** Section heading. It also names the section's group for assistive technology. */
866
946
  title: string;
947
+ /**
948
+ * Class of the title.
949
+ * @defaultValue 'h3'
950
+ */
867
951
  titleClass?: string;
952
+ /**
953
+ * Heading level (1 to 6) that assistive technology announces for the title.
954
+ * @defaultValue 3
955
+ */
956
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
957
+ /** Text shown under the title. */
868
958
  subtitle?: string;
959
+ /**
960
+ * Class of the subtitle.
961
+ * @defaultValue 'lead'
962
+ */
869
963
  subtitleClass?: string;
870
964
  }
965
+ /** @internal */
966
+ declare const sectionConfigDefaults: Partial<NgsFormsFormSectionConfig>;
871
967
 
872
968
  /**
873
969
  * Groups items under a title and optional subtitle. Does not create a form control, so child values stay in the
874
970
  * parent group.
875
971
  *
876
972
  * @remarks Registry key: `section`. Config: `title`, `subtitle`, `titleClass` (default `h3`),
877
- * `subtitleClass` (default `lead`) and `items`.
973
+ * `headingLevel` (default 3), `subtitleClass` (default `lead`) and `items`. The section is exposed to assistive
974
+ * technology as a group named by its title.
878
975
  */
879
976
  declare class NgsFormsFormSectionComponent extends NgsFormsBaseClassItemsContainerBase<NgsFormsFormSectionConfig> implements OnInit {
880
977
  static key: string;
978
+ /** Element id of the title, used to name the section's group. */
979
+ readonly titleId: string;
881
980
  /** Creates a `section` item. */
882
981
  static create(config: NgsFormsFormSectionConfig): NgsFormsFormItem<NgsFormsFormSectionConfig>;
883
982
  ngOnInit(): void;
@@ -899,5 +998,5 @@ declare class NgsFormsCoreModule {
899
998
  static ɵinj: i0.ɵɵInjectorDeclaration<NgsFormsCoreModule>;
900
999
  }
901
1000
 
902
- export { NGS_FORMS_CONTROL_ADD_REMOVE_FN, NGS_FORMS_ITEM_DATA, NGS_FORMS_ITEM_INDEX, NgsFormComponent, NgsFormsBaseClassFormComponent, NgsFormsBaseClassFormInputComponent, NgsFormsBaseClassFormItemInputWithOptionsComponent, NgsFormsBaseClassItemsContainerBase, NgsFormsColumnComponent, NgsFormsComponentRegistryService, NgsFormsCoreModule, NgsFormsFormArrayAddItemComponent, NgsFormsFormArrayContainerComponent, NgsFormsFormArrayInternalService, NgsFormsFormArrayListComponent, NgsFormsFormArrayRemoveItemComponent, NgsFormsFormControlAddRemoveFunctions, NgsFormsFormGroupComponent, NgsFormsFormItemDirective, NgsFormsFormItemWithVisibleAndValidatorsBase, NgsFormsFormSectionComponent, NgsFormsHtmlContentComponent, NgsFormsInternalService, NgsFormsRowComponent, NgsFormsService, NgsFormsTextDivComponent, NgsSubscriber, ngsDefaults };
903
- export type { INgsFormsFormControlAddRemove, NgsFormDisableFn, NgsFormItemArrayAddItemConfig, NgsFormItemArrayConfig, NgsFormItemArrayRemoveItemConfig, NgsFormItemHtmlContentConfig, NgsFormItemRowConfig, NgsFormItemVisibilityFn, NgsFormValidatorArrayBuilderFn, NgsFormsFormArrayListConfig, NgsFormsFormConfig, NgsFormsFormErrorKeyValueMap, NgsFormsFormGroupConfig, NgsFormsFormInputOption, NgsFormsFormItem, NgsFormsFormItemConfigBase, NgsFormsFormItemConfigBaseInput, NgsFormsFormItemConfigBaseInputWithOptions, NgsFormsFormItemConfigBaseItemWithNameAndValidators, NgsFormsFormItemConfigBaseTextInput, NgsFormsFormItemContainerConfigBase, NgsFormsFunctionParameters, NgsServerSideValidationErrorObjectType };
1001
+ export { NGS_FORMS_ARRAY_ROW, NGS_FORMS_CONTROL_ADD_REMOVE_FN, NGS_FORMS_ITEM_DATA, NGS_FORMS_ITEM_INDEX, NgsFormComponent, NgsFormsBaseClassFormComponent, NgsFormsBaseClassFormInputComponent, NgsFormsBaseClassFormItemInputWithOptionsComponent, NgsFormsBaseClassItemsContainerBase, NgsFormsColumnComponent, NgsFormsComponentRegistryService, NgsFormsCoreModule, NgsFormsFormArrayAddItemComponent, NgsFormsFormArrayContainerComponent, NgsFormsFormArrayInternalService, NgsFormsFormArrayListComponent, NgsFormsFormArrayRemoveItemComponent, NgsFormsFormControlAddRemoveFunctions, NgsFormsFormGroupComponent, NgsFormsFormItemDirective, NgsFormsFormItemWithVisibleAndValidatorsBase, NgsFormsFormSectionComponent, NgsFormsHtmlContentComponent, NgsFormsInternalService, NgsFormsRowComponent, NgsFormsService, NgsFormsTextDivComponent, NgsSubscriber, ngsDefaults, sectionConfigDefaults };
1002
+ export type { INgsFormsFormControlAddRemove, NgsFormDisableFn, NgsFormItemArrayAddItemConfig, NgsFormItemArrayConfig, NgsFormItemArrayRemoveItemConfig, NgsFormItemHtmlContentConfig, NgsFormItemRowConfig, NgsFormItemVisibilityFn, NgsFormValidatorArrayBuilderFn, NgsFormsCommonComponentState, NgsFormsFormArrayListConfig, NgsFormsFormConfig, NgsFormsFormErrorKeyValueMap, NgsFormsFormGroupConfig, NgsFormsFormInputOption, NgsFormsFormItem, NgsFormsFormItemConfigBase, NgsFormsFormItemConfigBaseInput, NgsFormsFormItemConfigBaseInputWithOptions, NgsFormsFormItemConfigBaseItemWithNameAndValidators, NgsFormsFormItemConfigBaseTextInput, NgsFormsFormItemContainerConfigBase, NgsFormsFormSectionConfig, NgsFormsFunctionParameters, NgsFormsGlobalFormState, NgsFormsTextDivConfig, NgsServerSideValidationErrorObjectType };
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@ng-simplicity/forms-core",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/BryanGWalsh/NgSimplicityForms.git",
8
8
  "directory": "libs/forms-core"
9
9
  },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
10
13
  "peerDependencies": {
11
14
  "@angular/common": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
12
15
  "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",