@neuravision/ng-construct 0.4.2 → 0.5.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.
@@ -1,8 +1,23 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { ElementRef, TemplateRef, OnDestroy, AfterViewInit, Signal, AfterContentInit, AfterContentChecked, PipeTransform } from '@angular/core';
3
- import { ControlValueAccessor } from '@angular/forms';
2
+ import { InjectionToken, ElementRef, TemplateRef, OnDestroy, AfterViewInit, Signal, AfterContentInit, AfterContentChecked, PipeTransform } from '@angular/core';
3
+ import * as _neuravision_ng_construct from '@neuravision/ng-construct';
4
+ import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
4
5
 
5
6
  type AfAlertVariant = 'info' | 'success' | 'warning' | 'danger';
7
+ /** Translatable strings used by the alert component. */
8
+ interface AfAlertI18n {
9
+ /** Label for the dismiss button (default: `'Dismiss alert'`). */
10
+ dismiss: string;
11
+ /** Screen-reader announcement when the alert is dismissed (default: `'Alert dismissed'`). */
12
+ dismissed: string;
13
+ }
14
+ /**
15
+ * Injection token to provide custom i18n strings for {@link AfAlertComponent}.
16
+ *
17
+ * @example
18
+ * providers: [{ provide: AF_ALERT_I18N, useValue: { dismiss: 'Schliessen', dismissed: 'Warnung geschlossen' } }]
19
+ */
20
+ declare const AF_ALERT_I18N: InjectionToken<AfAlertI18n>;
6
21
  /**
7
22
  * Alert component for displaying contextual feedback messages.
8
23
  *
@@ -10,6 +25,14 @@ type AfAlertVariant = 'info' | 'success' | 'warning' | 'danger';
10
25
  * - `danger` / `warning` → `role="alert"` (assertive announcement)
11
26
  * - `info` / `success` → `role="status"` (polite announcement)
12
27
  *
28
+ * ### Accessibility
29
+ * - The dismiss button is keyboard-accessible via Tab, activated by Enter/Space (native `<button>`)
30
+ * - When dismissed, a screen-reader announcement is made via an `aria-live="polite"` region
31
+ * - The icon slot is marked `aria-hidden="true"` to prevent redundant announcements
32
+ * - The `aria-label` on the dismiss button is configurable via {@link AF_ALERT_I18N} for i18n
33
+ * - Supports `forced-colors` (Windows High Contrast) mode
34
+ * - Uses CSS logical properties for RTL layout support
35
+ *
13
36
  * @example
14
37
  * <af-alert variant="warning" [dismissible]="true" (dismissed)="onDismiss()">
15
38
  * <span icon>⚠</span>
@@ -21,14 +44,17 @@ type AfAlertVariant = 'info' | 'success' | 'warning' | 'danger';
21
44
  * </af-alert>
22
45
  */
23
46
  declare class AfAlertComponent {
24
- /** Color variant determining the alert's visual style and ARIA role */
47
+ protected readonly i18n: AfAlertI18n;
48
+ /** Color variant determining the alert's visual style and ARIA role. */
25
49
  variant: _angular_core.InputSignal<AfAlertVariant>;
26
- /** Whether the alert can be dismissed by the user */
50
+ /** Whether the alert can be dismissed by the user. */
27
51
  dismissible: _angular_core.InputSignal<boolean>;
28
- /** Emits when the user dismisses the alert */
52
+ /** Emits when the user dismisses the alert. */
29
53
  dismissed: _angular_core.OutputEmitterRef<void>;
30
- /** Controls alert visibility */
54
+ /** Controls alert visibility. */
31
55
  visible: _angular_core.WritableSignal<boolean>;
56
+ /** @internal Screen-reader announcement text. */
57
+ liveAnnouncement: _angular_core.WritableSignal<string>;
32
58
  alertClasses: _angular_core.Signal<string>;
33
59
  /**
34
60
  * Maps variant to ARIA role:
@@ -36,12 +62,50 @@ declare class AfAlertComponent {
36
62
  * - info/success → 'status' (polite, non-intrusive announcement)
37
63
  */
38
64
  alertRole: _angular_core.Signal<"alert" | "status">;
39
- /** Hides the alert and emits the dismissed event */
65
+ /** Hides the alert and emits the dismissed event. */
40
66
  dismiss(): void;
41
67
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AfAlertComponent, never>;
42
68
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfAlertComponent, "af-alert", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "dismissible": { "alias": "dismissible"; "required": false; "isSignal": true; }; }, { "dismissed": "dismissed"; }, never, ["[icon]", "[title]", "*", "[actions]"], true, never>;
43
69
  }
44
70
 
71
+ /**
72
+ * Test harness for AfAlertComponent.
73
+ *
74
+ * Provides a semantic API for interacting with the alert in tests,
75
+ * abstracting DOM details behind readable method names.
76
+ *
77
+ * @example
78
+ * const harness = new AfAlertHarness(fixture.nativeElement);
79
+ * expect(harness.getVariant()).toBe('info');
80
+ * expect(harness.getRole()).toBe('status');
81
+ * harness.dismiss();
82
+ */
83
+ declare class AfAlertHarness {
84
+ private readonly hostEl;
85
+ constructor(container: HTMLElement);
86
+ /** Returns the inner `.ct-alert` wrapper element, or `null` if the alert is not visible. */
87
+ getAlertElement(): HTMLElement | null;
88
+ /** Returns the `data-variant` attribute value. Throws if the alert is not visible. */
89
+ getVariant(): string;
90
+ /** Returns the ARIA `role` attribute value. Throws if the alert is not visible. */
91
+ getRole(): string;
92
+ /** Returns the full trimmed text content of the alert. Throws if not visible. */
93
+ getText(): string;
94
+ /** Returns the trimmed text content of the title slot. Throws if not visible. */
95
+ getTitle(): string;
96
+ /** Returns whether the alert is currently visible in the DOM. */
97
+ isVisible(): boolean;
98
+ /** Returns whether the alert has a dismiss button. Throws if not visible. */
99
+ isDismissible(): boolean;
100
+ /** Clicks the dismiss button. Throws if the alert is not visible or not dismissible. */
101
+ dismiss(): void;
102
+ /** Returns the dismiss button element, or `null` if not present. */
103
+ getDismissButton(): HTMLButtonElement | null;
104
+ /** Returns the `aria-live` region element for screen-reader announcements. */
105
+ getLiveRegion(): HTMLElement | null;
106
+ private requireVisible;
107
+ }
108
+
45
109
  /**
46
110
  * Individual accordion item used within af-accordion.
47
111
  *
@@ -53,6 +117,8 @@ declare class AfAlertComponent {
53
117
  declare class AfAccordionItemComponent {
54
118
  private itemId;
55
119
  private accordion;
120
+ private announcer;
121
+ private i18n;
56
122
  /** Heading text displayed in the accordion trigger. */
