@angular/aria 22.0.0-next.7 → 22.0.0-next.8

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.
Files changed (93) hide show
  1. package/fesm2022/_accordion-chunk.mjs +1 -1
  2. package/fesm2022/_click-event-manager-chunk.mjs +1 -1
  3. package/fesm2022/{_signal-like-chunk.mjs → _collection-chunk.mjs} +51 -2
  4. package/fesm2022/_collection-chunk.mjs.map +1 -0
  5. package/fesm2022/_deferred-content-chunk.mjs +6 -6
  6. package/fesm2022/_list-chunk.mjs +4 -1
  7. package/fesm2022/_list-chunk.mjs.map +1 -1
  8. package/fesm2022/_list-navigation-chunk.mjs +1 -1
  9. package/fesm2022/_list-typeahead-chunk.mjs +1 -1
  10. package/fesm2022/_menu-chunk.mjs +1 -1
  11. package/fesm2022/{_combobox-listbox-chunk.mjs → _option-chunk.mjs} +3 -50
  12. package/fesm2022/_option-chunk.mjs.map +1 -0
  13. package/fesm2022/_tabs-chunk.mjs +1 -1
  14. package/fesm2022/_toolbar-widget-group-chunk.mjs +1 -1
  15. package/fesm2022/_transforms-chunk.mjs +8 -0
  16. package/fesm2022/_transforms-chunk.mjs.map +1 -0
  17. package/fesm2022/{_combobox-tree-chunk.mjs → _tree-chunk.mjs} +3 -48
  18. package/fesm2022/_tree-chunk.mjs.map +1 -0
  19. package/fesm2022/_widget-chunk.mjs +36 -15
  20. package/fesm2022/_widget-chunk.mjs.map +1 -1
  21. package/fesm2022/accordion.mjs +28 -55
  22. package/fesm2022/accordion.mjs.map +1 -1
  23. package/fesm2022/aria.mjs +1 -1
  24. package/fesm2022/aria.mjs.map +1 -1
  25. package/fesm2022/combobox-testing.mjs +79 -0
  26. package/fesm2022/combobox-testing.mjs.map +1 -0
  27. package/fesm2022/combobox.mjs +273 -307
  28. package/fesm2022/combobox.mjs.map +1 -1
  29. package/fesm2022/grid-testing.mjs +8 -0
  30. package/fesm2022/grid-testing.mjs.map +1 -1
  31. package/fesm2022/grid.mjs +68 -87
  32. package/fesm2022/grid.mjs.map +1 -1
  33. package/fesm2022/listbox-testing.mjs +4 -0
  34. package/fesm2022/listbox-testing.mjs.map +1 -1
  35. package/fesm2022/listbox.mjs +184 -205
  36. package/fesm2022/listbox.mjs.map +1 -1
  37. package/fesm2022/menu-testing.mjs +11 -0
  38. package/fesm2022/menu-testing.mjs.map +1 -1
  39. package/fesm2022/menu.mjs +42 -66
  40. package/fesm2022/menu.mjs.map +1 -1
  41. package/fesm2022/private.mjs +19 -13
  42. package/fesm2022/private.mjs.map +1 -1
  43. package/fesm2022/tabs.mjs +78 -84
  44. package/fesm2022/tabs.mjs.map +1 -1
  45. package/fesm2022/toolbar-testing.mjs +5 -1
  46. package/fesm2022/toolbar-testing.mjs.map +1 -1
  47. package/fesm2022/toolbar.mjs +21 -31
  48. package/fesm2022/toolbar.mjs.map +1 -1
  49. package/fesm2022/tree-testing.mjs +12 -0
  50. package/fesm2022/tree-testing.mjs.map +1 -1
  51. package/fesm2022/tree.mjs +118 -146
  52. package/fesm2022/tree.mjs.map +1 -1
  53. package/package.json +6 -6
  54. package/types/_accordion-chunk.d.ts +2 -2
  55. package/types/_collection-chunk.d.ts +42 -0
  56. package/types/_expansion-chunk.d.ts +1 -1
  57. package/types/_grid-chunk.d.ts +9 -3
  58. package/types/_keyboard-event-manager-chunk.d.ts +1 -1
  59. package/types/_list-chunk.d.ts +1 -1
  60. package/types/_list-navigation-chunk.d.ts +1 -1
  61. package/types/_listbox-chunk.d.ts +1 -1
  62. package/types/_menu-chunk.d.ts +1 -1
  63. package/types/_tabs-chunk.d.ts +1 -1
  64. package/types/_toolbar-chunk.d.ts +1 -1
  65. package/types/_tree-chunk.d.ts +1 -1
  66. package/types/accordion.d.ts +7 -13
  67. package/types/combobox-testing.d.ts +63 -0
  68. package/types/combobox.d.ts +96 -193
  69. package/types/grid-testing.d.ts +4 -0
  70. package/types/grid.d.ts +101 -97
  71. package/types/listbox-testing.d.ts +25 -0
  72. package/types/listbox.d.ts +55 -60
  73. package/types/menu-testing.d.ts +6 -0
  74. package/types/menu.d.ts +17 -13
  75. package/types/private.d.ts +24 -138
  76. package/types/tabs.d.ts +69 -72
  77. package/types/toolbar-testing.d.ts +4 -0
  78. package/types/toolbar.d.ts +5 -6
  79. package/types/tree-testing.d.ts +8 -0
  80. package/types/tree.d.ts +7 -14
  81. package/fesm2022/_combobox-chunk.mjs +0 -478
  82. package/fesm2022/_combobox-chunk.mjs.map +0 -1
  83. package/fesm2022/_combobox-listbox-chunk.mjs.map +0 -1
  84. package/fesm2022/_combobox-tree-chunk.mjs.map +0 -1
  85. package/fesm2022/_element-chunk.mjs +0 -6
  86. package/fesm2022/_element-chunk.mjs.map +0 -1
  87. package/fesm2022/_signal-like-chunk.mjs.map +0 -1
  88. package/fesm2022/simple-combobox.mjs +0 -443
  89. package/fesm2022/simple-combobox.mjs.map +0 -1
  90. package/types/_combobox-chunk.d.ts +0 -224
  91. package/types/_element-chunk.d.ts +0 -10
  92. package/types/_signal-like-chunk.d.ts +0 -14
  93. package/types/simple-combobox.d.ts +0 -124
package/types/grid.d.ts CHANGED
@@ -1,97 +1,11 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { Signal, EventEmitter } from '@angular/core';
2
+ import { OnInit, OnDestroy, Signal } from '@angular/core';
3
3
  import * as _angular_cdk_bidi from '@angular/cdk/bidi';
4
- import { GridPattern, GridCellPattern, GridRowPattern, ElementResolver, GridCellWidgetPattern } from './_grid-chunk.js';
5
- import './_signal-like-chunk.js';
4
+ import { GridCellPattern, GridPattern, GridRowPattern, ElementResolver, GridCellWidgetPattern } from './_grid-chunk.js';
5
+ import { SortedCollection } from './_collection-chunk.js';
6
6
  import './_keyboard-event-manager-chunk.js';
7
7
  import './_click-event-manager-chunk.js';
8
8
 
9
- /**
10
- * The container for a grid. It provides keyboard navigation and focus management for the grid's
11
- * rows and cells. It manages the overall behavior of the grid, including focus
12
- * wrapping, selection, and disabled states.
13
- *
14
- * ```html
15
- * <table ngGrid [multi]="true" [enableSelection]="true">
16
- * @for (row of gridData; track row) {
17
- * <tr ngGridRow>
18
- * @for (cell of row; track cell) {
19
- * <td ngGridCell [disabled]="cell.disabled">
20
- * {{cell.value}}
21
- * </td>
22
- * }
23
- * </tr>
24
- * }
25
- * </table>
26
- * ```
27
- *
28
- * @developerPreview 21.0
29
- *
30
- * @see [Grid](guide/aria/grid)
31
- */
32
- declare class Grid {
33
- /** A reference to the host element. */
34
- private readonly _elementRef;
35
- /** A reference to the host element. */
36
- readonly element: HTMLElement;
37
- /** The rows that make up the grid. */
38
- private readonly _rows;
39
- /** The UI patterns for the rows in the grid. */
40
- private readonly _rowPatterns;
41
- /** Text direction. */
42
- readonly textDirection: _angular_core.WritableSignal<_angular_cdk_bidi.Direction>;
43
- /** Whether selection is enabled for the grid. */
44
- readonly enableSelection: _angular_core.InputSignalWithTransform<boolean, unknown>;
45
- /** Whether the grid is disabled. */
46
- readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
47
- /**
48
- * Whether to allow disabled items to receive focus. When `true`, disabled items are
49
- * focusable but not interactive. When `false`, disabled items are skipped during navigation.
50
- */
51
- readonly softDisabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
52
- /**
53
- * The focus strategy used by the grid.
54
- * - `roving`: Focus is moved to the active cell using `tabindex`.
55
- * - `activedescendant`: Focus remains on the grid container, and `aria-activedescendant` is used to indicate the active cell.
56
- */
57
- readonly focusMode: _angular_core.InputSignal<"roving" | "activedescendant">;
58
- /**
59
- * The wrapping behavior for keyboard navigation along the row axis.
60
- * - `continuous`: Navigation wraps from the last row to the first, and vice-versa.
61
- * - `loop`: Navigation wraps within the current row.
62
- * - `nowrap`: Navigation stops at the first/last item in the row.
63
- */
64
- readonly rowWrap: _angular_core.InputSignal<"continuous" | "loop" | "nowrap">;
65
- /**
66
- * The wrapping behavior for keyboard navigation along the column axis.
67
- * - `continuous`: Navigation wraps from the last column to the first, and vice-versa.
68
- * - `loop`: Navigation wraps within the current column.
69
- * - `nowrap`: Navigation stops at the first/last item in the column.
70
- */
71
- readonly colWrap: _angular_core.InputSignal<"continuous" | "loop" | "nowrap">;
72
- /** Whether multiple cells in the grid can be selected. */
73
- readonly multi: _angular_core.InputSignalWithTransform<boolean, unknown>;
74
- /**
75
- * The selection strategy used by the grid.
76
- * - `follow`: The focused cell is automatically selected.
77
- * - `explicit`: Cells are selected explicitly by the user (e.g., via click or spacebar).
78
- */
79
- readonly selectionMode: _angular_core.InputSignal<"follow" | "explicit">;
80
- /** The tabindex of the grid. */
81
- readonly tabIndex: _angular_core.InputSignalWithTransform<number | undefined, string | number | undefined>;
82
- /** The UI pattern for the grid. */
83
- readonly _pattern: GridPattern;
84
- /** The ID of the active descendant in the grid. */
85
- readonly activeDescendant: Signal<string | undefined>;
86
- constructor();
87
- /** Scrolls the active cell into view. */
88
- scrollActiveCellIntoView(options?: ScrollIntoViewOptions): void;
89
- /** Gets the cell pattern for a given element. */
90
- private _getCell;
91
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<Grid, never>;
92
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Grid, "[ngGrid]", ["ngGrid"], { "enableSelection": { "alias": "enableSelection"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "softDisabled": { "alias": "softDisabled"; "required": false; "isSignal": true; }; "focusMode": { "alias": "focusMode"; "required": false; "isSignal": true; }; "rowWrap": { "alias": "rowWrap"; "required": false; "isSignal": true; }; "colWrap": { "alias": "colWrap"; "required": false; "isSignal": true; }; "multi": { "alias": "multi"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; }, {}, ["_rows"], never, true, never>;
93
- }
94
-
95
9
  /**
96
10
  * Represents a cell within a grid row. It is the primary focusable element
97
11
  * within the grid. It can be disabled and can have its selection state managed
@@ -107,13 +21,11 @@ declare class Grid {
107
21
  *
108
22
  * @see [Grid](guide/aria/grid)
109
23
  */
110
- declare class GridCell {
24
+ declare class GridCell implements OnInit, OnDestroy {
111
25
  private readonly _elementRef;
112
26
  private readonly _renderer;
113
27
  /** A reference to the host element. */
114
28
  readonly element: HTMLElement;
115
- /** Emits when the cell is activated via Enter/Space (simple widgets only). */
116
- readonly activated: EventEmitter<KeyboardEvent>;
117
29
  /** Whether the cell is currently active (focused). */
118
30
  readonly active: Signal<boolean>;
119
31
  /** The widget contained within this cell, if any. */
@@ -152,11 +64,13 @@ declare class GridCell {
152
64
  /** The UI pattern for the grid cell. */
153
65
  readonly _pattern: GridCellPattern;
154
66
  constructor();
67
+ ngOnInit(): void;
68
+ ngOnDestroy(): void;
155
69
  private _toggleAttribute;
156
70
  /** Gets the cell widget pattern for a given element. */
157
71
  private _getWidget;
158
72
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridCell, never>;
159
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridCell, "[ngGridCell]", ["ngGridCell"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "role": { "alias": "role"; "required": false; "isSignal": true; }; "rowSpan": { "alias": "rowSpan"; "required": false; "isSignal": true; }; "colSpan": { "alias": "colSpan"; "required": false; "isSignal": true; }; "rowIndex": { "alias": "rowIndex"; "required": false; "isSignal": true; }; "colIndex": { "alias": "colIndex"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "tabindex": { "alias": "tabindex"; "required": false; "isSignal": true; }; }, { "activated": "activated"; "selected": "selectedChange"; }, ["_widget"], never, true, never>;
73
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridCell, "[ngGridCell]", ["ngGridCell"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "role": { "alias": "role"; "required": false; "isSignal": true; }; "rowSpan": { "alias": "rowSpan"; "required": false; "isSignal": true; }; "colSpan": { "alias": "colSpan"; "required": false; "isSignal": true; }; "rowIndex": { "alias": "rowIndex"; "required": false; "isSignal": true; }; "colIndex": { "alias": "colIndex"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "tabindex": { "alias": "tabindex"; "required": false; "isSignal": true; }; }, { "selected": "selectedChange"; }, ["_widget"], never, true, never>;
160
74
  }
161
75
 
162
76
  /**
@@ -172,13 +86,13 @@ declare class GridCell {
172
86
  *
173
87
  * @see [Grid](guide/aria/grid)
174
88
  */
175
- declare class GridRow {
89
+ declare class GridRow implements OnInit, OnDestroy {
176
90
  /** A reference to the host element. */
177
91
  private readonly _elementRef;
178
92
  /** A reference to the host element. */
179
93
  readonly element: HTMLElement;
180
- /** The cells that make up this row. */
181
- private readonly _cells;
94
+ /** The collection of cells in this row. */
95
+ readonly _collection: SortedCollection<GridCell>;
182
96
  /** The UI patterns for the cells in this row. */
183
97
  private readonly _cellPatterns;
184
98
  /** The parent grid. */
@@ -189,8 +103,98 @@ declare class GridRow {
189
103
  readonly rowIndex: _angular_core.InputSignal<number | undefined>;
190
104
  /** The UI pattern for the grid row. */
191
105
  readonly _pattern: GridRowPattern;
106
+ constructor();
107
+ ngOnInit(): void;
108
+ ngOnDestroy(): void;
192
109
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridRow, never>;
193
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridRow, "[ngGridRow]", ["ngGridRow"], { "rowIndex": { "alias": "rowIndex"; "required": false; "isSignal": true; }; }, {}, ["_cells"], never, true, never>;
110
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridRow, "[ngGridRow]", ["ngGridRow"], { "rowIndex": { "alias": "rowIndex"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
111
+ }
112
+
113
+ /**
114
+ * The container for a grid. It provides keyboard navigation and focus management for the grid's
115
+ * rows and cells. It manages the overall behavior of the grid, including focus
116
+ * wrapping, selection, and disabled states.
117
+ *
118
+ * ```html
119
+ * <table ngGrid [multi]="true" [enableSelection]="true">
120
+ * @for (row of gridData; track row) {
121
+ * <tr ngGridRow>
122
+ * @for (cell of row; track cell) {
123
+ * <td ngGridCell [disabled]="cell.disabled">
124
+ * {{cell.value}}
125
+ * </td>
126
+ * }
127
+ * </tr>
128
+ * }
129
+ * </table>
130
+ * ```
131
+ *
132
+ * @developerPreview 21.0
133
+ *
134
+ * @see [Grid](guide/aria/grid)
135
+ */
136
+ declare class Grid implements OnDestroy {
137
+ /** A reference to the host element. */
138
+ private readonly _elementRef;
139
+ /** A reference to the host element. */
140
+ readonly element: HTMLElement;
141
+ /** The collection of rows in the grid. */
142
+ readonly _collection: SortedCollection<GridRow>;
143
+ /** The UI patterns for the rows in the grid. */
144
+ private readonly _rowPatterns;
145
+ /** Text direction. */
146
+ readonly textDirection: _angular_core.WritableSignal<_angular_cdk_bidi.Direction>;
147
+ /** Whether selection is enabled for the grid. */
148
+ readonly enableSelection: _angular_core.InputSignalWithTransform<boolean, unknown>;
149
+ /** Whether the grid is disabled. */
150
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
151
+ /**
152
+ * Whether to allow disabled items to receive focus. When `true`, disabled items are
153
+ * focusable but not interactive. When `false`, disabled items are skipped during navigation.
154
+ */
155
+ readonly softDisabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
156
+ /**
157
+ * The focus strategy used by the grid.
158
+ * - `roving`: Focus is moved to the active cell using `tabindex`.
159
+ * - `activedescendant`: Focus remains on the grid container, and `aria-activedescendant` is used to indicate the active cell.
160
+ */
161
+ readonly focusMode: _angular_core.InputSignal<"roving" | "activedescendant">;
162
+ /**
163
+ * The wrapping behavior for keyboard navigation along the row axis.
164
+ * - `continuous`: Navigation wraps from the last row to the first, and vice-versa.
165
+ * - `loop`: Navigation wraps within the current row.
166
+ * - `nowrap`: Navigation stops at the first/last item in the row.
167
+ */
168
+ readonly rowWrap: _angular_core.InputSignal<"continuous" | "loop" | "nowrap">;
169
+ /**
170
+ * The wrapping behavior for keyboard navigation along the column axis.
171
+ * - `continuous`: Navigation wraps from the last column to the first, and vice-versa.
172
+ * - `loop`: Navigation wraps within the current column.
173
+ * - `nowrap`: Navigation stops at the first/last item in the column.
174
+ */
175
+ readonly colWrap: _angular_core.InputSignal<"continuous" | "loop" | "nowrap">;
176
+ /** Whether multiple cells in the grid can be selected. */
177
+ readonly multi: _angular_core.InputSignalWithTransform<boolean, unknown>;
178
+ /**
179
+ * The selection strategy used by the grid.
180
+ * - `follow`: The focused cell is automatically selected.
181
+ * - `explicit`: Cells are selected explicitly by the user (e.g., via click or spacebar).
182
+ */
183
+ readonly selectionMode: _angular_core.InputSignal<"follow" | "explicit">;
184
+ /** The tabindex of the grid. */
185
+ readonly tabIndex: _angular_core.InputSignalWithTransform<number | undefined, string | number | undefined>;
186
+ /** The UI pattern for the grid. */
187
+ readonly _pattern: GridPattern;
188
+ /** The ID of the active descendant in the grid. */
189
+ readonly activeDescendant: Signal<string | undefined>;
190
+ constructor();
191
+ ngOnDestroy(): void;
192
+ /** Scrolls the active cell into view. */
193
+ scrollActiveCellIntoView(options?: ScrollIntoViewOptions): void;
194
+ /** Gets the cell pattern for a given element. */
195
+ private _getCell;
196
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<Grid, never>;
197
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Grid, "[ngGrid]", ["ngGrid"], { "enableSelection": { "alias": "enableSelection"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "softDisabled": { "alias": "softDisabled"; "required": false; "isSignal": true; }; "focusMode": { "alias": "focusMode"; "required": false; "isSignal": true; }; "rowWrap": { "alias": "rowWrap"; "required": false; "isSignal": true; }; "colWrap": { "alias": "colWrap"; "required": false; "isSignal": true; }; "multi": { "alias": "multi"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabindex"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
194
198
  }
195
199
 
196
200
  /**
@@ -15,24 +15,49 @@ interface ListboxHarnessFilters extends BaseHarnessFilters {
15
15
  disabled?: boolean;
16
16
  }
17
17
 
18
+ /** Harness for interacting with a standard ngOption in tests. */
18
19
  declare class ListboxOptionHarness extends ComponentHarness {
19
20
  static hostSelector: string;
21
+ /**
22
+ * Gets a `HarnessPredicate` that can be used to search for an option
23
+ * with specific attributes.
24
+ * @param options Options for filtering which option instances are considered a match.
25
+ * @return a `HarnessPredicate` configured with the given options.
26
+ */
20
27
  static with(options?: ListboxOptionHarnessFilters): HarnessPredicate<ListboxOptionHarness>;
28
+ /** Whether the option is selected. */
21
29
  isSelected(): Promise<boolean>;
30
+ /** Whether the option is disabled. */
22
31
  isDisabled(): Promise<boolean>;
32
+ /** Gets the option's text. */
23
33
  getText(): Promise<string>;
34
+ /** Clicks the option to toggle its selected state. */
24
35
  click(): Promise<void>;
25
36
  }
37
+ /** Harness for interacting with a standard ngListbox in tests. */
26
38
  declare class ListboxHarness extends ComponentHarness {
27
39
  static hostSelector: string;
40
+ /**
41
+ * Gets a `HarnessPredicate` that can be used to search for a listbox
42
+ * with specific attributes.
43
+ * @param options Options for filtering which listbox instances are considered a match.
44
+ * @return a `HarnessPredicate` configured with the given options.
45
+ */
28
46
  static with(options?: ListboxHarnessFilters): HarnessPredicate<ListboxHarness>;
47
+ /** Gets the orientation of the listbox. */
29
48
  getOrientation(): Promise<'vertical' | 'horizontal'>;
49
+ /** Whether the listbox is multiselectable. */
30
50
  isMulti(): Promise<boolean>;
51
+ /** Whether the listbox is disabled. */
31
52
  isDisabled(): Promise<boolean>;
53
+ /** Gets the options inside the listbox. */
32
54
  getOptions(filters?: ListboxOptionHarnessFilters): Promise<ListboxOptionHarness[]>;
55
+ /** Focuses the listbox container. */
33
56
  focus(): Promise<void>;
34
57
  /** Blurs the listbox container. */
35
58
  blur(): Promise<void>;
59
+ /** Gets the ID of the active option. */
60
+ getActiveDescendantId(): Promise<string | null>;
36
61
  }
37
62
 
38
63
  export { ListboxHarness, ListboxOptionHarness };
@@ -1,16 +1,59 @@
1
1
  import * as _angular_cdk_bidi from '@angular/cdk/bidi';
2
2
  import * as _angular_core from '@angular/core';
3
- import { Signal } from '@angular/core';
3
+ import { OnInit, OnDestroy, Signal } from '@angular/core';
4
4
  import { OptionPattern, ListboxPattern } from './_listbox-chunk.js';
5
- import { ComboboxPopup } from './combobox.js';
6
- export { Combobox as ɵɵCombobox, ComboboxDialog as ɵɵComboboxDialog, ComboboxInput as ɵɵComboboxInput, ComboboxPopupContainer as ɵɵComboboxPopupContainer } from './combobox.js';
7
- import './_signal-like-chunk.js';
5
+ import { SortedCollection } from './_collection-chunk.js';
8
6
  import './_list-chunk.js';
9
7
  import './_list-navigation-chunk.js';
10
8
  import './_keyboard-event-manager-chunk.js';
11
9
  import './_click-event-manager-chunk.js';
12
- import './_combobox-chunk.js';
13
- import './_deferred-content-chunk.js';
10
+
11
+ /**
12
+ * A selectable option in an `ngListbox`.
13
+ *
14
+ * This directive should be applied to an element (e.g., `<li>`, `<div>`) within an
15
+ * `ngListbox`. The `value` input is used to identify the option, and the `label` input provides
16
+ * the accessible name for the option.
17
+ *
18
+ * ```html
19
+ * <li ngOption value="item-id" label="Item Name">
20
+ * Item Name
21
+ * </li>
22
+ * ```
23
+ *
24
+ * @developerPreview 21.0
25
+ *
26
+ * @see [Listbox](guide/aria/listbox)
27
+ * @see [Autocomplete](guide/aria/autocomplete)
28
+ * @see [Select](guide/aria/select)
29
+ * @see [Multiselect](guide/aria/multiselect)
30
+ */
31
+ declare class Option<V> implements OnInit, OnDestroy {
32
+ /** A reference to the host element. */
33
+ readonly element: HTMLElement;
34
+ /** Whether the option is currently active (focused). */
35
+ readonly active: _angular_core.Signal<boolean>;
36
+ /** The parent Listbox. */
37
+ private readonly _listbox;
38
+ /** A unique identifier for the option. */
39
+ readonly id: _angular_core.InputSignal<string>;
40
+ /** The parent Listbox UIPattern. */
41
+ private readonly _listboxPattern;
42
+ /** The value of the option. */
43
+ readonly value: _angular_core.InputSignal<V>;
44
+ /** Whether an item is disabled. */
45
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
46
+ /** The text used by the typeahead search. */
47
+ readonly label: _angular_core.InputSignal<string | undefined>;
48
+ /** Whether the option is selected. */
49
+ readonly selected: _angular_core.Signal<boolean | undefined>;
50
+ /** The Option UIPattern. */
51
+ readonly _pattern: OptionPattern<V>;
52
+ ngOnInit(): void;
53
+ ngOnDestroy(): void;
54
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<Option<any>, never>;
55
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Option<any>, "[ngOption]", ["ngOption"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
56
+ }
14
57
 
15
58
  /**
16
59
  * Represents a container used to display a list of items for a user to select from.
@@ -36,21 +79,17 @@ import './_deferred-content-chunk.js';
36
79
  * @see [Select](guide/aria/select)
37
80
  * @see [Multiselect](guide/aria/multiselect)
38
81
  */
39
- declare class Listbox<V> {
82
+ declare class Listbox<V> implements OnDestroy {
40
83
  /** A unique identifier for the listbox. */
41
84
  readonly id: _angular_core.InputSignal<string>;
42
- /** A reference to the parent combobox popup, if one exists. */
43
- private readonly _popup;
44
85
  /** A reference to the host element. */
45
86
  private readonly _elementRef;
46
87
  /** A reference to the host element. */
47
88
  readonly element: HTMLElement;
48
- /** The Options nested inside of the Listbox. */
49
- private readonly _options;
89
+ /** The collection of Options. */
90
+ readonly _collection: SortedCollection<Option<V>>;
50
91
  /** A signal wrapper for directionality. */
51
92
  protected readonly textDirection: Signal<_angular_cdk_bidi.Direction>;
52
- /** The Option UIPatterns of the child Options. */
53
- protected readonly items: Signal<OptionPattern<V>[]>;
54
93
  /** Whether the list is vertically or horizontally oriented. */
55
94
  readonly orientation: _angular_core.InputSignal<"vertical" | "horizontal">;
56
95
  /** Whether multiple items in the list can be selected at once. */
@@ -89,56 +128,12 @@ declare class Listbox<V> {
89
128
  /** The ID of the active descendant in the listbox. */
90
129
  readonly activeDescendant: Signal<string | undefined>;
91
130
  constructor();
131
+ ngOnDestroy(): void;
92
132
  scrollActiveItemIntoView(options?: ScrollIntoViewOptions): void;
93
133
  /** Navigates to the first item in the listbox. */
94
134
  gotoFirst(): void;
95
135
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<Listbox<any>, never>;
96
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Listbox<any>, "[ngListbox]", ["ngListbox"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "multi": { "alias": "multi"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "softDisabled": { "alias": "softDisabled"; "required": false; "isSignal": true; }; "focusMode": { "alias": "focusMode"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "typeaheadDelay": { "alias": "typeaheadDelay"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, ["_options"], never, true, [{ directive: typeof ComboboxPopup; inputs: {}; outputs: {}; }]>;
97
- }
98
-
99
- /**
100
- * A selectable option in an `ngListbox`.
101
- *
102
- * This directive should be applied to an element (e.g., `<li>`, `<div>`) within an
103
- * `ngListbox`. The `value` input is used to identify the option, and the `label` input provides
104
- * the accessible name for the option.
105
- *
106
- * ```html
107
- * <li ngOption value="item-id" label="Item Name">
108
- * Item Name
109
- * </li>
110
- * ```
111
- *
112
- * @developerPreview 21.0
113
- *
114
- * @see [Listbox](guide/aria/listbox)
115
- * @see [Autocomplete](guide/aria/autocomplete)
116
- * @see [Select](guide/aria/select)
117
- * @see [Multiselect](guide/aria/multiselect)
118
- */
119
- declare class Option<V> {
120
- /** A reference to the host element. */
121
- readonly element: HTMLElement;
122
- /** Whether the option is currently active (focused). */
123
- readonly active: _angular_core.Signal<boolean>;
124
- /** The parent Listbox. */
125
- private readonly _listbox;
126
- /** A unique identifier for the option. */
127
- readonly id: _angular_core.InputSignal<string>;
128
- /** The parent Listbox UIPattern. */
129
- private readonly _listboxPattern;
130
- /** The value of the option. */
131
- readonly value: _angular_core.InputSignal<V>;
132
- /** Whether an item is disabled. */
133
- readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
134
- /** The text used by the typeahead search. */
135
- readonly label: _angular_core.InputSignal<string | undefined>;
136
- /** Whether the option is selected. */
137
- readonly selected: _angular_core.Signal<boolean | undefined>;
138
- /** The Option UIPattern. */
139
- readonly _pattern: OptionPattern<V>;
140
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<Option<any>, never>;
141
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Option<any>, "[ngOption]", ["ngOption"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
136
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Listbox<any>, "[ngListbox]", ["ngListbox"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "multi": { "alias": "multi"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "softDisabled": { "alias": "softDisabled"; "required": false; "isSignal": true; }; "focusMode": { "alias": "focusMode"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "typeaheadDelay": { "alias": "typeaheadDelay"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabindex"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
142
137
  }
143
138
 
144
- export { Listbox, Option, ComboboxPopup as ɵɵComboboxPopup };
139
+ export { Listbox, Option };
@@ -29,6 +29,10 @@ declare class MenuItemHarness extends ComponentHarness {
29
29
  click(): Promise<void>;
30
30
  /** Resolves the nested submenu panel associated with this menu item, if any exists. */
31
31
  getSubmenu(): Promise<MenuHarness | null>;
32
+ /** Whether the menu item has focus. */
33
+ isFocused(): Promise<boolean>;
34
+ /** Whether the menu item acts as a submenu trigger. */
35
+ hasSubmenu(): Promise<boolean>;
32
36
  }
33
37
  /** Harness for interacting with a standard ngMenu or ngMenuBar in tests. */
34
38
  declare class MenuHarness extends ComponentHarness {
@@ -38,6 +42,8 @@ declare class MenuHarness extends ComponentHarness {
38
42
  _getTrigger(): Promise<TestElement | null>;
39
43
  /** Checks whether the menu container is visible. */
40
44
  isOpen(): Promise<boolean>;
45
+ /** Whether the menu is a menu bar. */
46
+ isMenuBar(): Promise<boolean>;
41
47
  /** Opens the menu if it is currently closed. */
42
48
  open(): Promise<void>;
43
49
  /** Closes the menu if it is currently open. */
package/types/menu.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { Signal } from '@angular/core';
2
+ import { OnDestroy, OnInit, Signal } from '@angular/core';
3
3
  import * as _angular_cdk_bidi from '@angular/cdk/bidi';
4
4
  import { MenuBarPattern, MenuItemPattern, MenuPattern, MenuTriggerPattern } from './_menu-chunk.js';
5
5
  import { DeferredContentAware, DeferredContent } from './_deferred-content-chunk.js';
6
- import { SignalLike } from './_signal-like-chunk.js';
6
+ import { SortedCollection, SignalLike } from './_collection-chunk.js';
7
7
  import './_keyboard-event-manager-chunk.js';
8
8
  import './_list-chunk.js';
9
9
  import './_list-navigation-chunk.js';
@@ -37,9 +37,9 @@ import './_list-navigation-chunk.js';
37
37
  * @see [Menu](guide/aria/menu)
38
38
  * @see [MenuBar](guide/aria/menubar)
39
39
  */
40
- declare class MenuBar<V> {
41
- /** The menu items contained in the menubar. */
42
- readonly _allItems: _angular_core.Signal<readonly MenuItem<V>[]>;
40
+ declare class MenuBar<V> implements OnDestroy {
41
+ /** The collection of menu items. */
42
+ readonly _collection: SortedCollection<MenuItem<V>>;
43
43
  readonly _items: SignalLike<MenuItem<V>[]>;
44
44
  /** A reference to the host element. */
45
45
  private readonly _elementRef;
@@ -64,10 +64,11 @@ declare class MenuBar<V> {
64
64
  /** A callback function triggered when a menu item is selected. */
65
65
  readonly itemSelected: _angular_core.OutputEmitterRef<V>;
66
66
  constructor();
67
+ ngOnDestroy(): void;
67
68
  /** Closes the menubar. */
68
69
  close(): void;
69
70
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MenuBar<any>, never>;
70
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MenuBar<any>, "[ngMenuBar]", ["ngMenuBar"], { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "softDisabled": { "alias": "softDisabled"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "typeaheadDelay": { "alias": "typeaheadDelay"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "itemSelected": "itemSelected"; }, ["_allItems"], never, true, never>;
71
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MenuBar<any>, "[ngMenuBar]", ["ngMenuBar"], { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "softDisabled": { "alias": "softDisabled"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "typeaheadDelay": { "alias": "typeaheadDelay"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "itemSelected": "itemSelected"; }, never, never, true, never>;
71
72
  }
72
73
 
73
74
  /**
@@ -78,7 +79,7 @@ declare class MenuBar<V> {
78
79
  *
79
80
  * ```html
80
81
  * <div ngMenu (itemSelected)="doAction()">
81
- * <div ngMenuItem >Action Item</div>
82
+ * <div ngMenuItem>Action Item</div>
82
83
  * <div ngMenuItem [submenu]="anotherMenu">Submenu Trigger</div>
83
84
  * </div>
84
85
  * ```
@@ -88,14 +89,14 @@ declare class MenuBar<V> {
88
89
  * @see [Menu](guide/aria/menu)
89
90
  * @see [MenuBar](guide/aria/menubar)
90
91
  */
91
- declare class MenuItem<V> {
92
+ declare class MenuItem<V> implements OnInit, OnDestroy {
92
93
  /** A reference to the host element. */
93
94
  private readonly _elementRef;
94
95
  /** A reference to the host element. */
95
96
  readonly element: HTMLElement;
96
97
  /** The unique ID of the menu item. */
97
98
  readonly id: _angular_core.InputSignal<string>;
98
- /** The value of the menu item, used as the default aria-label */
99
+ /** The value of the menu item. */
99
100
  readonly value: _angular_core.InputSignal<V>;
100
101
  /** Whether the menu item is disabled. */
101
102
  readonly disabled: _angular_core.InputSignal<boolean>;
@@ -114,6 +115,8 @@ declare class MenuItem<V> {
114
115
  /** The menu item ui pattern instance. */
115
116
  readonly _pattern: MenuItemPattern<V>;
116
117
  constructor();
118
+ ngOnInit(): void;
119
+ ngOnDestroy(): void;
117
120
  /** Opens the submenu focusing on the first menu item. */
118
121
  open(): void;
119
122
  /** Closes the submenu. */
@@ -149,11 +152,11 @@ declare class MenuItem<V> {
149
152
  * @see [Menu](guide/aria/menu)
150
153
  * @see [MenuBar](guide/aria/menubar)
151
154
  */
152
- declare class Menu<V> {
155
+ declare class Menu<V> implements OnDestroy {
153
156
  /** The DeferredContentAware host directive. */
154
157
  private readonly _deferredContentAware;
155
- /** The menu items contained in the menu. */
156
- readonly _allItems: Signal<readonly MenuItem<V>[]>;
158
+ /** The collection of menu items. */
159
+ readonly _collection: SortedCollection<MenuItem<V>>;
157
160
  /** The menu items that are direct children of this menu. */
158
161
  readonly _items: Signal<MenuItem<V>[]>;
159
162
  /** A reference to the host element. */
@@ -194,10 +197,11 @@ declare class Menu<V> {
194
197
  /** The delay in milliseconds before expanding sub-menus on hover. */
195
198
  readonly expansionDelay: _angular_core.InputSignal<number>;
196
199
  constructor();
200
+ ngOnDestroy(): void;
197
201
  /** Closes the menu. */
198
202
  close(): void;
199
203
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<Menu<any>, never>;
200
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Menu<any>, "[ngMenu]", ["ngMenu"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "typeaheadDelay": { "alias": "typeaheadDelay"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "expansionDelay": { "alias": "expansionDelay"; "required": false; "isSignal": true; }; }, { "itemSelected": "itemSelected"; }, ["_allItems"], never, true, [{ directive: typeof DeferredContentAware; inputs: { "preserveContent": "preserveContent"; }; outputs: {}; }]>;
204
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Menu<any>, "[ngMenu]", ["ngMenu"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "typeaheadDelay": { "alias": "typeaheadDelay"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "expansionDelay": { "alias": "expansionDelay"; "required": false; "isSignal": true; }; }, { "itemSelected": "itemSelected"; }, never, never, true, [{ directive: typeof DeferredContentAware; inputs: { "preserveContent": "preserveContent"; }; outputs: {}; }]>;
201
205
  }
202
206
 
203
207
  /**