57
123
  heading: _angular_core.InputSignal<string>;
58
124
  /** Whether this item is expanded (supports two-way binding). */
@@ -109,6 +175,69 @@ declare class AfAccordionComponent {
109
175
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfAccordionComponent, "af-accordion", never, { "multi": { "alias": "multi"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; }, {}, ["items"], ["*"], true, never>;
110
176
  }
111
177
 
178
+ /**
179
+ * Test harness for AfAccordionItemComponent.
180
+ *
181
+ * Provides a semantic API for interacting with a single accordion item,
182
+ * abstracting DOM details behind readable method names.
183
+ */
184
+ declare class AfAccordionItemHarness {
185
+ private readonly hostEl;
186
+ constructor(hostEl: HTMLElement);
187
+ /** Returns the heading text. */
188
+ getHeading(): string;
189
+ /** Returns whether the item is expanded. */
190
+ isExpanded(): boolean;
191
+ /** Returns whether the item is disabled. */
192
+ isDisabled(): boolean;
193
+ /** Clicks the trigger to toggle the item. */
194
+ toggle(): void;
195
+ /** Returns the trigger (summary) element. */
196
+ getTriggerElement(): HTMLElement;
197
+ /** Returns the content panel element. */
198
+ getContentElement(): HTMLElement;
199
+ /** Returns the `aria-controls` value of the trigger. */
200
+ getAriaControls(): string | null;
201
+ /** Returns the `aria-expanded` value of the trigger. */
202
+ getAriaExpanded(): string | null;
203
+ }
204
+ /**
205
+ * Test harness for AfAccordionComponent.
206
+ *
207
+ * @example
208
+ * const harness = new AfAccordionHarness(fixture.nativeElement);
209
+ * expect(harness.getItems()).toHaveLength(3);
210
+ * harness.getItem(0).toggle();
211
+ */
212
+ declare class AfAccordionHarness {
213
+ private readonly hostEl;
214
+ constructor(container: HTMLElement);
215
+ /** Returns harnesses for all accordion items. */
216
+ getItems(): AfAccordionItemHarness[];
217
+ /** Returns the harness for the accordion item at the given index. */
218
+ getItem(index: number): AfAccordionItemHarness;
219
+ /** Returns whether the bordered variant is applied. */
220
+ isBordered(): boolean;
221
+ }
222
+
223
+ /** Translatable strings used by the accordion component. */
224
+ interface AfAccordionI18n {
225
+ /** Announcement when a section is expanded. Use `{heading}` as placeholder. */
226
+ expanded: string;
227
+ /** Announcement when a section is collapsed. Use `{heading}` as placeholder. */
228
+ collapsed: string;
229
+ }
230
+ /**
231
+ * Injection token to override accordion screen-reader announcements.
232
+ *
233
+ * @example
234
+ * providers: [{
235
+ * provide: AF_ACCORDION_I18N,
236
+ * useValue: { expanded: '{heading} ausgeklappt', collapsed: '{heading} eingeklappt' },
237
+ * }]
238
+ */
239
+ declare const AF_ACCORDION_I18N: InjectionToken<AfAccordionI18n>;
240
+
112
241
  type AfShellSidebarState = 'expanded' | 'collapsed' | 'hidden';
113
242
  type AfShellPanelState = 'open' | 'closed';
114
243
  /**
@@ -324,15 +453,37 @@ type AfButtonVariant = 'primary' | 'secondary' | 'ghost' | 'outline' | 'danger'
324
453
  type AfButtonSize = 'sm' | 'md' | 'lg';
325
454
  type AfButtonType = 'button' | 'submit' | 'reset';
326
455
  /**
327
- * Button component from the Construct Design System
456
+ * Button component from the Construct Design System.
328
457
  *
329
- * @example
330
- * <af-button variant="primary" (clicked)="handleClick()">Click me</af-button>
458
+ * Wraps a native `<button>` element with design system tokens and
459
+ * variant/size modifiers.
331
460
  *
332
- * @example Icon-only button
461
+ * @example Basic usage
462
+ * <af-button variant="primary" (clicked)="save()">Save</af-button>
463
+ *
464
+ * @example Variants
465
+ * <af-button variant="secondary">Secondary</af-button>
466
+ * <af-button variant="ghost">Ghost</af-button>
467
+ * <af-button variant="outline">Outline</af-button>
468
+ * <af-button variant="danger">Danger</af-button>
469
+ * <af-button variant="accent">Accent</af-button>
470
+ * <af-button variant="link">Link</af-button>
471
+ *
472
+ * @example Icon-only button (ariaLabel required)
333
473
  * <af-button variant="ghost" size="sm" iconOnly ariaLabel="Delete item">
334
474
  * <af-icon name="delete" />
335
475
  * </af-button>
476
+ *
477
+ * @example Disabled button
478
+ * <af-button [disabled]="true">Cannot click</af-button>
479
+ *
480
+ * @accessibility
481
+ * - Uses native `<button>` element — keyboard (Enter/Space) and screen reader support built-in.
482
+ * - Disabled state uses the native `disabled` attribute.
483
+ * - Icon-only buttons must provide `ariaLabel` for screen reader users.
484
+ * A dev-mode warning is emitted if `ariaLabel` is missing on an icon-only button.
485
+ * - Focus indicator: 2px outline via `:focus-visible` (design system CSS).
486
+ * - Reduced motion: `transform` animation disabled via `prefers-reduced-motion`.
336
487
  */
337
488
  declare class AfButtonComponent {
338
489
  /** Button variant/style */
@@ -352,14 +503,53 @@ declare class AfButtonComponent {
352
503
  /** Click event emitter */
353
504
  clicked: _angular_core.OutputEmitterRef<MouseEvent>;
354
505
  buttonClasses: _angular_core.Signal<string>;
506
+ private readonly iconOnlyWarning;
355
507
  handleClick(event: MouseEvent): void;
356
508
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AfButtonComponent, never>;
357
509
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfButtonComponent, "af-button", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; }, { "clicked": "clicked"; }, never, ["*"], true, never>;
358
510
  }
359
511
 
512
+ /**
513
+ * Test harness for AfButtonComponent.
514
+ *
515
+ * Provides a semantic API for interacting with the button in tests,
516
+ * abstracting DOM details behind readable method names.
517
+ *
518
+ * @example
519
+ * const harness = new AfButtonHarness(fixture.nativeElement);
520
+ * expect(harness.getText()).toBe('Save');
521
+ * expect(harness.isDisabled()).toBe(false);
522
+ * harness.click();
523
+ */
524
+ declare class AfButtonHarness {
525
+ private readonly hostEl;
526
+ constructor(container: HTMLElement);
527
+ /** Returns the inner native `<button>` element. */
528
+ getButtonElement(): HTMLButtonElement;
529
+ /** Returns the trimmed text content of the button. */
530
+ getText(): string;
531
+ /** Returns whether the button is disabled. */
532
+ isDisabled(): boolean;
533
+ /** Clicks the inner button element. */
534
+ click(): void;
535
+ /** Returns the `aria-label` attribute value, or `null` if absent. */
536
+ getAriaLabel(): string | null;
537
+ /** Returns the `title` attribute value, or `null` if absent. */
538
+ getTitle(): string | null;
539
+ /** Returns the `type` attribute of the button. */
540
+ getType(): string;
541
+ /** Returns the full `class` attribute string of the inner button. */
542
+ getClasses(): string;
543
+ /** Returns whether the inner button has the given CSS class. */
544
+ hasClass(className: string): boolean;
545
+ }
546
+
360
547
  type AfInputType = 'text' | 'email' | 'password' | 'number' | 'search' | 'tel' | 'url';
361
548
  /**
362
- * Input field component with form control support
549
+ * Input field component with form control support.
550
+ *
551
+ * Wraps a native `<input>` element with label, hint, error, and icon slots.
552
+ * Implements `ControlValueAccessor` for seamless `ngModel` and `formControl` integration.
363
553
  *
364
554
  * @example
365
555
  * <af-input
@@ -368,52 +558,132 @@ type AfInputType = 'text' | 'email' | 'password' | 'number' | 'search' | 'tel' |
368
558
  * placeholder="name@company.com"
369
559
  * [(ngModel)]="email"
370
560
  * hint="We will not share this."
371
- * ></af-input>
561
+ * />
372
562
  *
373
563
  * @example
374
564
  * <af-input
375
565
  * label="Name"
376
566
  * [error]="nameError"
377
567
  * required
378
- * ></af-input>
568
+ * />
379
569
  */
380
570
  declare class AfInputComponent implements ControlValueAccessor {
381
571
  private static nextId;
382
- /** Input label */
572
+ readonly i18n: _neuravision_ng_construct.AfInputI18n;
573
+ /** Input label. */
383
574
  label: _angular_core.InputSignal<string>;
384
- /** Input type */
575
+ /** Input type. */
385
576
  type: _angular_core.InputSignal<AfInputType>;
386
- /** Placeholder text */
577
+ /** Placeholder text. */
387
578
  placeholder: _angular_core.InputSignal<string>;
388
- /** Hint text shown below input */
579
+ /** Hint text shown below input. */
389
580
  hint: _angular_core.InputSignal<string>;
390
- /** Error message - shows error state and message */
581
+ /** Error message shows error state and message. */
391
582
  error: _angular_core.InputSignal<string>;
392
- /** Whether input is required */
393
- required: _angular_core.InputSignal<boolean>;
394
- /** Whether input is disabled */
583
+ /** Whether input is required. */
584
+ required: _angular_core.InputSignalWithTransform<boolean, unknown>;
585
+ /** Whether input is disabled. */
395
586
  disabled: _angular_core.ModelSignal<boolean>;
396
- /** Icon position (if icon content is projected) */
587
+ /** Icon position (if icon content is projected). */
397
588
  iconPosition: _angular_core.InputSignal<"left" | "right" | null>;
398
- /** Unique input ID */
589
+ /** Unique input ID. */
399
590
  inputId: _angular_core.InputSignal<string>;
400
- value: string;
591
+ /** @docs-private — internal form value managed by CVA. */
592
+ readonly value: _angular_core.WritableSignal<string>;
401
593
  onChange: (value: string) => void;
402
594
  onTouched: () => void;
595
+ /** Computed hint element ID. */
403
596
  hintId: _angular_core.Signal<string>;
597
+ /** Computed error element ID. */
404
598
  errorId: _angular_core.Signal<string>;
599
+ /** Computed CSS classes for the inner input. */
405
600
  inputClasses: _angular_core.Signal<string>;
406
- getAriaDescribedBy(): string | null;
601
+ /** Computed `aria-describedby` value linking to hint or error. */
602
+ ariaDescribedBy: _angular_core.Signal<string | null>;
407
603
  onInput(event: Event): void;
408
- /** ControlValueAccessor implementation */
604
+ /** @docs-private */
409
605
  writeValue(value: string): void;
606
+ /** @docs-private */
410
607
  registerOnChange(fn: (value: string) => void): void;
608
+ /** @docs-private */
411
609
  registerOnTouched(fn: () => void): void;
610
+ /** @docs-private */
412
611
  setDisabledState(isDisabled: boolean): void;
413
612
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AfInputComponent, never>;
414
613
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfInputComponent, "af-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; }, never, ["[icon]", "[icon]"], true, never>;
415
614
  }
416
615
 
616
+ /**
617
+ * Test harness for AfInputComponent.
618
+ *
619
+ * Provides a semantic API for interacting with the input in tests,
620
+ * abstracting DOM details behind readable method names.
621
+ *
622
+ * @example
623
+ * const harness = new AfInputHarness(fixture.nativeElement);
624
+ * expect(harness.getValue()).toBe('');
625
+ * harness.setValue('hello');
626
+ * expect(harness.getValue()).toBe('hello');
627
+ */
628
+ declare class AfInputHarness {
629
+ private readonly hostEl;
630
+ constructor(container: HTMLElement);
631
+ /** Returns the inner native `<input>` element. */
632
+ getInputElement(): HTMLInputElement;
633
+ /** Returns the current value of the input. */
634
+ getValue(): string;
635
+ /** Sets the input value and dispatches an `input` event. */
636
+ setValue(value: string): void;
637
+ /** Returns the label text, or `null` if no label is rendered. */
638
+ getLabel(): string | null;
639
+ /** Returns the hint text, or `null` if no hint is rendered. */
640
+ getHint(): string | null;
641
+ /** Returns the error text, or `null` if no error is rendered. */
642
+ getError(): string | null;
643
+ /** Returns whether the input is disabled. */
644
+ isDisabled(): boolean;
645
+ /** Returns whether the input is required. */
646
+ isRequired(): boolean;
647
+ /** Returns whether `aria-invalid` is set to `"true"`. */
648
+ isInvalid(): boolean;
649
+ /** Returns the `type` attribute of the input. */
650
+ getType(): string;
651
+ /** Returns the `placeholder` attribute of the input. */
652
+ getPlaceholder(): string;
653
+ /** Returns the `aria-describedby` attribute value, or `null` if absent. */
654
+ getAriaDescribedBy(): string | null;
655
+ /** Focuses the input element. */
656
+ focus(): void;
657
+ /** Blurs the input element and dispatches a `blur` event. */
658
+ blur(): void;
659
+ /** Returns the `id` attribute of the input. */
660
+ getId(): string;
661
+ /** Returns whether the field wrapper has the error modifier class. */
662
+ hasFieldError(): boolean;
663
+ /** Returns whether an icon wrapper is rendered. */
664
+ hasIcon(): boolean;
665
+ /** Returns the full `class` attribute string of the inner input. */
666
+ getClasses(): string;
667
+ /** Returns whether the inner input has the given CSS class. */
668
+ hasClass(className: string): boolean;
669
+ }
670
+
671
+ /** Translatable strings used by the input component. */
672
+ interface AfInputI18n {
673
+ /** Screen-reader label for the required indicator. */
674
+ required: string;
675
+ }
676
+ /**
677
+ * Injection token to override input screen-reader announcements.
678
+ *
679
+ * @example
680
+ * providers: [{
681
+ * provide: AF_INPUT_I18N,
682
+ * useValue: { required: 'Pflichtfeld' },
683
+ * }]
684
+ */
685
+ declare const AF_INPUT_I18N: InjectionToken<AfInputI18n>;
686
+
417
687
  interface AfSelectOption {
418
688
  value: unknown;
419
689
  label: string;
@@ -1149,77 +1419,226 @@ declare class AfBreadcrumbsComponent {
1149
1419
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfBreadcrumbsComponent, "af-breadcrumbs", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1150
1420
  }
1151
1421
 
1422
+ /** Supported calendar views */
1423
+ type AfDatepickerView = 'days' | 'months' | 'years';
1424
+ /** Selection mode */
1425
+ type AfDatepickerMode = 'single' | 'range';
1426
+ /** Value format emitted by ControlValueAccessor */
1427
+ type AfDatepickerValueFormat = 'date' | 'iso';
1428
+ /** Date range value for range mode */
1429
+ interface AfDateRange {
1430
+ start: Date | null;
1431
+ end: Date | null;
1432
+ }
1152
1433
  interface CalendarDay {
1153
1434
  date: Date;
1154
1435
  isCurrentMonth: boolean;
1155
1436
  isToday: boolean;
1156
1437
  isSelected: boolean;
1438
+ isDisabled: boolean;
1439
+ isUnavailable: boolean;
1440
+ isInRange: boolean;
1441
+ isRangeStart: boolean;
1442
+ isRangeEnd: boolean;
1443
+ }
1444
+ interface MonthItem {
1445
+ index: number;
1446
+ label: string;
1447
+ shortLabel: string;
1448
+ isSelected: boolean;
1449
+ isDisabled: boolean;
1450
+ }
1451
+ interface YearItem {
1452
+ value: number;
1453
+ isSelected: boolean;
1454
+ isDisabled: boolean;
1157
1455
  }
1158
1456
  /**
1159
- * Datepicker component with calendar popup
1457
+ * Datepicker component with calendar popup, month/year views, range selection,
1458
+ * min/max constraints, disabled dates, and full keyboard navigation.
1459
+ *
1460
+ * Implements WAI-ARIA Date Picker Dialog pattern with roving tabindex.
1160
1461
  *
1161
1462
  * @example
1162
1463
  * <af-datepicker
1163
- * label="Select date"
1464
+ * label="Start date"
1164
1465
  * placeholder="Pick a date"
1165
- * [(ngModel)]="selectedDate">
1166
- * </af-datepicker>
1466
+ * [(ngModel)]="selectedDate"
1467
+ * [min]="minDate"
1468
+ * [max]="maxDate"
1469
+ * hint="Choose a date within the project timeline"
1470
+ * />
1471
+ *
1472
+ * @example
1473
+ * <af-datepicker
1474
+ * label="Period"
1475
+ * mode="range"
1476
+ * [(ngModel)]="dateRange"
1477
+ * valueFormat="iso"
1478
+ * />
1167
1479
  */
1168
- declare class AfDatepickerComponent implements ControlValueAccessor {
1480
+ declare class AfDatepickerComponent implements ControlValueAccessor, Validator {
1169
1481
  private static nextId;
1170
- /** Input label */
1482
+ /** Field label */
1171
1483
  label: _angular_core.InputSignal<string>;
1172
- /** Placeholder text */
1484
+ /** Input placeholder text */
1173
1485
  placeholder: _angular_core.InputSignal<string>;
1174
- /** Whether datepicker is disabled */
1486
+ /** Whether the datepicker is disabled */
1175
1487
  disabled: _angular_core.ModelSignal<boolean>;
1176
- /** Date format for display */
1488
+ /** Display format for the selected date */
1177
1489
  dateFormat: _angular_core.InputSignal<string>;
1178
- /** Unique input ID */
1490
+ /** Unique ID for the input element */
1179
1491
  inputId: _angular_core.InputSignal<string>;
1180
- /** Selected date change event */
1492
+ /** Minimum selectable date */
1493
+ min: _angular_core.InputSignal<string | Date | null>;
1494
+ /** Maximum selectable date */
1495
+ max: _angular_core.InputSignal<string | Date | null>;
1496
+ /** Array of specific dates that cannot be selected */
1497
+ disabledDates: _angular_core.InputSignal<Date[]>;
1498
+ /**
1499
+ * Predicate function to determine if a date is selectable.
1500
+ * Return `true` to allow selection, `false` to disable.
1501
+ */
1502
+ dateFilter: _angular_core.InputSignal<((date: Date) => boolean) | null>;
1503
+ /** Hint text displayed below the input */
1504
+ hint: _angular_core.InputSignal<string>;
1505
+ /** Error message — displays error state and message */
1506
+ error: _angular_core.InputSignal<string>;
1507
+ /** Whether the field is required */
1508
+ required: _angular_core.InputSignal<boolean>;
1509
+ /** Selection mode: single date or date range */
1510
+ mode: _angular_core.InputSignal<AfDatepickerMode>;
1511
+ /**
1512
+ * Value format for ControlValueAccessor.
1513
+ * `'date'` emits `Date` objects, `'iso'` emits ISO date strings (`yyyy-MM-dd`).
1514
+ */
1515
+ valueFormat: _angular_core.InputSignal<AfDatepickerValueFormat>;
1516
+ /** Emitted when a single date is selected */
1181
1517
  dateChange: _angular_core.OutputEmitterRef<Date>;
1518
+ /** Emitted when a date range is selected (range mode only) */
1519
+ rangeChange: _angular_core.OutputEmitterRef<AfDateRange>;
1182
1520
  inputRef: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
1183
1521
  popoverRef: _angular_core.Signal<ElementRef<HTMLDivElement> | undefined>;
1184
1522
  weekdayLabels: string[];
1185
- monthNames: string[];
1523
+ weekdayFullLabels: string[];
1186
1524
  selectedDate: _angular_core.WritableSignal<Date | null>;
1525
+ rangeStart: _angular_core.WritableSignal<Date | null>;
1526
+ rangeEnd: _angular_core.WritableSignal<Date | null>;
1527
+ rangeSelecting: _angular_core.WritableSignal<boolean>;
1187
1528
  currentMonth: _angular_core.WritableSignal<number>;
1188
1529
  currentYear: _angular_core.WritableSignal<number>;
1189
1530
  isOpen: _angular_core.WritableSignal<boolean>;
1190
1531
  focusedDate: _angular_core.WritableSignal<Date | null>;
1191
- onChange: (value: Date | null) => void;
1532
+ currentView: _angular_core.WritableSignal<AfDatepickerView>;
1533
+ focusedMonth: _angular_core.WritableSignal<number>;
1534
+ focusedYear: _angular_core.WritableSignal<number>;
1535
+ yearPageStart: _angular_core.WritableSignal<number>;
1536
+ onChange: (value: unknown) => void;
1192
1537
  onTouched: () => void;
1193
- calendarDays: _angular_core.Signal<CalendarDay[]>;
1194
- formattedDate: _angular_core.Signal<string>;
1538
+ private onValidatorChange;
1539
+ parsedMin: _angular_core.Signal<Date | null>;
1540
+ parsedMax: _angular_core.Signal<Date | null>;
1195
1541
  popoverId: _angular_core.Signal<string>;
1542
+ hintId: _angular_core.Signal<string>;
1543
+ errorId: _angular_core.Signal<string>;
1544
+ ariaDescribedBy: _angular_core.Signal<string | null>;
1545
+ dialogAriaLabel: _angular_core.Signal<"Choose date range" | "Choose date">;
1546
+ headerTitle: _angular_core.Signal<string>;
1547
+ titleAriaLabel: _angular_core.Signal<"Switch to month view" | "Switch to year view" | null>;
1548
+ prevButtonAriaLabel: _angular_core.Signal<"Previous month" | "Previous year" | "Previous 12 years">;
1549
+ nextButtonAriaLabel: _angular_core.Signal<"Next month" | "Next year" | "Next 12 years">;
1550
+ gridAriaLabel: _angular_core.Signal<string>;
1551
+ hasClearableValue: _angular_core.Signal<boolean>;
1552
+ formattedValue: _angular_core.Signal<string>;
1553
+ isTodayDisabled: _angular_core.Signal<boolean>;
1554
+ calendarDays: _angular_core.Signal<CalendarDay[]>;
1555
+ monthItems: _angular_core.Signal<MonthItem[]>;
1556
+ yearItems: _angular_core.Signal<YearItem[]>;
1196
1557
  toggle(): void;
1197
- selectDate(date: Date): void;
1198
- previousMonth(): void;
1199
- nextMonth(): void;
1200
- private generateCalendarDays;
1558
+ /** Opens the calendar popover */
1559
+ open(): void;
1560
+ /** Closes the calendar popover */
1561
+ close(returnFocus?: boolean): void;
1562
+ /** Handles click on a calendar day */
1563
+ onDayClick(day: CalendarDay): void;
1564
+ /** Selects a single date and closes the popover */
1565
+ selectSingleDate(date: Date): void;
1566
+ /** Handles range date selection (two-click: start then end) */
1567
+ selectRangeDate(date: Date): void;
1568
+ /** Navigates to today and selects it (single mode) or focuses it */
1569
+ goToToday(): void;
1570
+ /** Clears the selected value */
1571
+ clearValue(event: Event): void;
1572
+ /** Drills up: days -> months -> years */
1573
+ drillUp(): void;
1574
+ /** Navigates to previous period based on current view */
1575
+ navigatePrevious(): void;
1576
+ /** Navigates to next period based on current view */
1577
+ navigateNext(): void;
1578
+ /** Selects a month from the month view and switches to days */
1579
+ selectMonth(monthIndex: number): void;
1580
+ /** Selects a year from the year view and switches to months */
1581
+ selectYear(year: number): void;
1582
+ /** Returns true if the given day matches the keyboard-focused date */
1583
+ isDayHighlighted(day: CalendarDay): boolean;
1584
+ /** Returns the tabindex for a day button (roving tabindex pattern) */
1201
1585
  getDayTabIndex(day: CalendarDay): number;
1586
+ /** Returns true if the given month index matches the keyboard-focused month */
1587
+ isMonthHighlighted(monthIndex: number): boolean;
1588
+ /** Returns the tabindex for a month button */
1589
+ getMonthTabIndex(monthIndex: number): number;
1590
+ /** Returns true if the given year matches the keyboard-focused year */
1591
+ isYearHighlighted(year: number): boolean;
1592
+ /** Returns the tabindex for a year button */
1593
+ getYearTabIndex(year: number): number;
1594
+ /** Returns a date key string for DOM identification */
1202
1595
  getDateKey(date: Date): string;
1203
1596
  onInputKeydown(event: KeyboardEvent): void;
1204
- onGridKeydown(event: KeyboardEvent): void;
1205
- onEscape(): void;
1597
+ /** Keyboard navigation within the day grid */
1598
+ onDayGridKeydown(event: KeyboardEvent): void;
1599
+ /** Keyboard navigation within the month grid */
1600
+ onMonthGridKeydown(event: KeyboardEvent): void;
1601
+ /** Keyboard navigation within the year grid */
1602
+ onYearGridKeydown(event: KeyboardEvent): void;
1206
1603
  onDocumentClick(event: MouseEvent): void;
1207
- private open;
1208
- private close;
1604
+ writeValue(value: unknown): void;
1605
+ registerOnChange(fn: (value: unknown) => void): void;
1606
+ registerOnTouched(fn: () => void): void;
1607
+ setDisabledState(isDisabled: boolean): void;
1608
+ validate(control: AbstractControl): ValidationErrors | null;
1609
+ registerOnValidatorChange(fn: () => void): void;
1610
+ private writeSingleValue;
1611
+ private writeRangeValue;
1612
+ private emitSingleValue;
1613
+ private emitRangeValue;
1614
+ private validateSingle;
1615
+ private validateRange;
1616
+ private buildDay;
1617
+ /** Checks whether a date falls outside min/max bounds */
1618
+ isDateDisabled(date: Date): boolean;
1619
+ /** Checks whether a date is explicitly unavailable (disabledDates or dateFilter) */
1620
+ private isDateUnavailable;
1621
+ private isMonthDisabled;
1622
+ private isYearDisabled;
1209
1623
  private setFocusedDate;
1210
1624
  private focusDayButton;
1625
+ private focusMonthButton;
1626
+ private focusYearButton;
1627
+ /** Finds the next non-disabled date in the given direction */
1628
+ private findNextEnabledDate;
1629
+ private shiftMonth;
1211
1630
  private addDays;
1212
1631
  private addMonths;
1632
+ private addYears;
1213
1633
  private getWeekdayIndex;
1214
- private shiftMonth;
1215
1634
  private isSameDay;
1635
+ private compareDays;
1636
+ private parseDate;
1637
+ private coerceToDate;
1638
+ private toIsoString;
1216
1639
  private formatDate;
1217
- writeValue(value: Date | null): void;
1218
- registerOnChange(fn: (value: Date | null) => void): void;
1219
- registerOnTouched(fn: () => void): void;
1220
- setDisabledState(isDisabled: boolean): void;
1221
1640
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AfDatepickerComponent, never>;
1222
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfDatepickerComponent, "af-datepicker", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "dateFormat": { "alias": "dateFormat"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; "dateChange": "dateChange"; }, never, never, true, never>;
1641
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfDatepickerComponent, "af-datepicker", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "dateFormat": { "alias": "dateFormat"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "disabledDates": { "alias": "disabledDates"; "required": false; "isSignal": true; }; "dateFilter": { "alias": "dateFilter"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; "dateChange": "dateChange"; "rangeChange": "rangeChange"; }, never, never, true, never>;
1223
1642
  }
1224
1643
 
1225
1644
  type AfChipVariant = 'default' | 'info' | 'success' | 'warning' | 'danger';
@@ -1394,24 +1813,80 @@ declare class AfTooltipDirective implements OnDestroy {
1394
1813
 
1395
1814
  type AfBadgeVariant = 'default' | 'info' | 'success' | 'warning' | 'danger';
1396
1815
  /**
1397
- * Badge component for status indicators
1816
+ * Badge component for status indicators, labels, and counts.
1398
1817
  *
1399
- * @example
1400
- * <af-badge variant="success" icon="+">Approved</af-badge>
1401
- * <af-badge variant="danger">Blocked</af-badge>
1818
+ * Wraps the Construct Design System `ct-badge` with semantic color
1819
+ * variants and optional icon or dot indicators.
1820
+ *
1821
+ * @example Basic usage
1822
+ * <af-badge variant="success">Approved</af-badge>
1823
+ *
1824
+ * @example With icon
1825
+ * <af-badge variant="danger" icon="+">Blocked</af-badge>
1826
+ *
1827
+ * @example With dot indicator
1828
+ * <af-badge variant="info" dot>Online</af-badge>
1829
+ *
1830
+ * @example Status badge for screen readers
1831
+ * <af-badge variant="warning" role="status" ariaLabel="Build status: failing">
1832
+ * Failing
1833
+ * </af-badge>
1834
+ *
1835
+ * @accessibility
1836
+ * - Non-interactive element — no keyboard navigation required.
1837
+ * - Decorative elements (icon, dot) are hidden from screen readers via `aria-hidden`.
1838
+ * - Use `ariaLabel` when the badge has no visible text or when the visual content
1839
+ * alone does not convey the full meaning.
1840
+ * - Set `role="status"` when the badge reflects a live value that screen readers
1841
+ * should announce on change.
1402
1842
  */
1403
1843
  declare class AfBadgeComponent {
1844
+ /** ARIA role, e.g. `"status"` for live status badges. */
1845
+ role: _angular_core.InputSignal<string>;
1404
1846
  /** Accessible label, useful when the badge has no visible text. */
1405
1847
  ariaLabel: _angular_core.InputSignal<string>;
1406
- /** Color variant. */
1848
+ /** Semantic color variant. */
1407
1849
  variant: _angular_core.InputSignal<AfBadgeVariant>;
1408
- /** Icon character to display */
1850
+ /** Icon character to display before the label. */
1409
1851
  icon: _angular_core.InputSignal<string>;
1410
- /** Show a dot indicator instead of icon */
1411
- dot: _angular_core.InputSignal<boolean>;
1852
+ /** Show a dot indicator instead of an icon. */
1853
+ dot: _angular_core.InputSignalWithTransform<boolean, unknown>;
1854
+ /** Computed CSS classes combining base class and variant/icon modifiers. */
1412
1855
  badgeClasses: _angular_core.Signal<string>;
1413
1856
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AfBadgeComponent, never>;
1414
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfBadgeComponent, "af-badge", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1857
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfBadgeComponent, "af-badge", never, { "role": { "alias": "role"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1858
+ }
1859
+
1860
+ /**
1861
+ * Test harness for AfBadgeComponent.
1862
+ *
1863
+ * Provides a semantic API for querying badge state in tests,
1864
+ * abstracting DOM details behind readable method names.
1865
+ *
1866
+ * @example
1867
+ * const harness = new AfBadgeHarness(fixture.nativeElement);
1868
+ * expect(harness.getText()).toBe('Approved');
1869
+ * expect(harness.hasClass('ct-badge--success')).toBe(true);
1870
+ */
1871
+ declare class AfBadgeHarness {
1872
+ private readonly hostEl;
1873
+ constructor(container: HTMLElement);
1874
+ /** Returns the trimmed text content of the badge (projected content only). */
1875
+ getText(): string;
1876
+ /** Returns the full `class` attribute string of the host element. */
1877
+ getClasses(): string;
1878
+ /** Returns whether the host element has the given CSS class. */
1879
+ hasClass(className: string): boolean;
1880
+ /** Returns the `aria-label` attribute value, or `null` if absent. */
1881
+ getAriaLabel(): string | null;
1882
+ /** Returns the `role` attribute value, or `null` if absent. */
1883
+ getRole(): string | null;
1884
+ /** Returns whether the badge contains an icon element. */
1885
+ hasIcon(): boolean;
1886
+ /** Returns whether the badge contains a dot indicator. */
1887
+ hasDot(): boolean;
1888
+ /** Returns the text content of the icon element, or empty string if absent. */
1889
+ getIconText(): string;
1415
1890
  }
1416
1891
 
1417
1892
  type AfProgressBarVariant = 'default' | 'info' | 'success' | 'warning' | 'danger';
@@ -1915,9 +2390,22 @@ interface AfSelectMenuOption {
1915
2390
  * [multiple]="true"
1916
2391
  * [formControl]="rolesControl">
1917
2392
  * </af-select-menu>
2393
+ *
2394
+ * @accessibility
2395
+ * - Implements the WAI-ARIA Listbox pattern with a combobox trigger.
2396
+ * - Keyboard: ArrowDown/Up to move highlight, Enter/Space to select,
2397
+ * Escape to close, Home/End to jump, Tab to select-and-close (single) or close (multi).
2398
+ * - Focus stays on the combobox trigger; `aria-activedescendant` tracks the highlighted option.
2399
+ * - Screen-reader announcements via {@link AriaLiveAnnouncer} for open/close/selection changes.
2400
+ * - All user-facing strings are configurable via {@link AF_SELECT_MENU_I18N} for i18n.
2401
+ * - Uses CSS logical properties for RTL layout support.
2402
+ * - `aria-describedby` links to hint or error text; `aria-invalid` is set on error state.
2403
+ * - Disabled options are marked with `aria-disabled` and skipped during keyboard navigation.
1918
2404
  */
1919
2405
  declare class AfSelectMenuComponent implements ControlValueAccessor {
1920
2406
  private static nextId;
2407
+ protected readonly i18n: _neuravision_ng_construct.AfSelectMenuI18n;
2408
+ private readonly announcer;
1921
2409
  /** Label shown above the select */
1922
2410
  label: _angular_core.InputSignal<string>;
1923
2411
  /** Placeholder text when nothing is selected */
@@ -1983,6 +2471,105 @@ declare class AfSelectMenuComponent implements ControlValueAccessor {
1983
2471
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AfSelectMenuComponent, "af-select-menu", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "componentId": { "alias": "componentId"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; }, never, never, true, never>;
1984
2472
  }
1985
2473
 
2474
+ /**
2475
+ * Test harness for AfSelectMenuComponent.
2476
+ *
2477
+ * Provides a semantic API for interacting with the select-menu in tests,
2478
+ * abstracting DOM details behind readable method names.
2479
+ *
2480
+ * @example
2481
+ * const harness = new AfSelectMenuHarness(fixture.nativeElement);
2482
+ * harness.click();
2483
+ * expect(harness.isOpen()).toBe(true);
2484
+ * expect(harness.getOptionCount()).toBe(4);
2485
+ * harness.clickOption(1);
2486
+ * expect(harness.getTriggerText()).toBe('Banana');
2487
+ */
2488
+ declare class AfSelectMenuHarness {
2489
+ private readonly hostEl;
2490
+ constructor(container: HTMLElement);
2491
+ /** Returns the trigger `<button>` element. */
2492
+ getTriggerElement(): HTMLButtonElement;
2493
+ /** Returns the trimmed display text of the trigger. */
2494
+ getTriggerText(): string;
2495
+ /** Clicks the trigger button. */
2496
+ click(): void;
2497
+ /** Returns whether the trigger is disabled. */
2498
+ isDisabled(): boolean;
2499
+ /** Returns whether the listbox is currently open. */
2500
+ isOpen(): boolean;
2501
+ /** Returns the `aria-expanded` attribute value. */
2502
+ getAriaExpanded(): string | null;
2503
+ /** Returns the `aria-label` attribute value. */
2504
+ getAriaLabel(): string | null;
2505
+ /** Returns the `aria-labelledby` attribute value. */
2506
+ getAriaLabelledBy(): string | null;
2507
+ /** Returns the `aria-activedescendant` attribute value. */
2508
+ getAriaActiveDescendant(): string | null;
2509
+ /** Returns the `aria-invalid` attribute value. */
2510
+ getAriaInvalid(): string | null;
2511
+ /** Returns the `aria-required` attribute value. */
2512
+ getAriaRequired(): string | null;
2513
+ /** Returns the `aria-describedby` attribute value. */
2514
+ getAriaDescribedBy(): string | null;
2515
+ /** Returns all option elements inside the listbox. */
2516
+ getOptions(): HTMLElement[];
2517
+ /** Returns the trimmed text of the option at the given index. */
2518
+ getOptionText(index: number): string;
2519
+ /** Returns the number of options. */
2520
+ getOptionCount(): number;
2521
+ /** Returns whether the option at the given index is selected. */
2522
+ isOptionSelected(index: number): boolean;
2523
+ /** Returns whether the option at the given index is disabled. */
2524
+ isOptionDisabled(index: number): boolean;
2525
+ /** Returns whether the option at the given index is highlighted. */
2526
+ isOptionHighlighted(index: number): boolean;
2527
+ /** Clicks the option at the given index. */
2528
+ clickOption(index: number): void;
2529
+ /** Returns the trimmed label text, or empty string if no label. */
2530
+ getLabelText(): string;
2531
+ /** Returns the trimmed hint text, or empty string if no hint. */
2532
+ getHintText(): string;
2533
+ /** Returns the trimmed error text, or empty string if no error. */
2534
+ getErrorText(): string;
2535
+ /** Returns whether the select-menu wrapper has the given CSS class. */
2536
+ hasClass(className: string): boolean;
2537
+ }
2538
+
2539
+ /** Translatable strings used by the select-menu component. */
2540
+ interface AfSelectMenuI18n {
2541
+ /** Fallback `aria-label` when no `label` input is provided. */
2542
+ selectOption: string;
2543
+ /** Announcement when the listbox opens. Use `{count}` as placeholder. */
2544
+ opened: string;
2545
+ /** Announcement when the listbox closes. */
2546
+ closed: string;
2547
+ /** Announcement when an option is selected. Use `{label}` as placeholder. */
2548
+ selected: string;
2549
+ /** Announcement when an option is deselected (multi-select). Use `{label}` as placeholder. */
2550
+ deselected: string;
2551
+ /** Announcement for the number of selected options (multi-select). Use `{count}` as placeholder. */
2552
+ countSelected: string;
2553
+ }
2554
+ /**
2555
+ * Injection token to override select-menu screen-reader announcements
2556
+ * and the fallback `aria-label`.
2557
+ *
2558
+ * @example
2559
+ * providers: [{
2560
+ * provide: AF_SELECT_MENU_I18N,
2561
+ * useValue: {
2562
+ * selectOption: 'Option auswählen',
2563
+ * opened: '{count} Optionen verfügbar',
2564
+ * closed: 'Auswahl geschlossen',
2565
+ * selected: '{label} ausgewählt',
2566
+ * deselected: '{label} abgewählt',
2567
+ * countSelected: '{count} Optionen ausgewählt',
2568
+ * },
2569
+ * }]
2570
+ */
2571
+ declare const AF_SELECT_MENU_I18N: InjectionToken<AfSelectMenuI18n>;
2572
+
1986
2573
  type AfNavbarSize = 'sm' | 'md' | 'lg';
1987
2574
  type AfNavbarVariant = 'default' | 'sticky' | 'fixed' | 'elevated' | 'transparent' | 'dark' | 'bordered';
1988
2575
  /**
@@ -2495,5 +3082,5 @@ declare class AfFormatLabelPipe implements PipeTransform {
2495
3082
  static ɵpipe: _angular_core.ɵɵPipeDeclaration<AfFormatLabelPipe, "afFormatLabel", true>;
2496
3083
  }
2497
3084
 
2498
- export { AfAccordionComponent, AfAccordionItemComponent, AfAlertComponent, AfAppShellComponent, AfAppShellPageHeaderComponent, AfAppShellV2Component, AfAppShellV2ToolbarComponent, AfAvatarComponent, AfBadgeComponent, AfBannerComponent, AfBreadcrumbsComponent, AfButtonComponent, AfCardComponent, AfCellDefDirective, AfCheckboxComponent, AfChipComponent, AfChipInputComponent, AfComboboxComponent, AfDataTableComponent, AfDatepickerComponent, AfDividerComponent, AfDrawerComponent, AfDropdownComponent, AfEmptyStateComponent, AfFieldComponent, AfFileUploadComponent, AfFormatLabelPipe, AfIconComponent, AfInputComponent, AfModalComponent, AfNavItemComponent, AfNavTabsComponent, AfNavbarComponent, AfPaginationComponent, AfPopoverComponent, AfPopoverTriggerDirective, AfProgressBarComponent, AfRadioComponent, AfRadioGroupComponent, AfSelectComponent, AfSelectMenuComponent, AfSidebarComponent, AfSkeletonComponent, AfSkipLinkComponent, AfSliderComponent, AfSpinnerComponent, AfSwitchComponent, AfTabPanelComponent, AfTableBodyComponent, AfTableCellComponent, AfTableComponent, AfTableHeaderCellComponent, AfTableHeaderComponent, AfTableRowComponent, AfTabsComponent, AfTextareaComponent, AfToastContainerComponent, AfToastService, AfToggleGroupComponent, AfToolbarComponent, AfTooltipDirective };
2499
- export type { AfAlertVariant, AfAvatarSize, AfAvatarStatus, AfBadgeVariant, AfBannerAppearance, AfBannerPosition, AfBannerVariant, AfBreadcrumb, AfButtonSize, AfButtonType, AfButtonVariant, AfCardElevation, AfCardPadding, AfChipAppearance, AfChipSize, AfChipVariant, AfColumn, AfComboboxOption, AfDataRow, AfDataTableConfig, AfDividerColor, AfDividerOrientation, AfDividerSpacing, AfDrawerPosition, AfDrawerSize, AfDropdownItem, AfEmptyStateSize, AfEmptyStateVariant, AfFileEntry, AfFileValidationError, AfIconSize, AfInputType, AfNavTab, AfNavTabsSize, AfNavTabsVariant, AfNavbarSize, AfNavbarVariant, AfPopoverAlign, AfPopoverPosition, AfPopoverSize, AfProgressBarSize, AfProgressBarVariant, AfSelectMenuOption, AfSelectOption, AfShellPanelState, AfShellSidebarState, AfSidebarMode, AfSkeletonVariant, AfSliderSize, AfSortDirection, AfSortState, AfSpinnerSize, AfTab, AfTableCellType, AfTableVariant, AfToast, AfToastVariant, AfToggleGroupSize, AfToggleItem, AfTooltipPosition };
3085
+ export { AF_ACCORDION_I18N, AF_ALERT_I18N, AF_INPUT_I18N, AF_SELECT_MENU_I18N, AfAccordionComponent, AfAccordionHarness, AfAccordionItemComponent, AfAccordionItemHarness, AfAlertComponent, AfAlertHarness, AfAppShellComponent, AfAppShellPageHeaderComponent, AfAppShellV2Component, AfAppShellV2ToolbarComponent, AfAvatarComponent, AfBadgeComponent, AfBadgeHarness, AfBannerComponent, AfBreadcrumbsComponent, AfButtonComponent, AfButtonHarness, AfCardComponent, AfCellDefDirective, AfCheckboxComponent, AfChipComponent, AfChipInputComponent, AfComboboxComponent, AfDataTableComponent, AfDatepickerComponent, AfDividerComponent, AfDrawerComponent, AfDropdownComponent, AfEmptyStateComponent, AfFieldComponent, AfFileUploadComponent, AfFormatLabelPipe, AfIconComponent, AfInputComponent, AfInputHarness, AfModalComponent, AfNavItemComponent, AfNavTabsComponent, AfNavbarComponent, AfPaginationComponent, AfPopoverComponent, AfPopoverTriggerDirective, AfProgressBarComponent, AfRadioComponent, AfRadioGroupComponent, AfSelectComponent, AfSelectMenuComponent, AfSelectMenuHarness, AfSidebarComponent, AfSkeletonComponent, AfSkipLinkComponent, AfSliderComponent, AfSpinnerComponent, AfSwitchComponent, AfTabPanelComponent, AfTableBodyComponent, AfTableCellComponent, AfTableComponent, AfTableHeaderCellComponent, AfTableHeaderComponent, AfTableRowComponent, AfTabsComponent, AfTextareaComponent, AfToastContainerComponent, AfToastService, AfToggleGroupComponent, AfToolbarComponent, AfTooltipDirective };
3086
+ export type { AfAccordionI18n, AfAlertI18n, AfAlertVariant, AfAvatarSize, AfAvatarStatus, AfBadgeVariant, AfBannerAppearance, AfBannerPosition, AfBannerVariant, AfBreadcrumb, AfButtonSize, AfButtonType, AfButtonVariant, AfCardElevation, AfCardPadding, AfChipAppearance, AfChipSize, AfChipVariant, AfColumn, AfComboboxOption, AfDataRow, AfDataTableConfig, AfDateRange, AfDatepickerMode, AfDatepickerValueFormat, AfDatepickerView, AfDividerColor, AfDividerOrientation, AfDividerSpacing, AfDrawerPosition, AfDrawerSize, AfDropdownItem, AfEmptyStateSize, AfEmptyStateVariant, AfFileEntry, AfFileValidationError, AfIconSize, AfInputI18n, AfInputType, AfNavTab, AfNavTabsSize, AfNavTabsVariant, AfNavbarSize, AfNavbarVariant, AfPopoverAlign, AfPopoverPosition, AfPopoverSize, AfProgressBarSize, AfProgressBarVariant, AfSelectMenuI18n, AfSelectMenuOption, AfSelectOption, AfShellPanelState, AfShellSidebarState, AfSidebarMode, AfSkeletonVariant, AfSliderSize, AfSortDirection, AfSortState, AfSpinnerSize, AfTab, AfTableCellType, AfTableVariant, AfToast, AfToastVariant, AfToggleGroupSize, AfToggleItem, AfTooltipPosition };