@angular/aria 21.0.0-rc.0 → 21.0.0-rc.1

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 (48) hide show
  1. package/_adev_assets/aria-accordion.json +14 -14
  2. package/_adev_assets/aria-combobox.json +10 -10
  3. package/_adev_assets/aria-grid.json +81 -12
  4. package/_adev_assets/aria-listbox.json +3 -3
  5. package/_adev_assets/aria-menu.json +174 -74
  6. package/_adev_assets/aria-tabs.json +22 -22
  7. package/_adev_assets/aria-toolbar.json +99 -120
  8. package/_adev_assets/aria-tree.json +20 -16
  9. package/fesm2022/_widget-chunk.mjs +266 -144
  10. package/fesm2022/_widget-chunk.mjs.map +1 -1
  11. package/fesm2022/accordion.mjs +12 -13
  12. package/fesm2022/accordion.mjs.map +1 -1
  13. package/fesm2022/aria.mjs +1 -1
  14. package/fesm2022/aria.mjs.map +1 -1
  15. package/fesm2022/combobox.mjs +9 -7
  16. package/fesm2022/combobox.mjs.map +1 -1
  17. package/fesm2022/grid.mjs +61 -12
  18. package/fesm2022/grid.mjs.map +1 -1
  19. package/fesm2022/listbox.mjs +14 -15
  20. package/fesm2022/listbox.mjs.map +1 -1
  21. package/fesm2022/menu.mjs +117 -61
  22. package/fesm2022/menu.mjs.map +1 -1
  23. package/fesm2022/private.mjs +390 -399
  24. package/fesm2022/private.mjs.map +1 -1
  25. package/fesm2022/tabs.mjs +16 -17
  26. package/fesm2022/tabs.mjs.map +1 -1
  27. package/fesm2022/toolbar.mjs +79 -44
  28. package/fesm2022/toolbar.mjs.map +1 -1
  29. package/fesm2022/tree.mjs +22 -19
  30. package/fesm2022/tree.mjs.map +1 -1
  31. package/package.json +2 -10
  32. package/types/_grid-chunk.d.ts +115 -53
  33. package/types/accordion.d.ts +4 -4
  34. package/types/combobox.d.ts +2 -2
  35. package/types/grid.d.ts +12 -3
  36. package/types/listbox.d.ts +3 -4
  37. package/types/menu.d.ts +33 -21
  38. package/types/private.d.ts +263 -341
  39. package/types/tabs.d.ts +4 -4
  40. package/types/toolbar.d.ts +29 -26
  41. package/types/tree.d.ts +5 -6
  42. package/_adev_assets/aria-radio-group.json +0 -389
  43. package/fesm2022/deferred-content.mjs +0 -99
  44. package/fesm2022/deferred-content.mjs.map +0 -1
  45. package/fesm2022/radio-group.mjs +0 -338
  46. package/fesm2022/radio-group.mjs.map +0 -1
  47. package/types/deferred-content.d.ts +0 -38
  48. package/types/radio-group.d.ts +0 -84
@@ -1,11 +1,12 @@
1
- import { signal, computed } from '@angular/core';
1
+ import * as i0 from '@angular/core';
2
+ import { signal, computed, model, Directive, inject, TemplateRef, ViewContainerRef, afterRenderEffect } from '@angular/core';
2
3
  import { KeyboardEventManager, PointerEventManager, Modifier } from './_widget-chunk.mjs';
3
4
  export { GridCellPattern, GridCellWidgetPattern, GridPattern, GridRowPattern } from './_widget-chunk.mjs';
4
5
 
5
6
  class ComboboxPattern {
6
7
  inputs;
7
8
  expanded = signal(false);
8
- activedescendant = computed(() => this.inputs.popupControls()?.activeId() ?? null);
9
+ activeDescendant = computed(() => this.inputs.popupControls()?.activeId() ?? null);
9
10
  highlightedItem = signal(undefined);
10
11
  isDeleting = false;
11
12
  isFocused = signal(false);
@@ -14,37 +15,54 @@ class ComboboxPattern {
14
15
  popupId = computed(() => this.inputs.popupControls()?.id() || null);
15
16
  autocomplete = computed(() => this.inputs.filterMode() === 'highlight' ? 'both' : 'list');
16
17
  hasPopup = computed(() => this.inputs.popupControls()?.role() || null);
17
- isInteractive = computed(() => !this.inputs.disabled() && !this.inputs.readonly());
18
+ readonly = computed(() => this.inputs.readonly() || null);
18
19
  keydown = computed(() => {
19
20
  if (!this.expanded()) {
20
- return new KeyboardEventManager().on('ArrowDown', () => this.open({
21
+ const manager = new KeyboardEventManager().on('ArrowDown', () => this.open({
21
22
  first: true
22
23
  })).on('ArrowUp', () => this.open({
23
24
  last: true
25
+ })).on('Escape', () => this.close({
26
+ reset: !this.readonly()
24
27
  }));
28
+ if (this.readonly()) {
29
+ manager.on('Enter', () => this.open({
30
+ selected: true
31
+ })).on(' ', () => this.open({
32
+ selected: true
33
+ }));
34
+ }
35
+ return manager;
25
36
  }
26
37
  const popupControls = this.inputs.popupControls();
27
38
  if (!popupControls) {
28
39
  return new KeyboardEventManager();
29
40
  }
30
- const manager = new KeyboardEventManager().on('ArrowDown', () => this.next()).on('ArrowUp', () => this.prev()).on('Home', () => this.first()).on('End', () => this.last()).on('Escape', () => {
31
- if (this.inputs.filterMode() === 'highlight' && popupControls.activeId()) {
32
- popupControls.unfocus();
33
- popupControls.clearSelection();
34
- const inputEl = this.inputs.inputEl();
35
- if (inputEl) {
36
- inputEl.value = this.inputs.inputValue();
37
- }
38
- } else {
39
- this.close();
40
- this.inputs.popupControls()?.clearSelection();
41
- }
42
- }).on('Enter', () => this.select({
43
- commit: true,
44
- close: true
41
+ const manager = new KeyboardEventManager().on('ArrowDown', () => this.next()).on('ArrowUp', () => this.prev()).on('Home', () => this.first()).on('End', () => this.last()).on('Escape', () => this.close({
42
+ reset: !this.readonly()
45
43
  }));
44
+ if (this.readonly()) {
45
+ manager.on(' ', () => this.select({
46
+ commit: true,
47
+ close: !popupControls.multi()
48
+ }));
49
+ }
50
+ if (popupControls.role() === 'listbox') {
51
+ manager.on('Enter', () => this.select({
52
+ commit: true,
53
+ close: !popupControls.multi()
54
+ }));
55
+ }
46
56
  if (popupControls.role() === 'tree') {
47
57
  const treeControls = popupControls;
58
+ if (treeControls.isItemSelectable()) {
59
+ manager.on('Enter', () => this.select({
60
+ commit: true,
61
+ close: true
62
+ }));
63
+ } else if (treeControls.isItemExpandable()) {
64
+ manager.on('Enter', () => this.expandItem());
65
+ }
48
66
  if (treeControls.isItemExpandable() || treeControls.isItemCollapsible()) {
49
67
  manager.on(this.collapseKey(), () => this.collapseItem());
50
68
  }
@@ -57,32 +75,44 @@ class ComboboxPattern {
57
75
  pointerup = computed(() => new PointerEventManager().on(e => {
58
76
  const item = this.inputs.popupControls()?.getItem(e);
59
77
  if (item) {
78
+ if (this.inputs.popupControls()?.role() === 'tree') {
79
+ const treeControls = this.inputs.popupControls();
80
+ if (treeControls.isItemExpandable(item) && !treeControls.isItemSelectable(item)) {
81
+ treeControls.toggleExpansion(item);
82
+ this.inputs.inputEl()?.focus();
83
+ return;
84
+ }
85
+ }
60
86
  this.select({
61
87
  item,
62
88
  commit: true,
63
- close: true
89
+ close: !this.inputs.popupControls()?.multi()
64
90
  });
65
91
  this.inputs.inputEl()?.focus();
66
92
  }
67
93
  if (e.target === this.inputs.inputEl()) {
68
- this.open();
94
+ if (this.readonly()) {
95
+ this.expanded() ? this.close() : this.open({
96
+ selected: true
97
+ });
98
+ }
69
99
  }
70
100
  }));
71
101
  constructor(inputs) {
72
102
  this.inputs = inputs;
73
103
  }
74
104
  onKeydown(event) {
75
- if (this.isInteractive()) {
105
+ if (!this.inputs.disabled()) {
76
106
  this.keydown().handle(event);
77
107
  }
78
108
  }
79
109
  onPointerup(event) {
80
- if (this.isInteractive()) {
110
+ if (!this.inputs.disabled()) {
81
111
  this.pointerup().handle(event);
82
112
  }
83
113
  }
84
114
  onInput(event) {
85
- if (!this.isInteractive()) {
115
+ if (this.inputs.disabled() || this.inputs.readonly()) {
86
116
  return;
87
117
  }
88
118
  const inputEl = this.inputs.inputEl();
@@ -93,21 +123,29 @@ class ComboboxPattern {
93
123
  this.inputs.inputValue?.set(inputEl.value);
94
124
  this.isDeleting = event instanceof InputEvent && !!event.inputType.match(/^delete/);
95
125
  if (this.inputs.filterMode() === 'manual') {
96
- const searchTerm = this.inputs.popupControls()?.getSelectedItem()?.searchTerm();
126
+ const selectedItems = this.inputs.popupControls()?.getSelectedItems();
127
+ const searchTerm = selectedItems?.[0]?.searchTerm();
97
128
  if (searchTerm && this.inputs.inputValue() !== searchTerm) {
98
129
  this.inputs.popupControls()?.clearSelection();
99
130
  }
100
131
  }
132
+ if (this.inputs.filterMode() === 'highlight' && !this.isDeleting) {
133
+ this.highlight();
134
+ }
101
135
  }
102
136
  onFocusIn() {
103
137
  this.isFocused.set(true);
104
138
  }
105
139
  onFocusOut(event) {
106
- if (this.inputs.disabled() || this.inputs.readonly()) {
140
+ if (this.inputs.disabled()) {
107
141
  return;
108
142
  }
109
143
  if (!(event.relatedTarget instanceof HTMLElement) || !this.inputs.containerEl()?.contains(event.relatedTarget)) {
110
144
  this.isFocused.set(false);
145
+ if (this.readonly()) {
146
+ this.close();
147
+ return;
148
+ }
111
149
  if (this.inputs.filterMode() !== 'manual') {
112
150
  this.commit();
113
151
  } else {
@@ -128,6 +166,9 @@ class ComboboxPattern {
128
166
  return this.inputs.popupControls()?.items().find(i => i.value() === this.inputs.firstMatch());
129
167
  });
130
168
  onFilter() {
169
+ if (this.readonly()) {
170
+ return;
171
+ }
131
172
  const isInitialRender = !this.inputs.inputValue?.().length && !this.isDeleting;
132
173
  if (isInitialRender) {
133
174
  return;
@@ -157,7 +198,8 @@ class ComboboxPattern {
157
198
  }
158
199
  highlight() {
159
200
  const inputEl = this.inputs.inputEl();
160
- const item = this.inputs.popupControls()?.getSelectedItem();
201
+ const selectedItems = this.inputs.popupControls()?.getSelectedItems();
202
+ const item = selectedItems?.[0];
161
203
  if (!inputEl || !item) {
162
204
  return;
163
205
  }
@@ -168,18 +210,52 @@ class ComboboxPattern {
168
210
  this.highlightedItem.set(item);
169
211
  }
170
212
  }
171
- close() {
172
- this.expanded.set(false);
173
- this.inputs.popupControls()?.unfocus();
213
+ close(opts) {
214
+ if (!opts?.reset) {
215
+ this.expanded.set(false);
216
+ this.inputs.popupControls()?.unfocus();
217
+ return;
218
+ }
219
+ const popupControls = this.inputs.popupControls();
220
+ if (!this.expanded()) {
221
+ this.inputs.inputValue?.set('');
222
+ popupControls?.clearSelection();
223
+ const inputEl = this.inputs.inputEl();
224
+ if (inputEl) {
225
+ inputEl.value = '';
226
+ }
227
+ } else if (this.expanded()) {
228
+ this.close();
229
+ const selectedItem = popupControls?.getSelectedItems()?.[0];
230
+ if (selectedItem?.searchTerm() !== this.inputs.inputValue()) {
231
+ popupControls?.clearSelection();
232
+ }
233
+ }
234
+ this.close();
235
+ if (!this.readonly()) {
236
+ this.inputs.popupControls()?.clearSelection();
237
+ }
174
238
  }
175
239
  open(nav) {
176
240
  this.expanded.set(true);
241
+ const inputEl = this.inputs.inputEl();
242
+ if (inputEl && this.inputs.filterMode() === 'highlight') {
243
+ const isHighlighting = inputEl.selectionStart !== inputEl.value.length;
244
+ this.inputs.inputValue?.set(inputEl.value.slice(0, inputEl.selectionStart || 0));
245
+ if (!isHighlighting) {
246
+ this.highlightedItem.set(undefined);
247
+ }
248
+ }
177
249
  if (nav?.first) {
178
250
  this.first();
179
251
  }
180
252
  if (nav?.last) {
181
253
  this.last();
182
254
  }
255
+ if (nav?.selected) {
256
+ const selectedItem = this.inputs.popupControls()?.items().find(i => this.inputs.popupControls()?.getSelectedItems().includes(i));
257
+ selectedItem ? this.inputs.popupControls()?.focus(selectedItem) : this.first();
258
+ }
183
259
  }
184
260
  next() {
185
261
  this._navigate(() => this.inputs.popupControls()?.next());
@@ -202,7 +278,13 @@ class ComboboxPattern {
202
278
  this._navigate(() => controls?.expandItem());
203
279
  }
204
280
  select(opts = {}) {
205
- this.inputs.popupControls()?.select(opts.item);
281
+ const controls = this.inputs.popupControls();
282
+ if (opts.item) {
283
+ controls?.focus(opts.item, {
284
+ focusElement: false
285
+ });
286
+ }
287
+ controls?.multi() ? controls.toggle(opts.item) : controls?.select(opts.item);
206
288
  if (opts.commit) {
207
289
  this.commit();
208
290
  }
@@ -212,14 +294,15 @@ class ComboboxPattern {
212
294
  }
213
295
  commit() {
214
296
  const inputEl = this.inputs.inputEl();
215
- const item = this.inputs.popupControls()?.getSelectedItem();
216
- if (inputEl && item) {
217
- inputEl.value = item.searchTerm();
218
- this.inputs.inputValue?.set(item.searchTerm());
219
- if (this.inputs.filterMode() === 'highlight') {
220
- const length = inputEl.value.length;
221
- inputEl.setSelectionRange(length, length);
222
- }
297
+ const selectedItems = this.inputs.popupControls()?.getSelectedItems();
298
+ if (!inputEl) {
299
+ return;
300
+ }
301
+ inputEl.value = selectedItems?.map(i => i.searchTerm()).join(', ') || '';
302
+ this.inputs.inputValue?.set(inputEl.value);
303
+ if (this.inputs.filterMode() === 'highlight' && !this.readonly()) {
304
+ const length = inputEl.value.length;
305
+ inputEl.setSelectionRange(length, length);
223
306
  }
224
307
  }
225
308
  _navigate(operation) {
@@ -228,7 +311,7 @@ class ComboboxPattern {
228
311
  this.select();
229
312
  }
230
313
  if (this.inputs.filterMode() === 'highlight') {
231
- const selectedItem = this.inputs.popupControls()?.getSelectedItem();
314
+ const selectedItem = this.inputs.popupControls()?.getSelectedItems()[0];
232
315
  if (!selectedItem) {
233
316
  return;
234
317
  }
@@ -266,13 +349,13 @@ class ListFocus {
266
349
  }
267
350
  return this.inputs.activeItem()?.id() ?? undefined;
268
351
  }
269
- getListTabindex() {
352
+ getListTabIndex() {
270
353
  if (this.isListDisabled()) {
271
354
  return 0;
272
355
  }
273
356
  return this.inputs.focusMode() === 'activedescendant' ? 0 : -1;
274
357
  }
275
- getItemTabindex(item) {
358
+ getItemTabIndex(item) {
276
359
  if (this.isListDisabled()) {
277
360
  return -1;
278
361
  }
@@ -288,12 +371,12 @@ class ListFocus {
288
371
  this.prevActiveItem.set(this.inputs.activeItem());
289
372
  this.inputs.activeItem.set(item);
290
373
  if (opts?.focusElement || opts?.focusElement === undefined) {
291
- this.inputs.focusMode() === 'roving' ? item.element().focus() : this.inputs.element()?.focus();
374
+ this.inputs.focusMode() === 'roving' ? item.element()?.focus() : this.inputs.element()?.focus();
292
375
  }
293
376
  return true;
294
377
  }
295
378
  isFocusable(item) {
296
- return !item.disabled() || !this.inputs.skipDisabled();
379
+ return !item.disabled() || this.inputs.softDisabled();
297
380
  }
298
381
  }
299
382
 
@@ -318,17 +401,23 @@ class ListNavigation {
318
401
  return this._peek(-1);
319
402
  }
320
403
  first(opts) {
321
- const item = this.inputs.items().find(i => this.inputs.focusManager.isFocusable(i));
404
+ const item = this.peekFirst();
322
405
  return item ? this.goto(item, opts) : false;
323
406
  }
324
407
  last(opts) {
325
- const items = this.inputs.items();
408
+ const item = this.peekLast();
409
+ return item ? this.goto(item, opts) : false;
410
+ }
411
+ peekFirst(items = this.inputs.items()) {
412
+ return items.find(i => this.inputs.focusManager.isFocusable(i));
413
+ }
414
+ peekLast(items = this.inputs.items()) {
326
415
  for (let i = items.length - 1; i >= 0; i--) {
327
416
  if (this.inputs.focusManager.isFocusable(items[i])) {
328
- return this.goto(items[i], opts);
417
+ return items[i];
329
418
  }
330
419
  }
331
- return false;
420
+ return;
332
421
  }
333
422
  _advance(delta, opts) {
334
423
  const item = this._peek(delta);
@@ -378,10 +467,10 @@ class ListSelection {
378
467
  this.inputs.value.update(values => values.filter(value => value !== item.value()));
379
468
  }
380
469
  }
381
- toggle() {
382
- const item = this.inputs.focusManager.inputs.activeItem();
470
+ toggle(item) {
471
+ item = item ?? this.inputs.focusManager.inputs.activeItem();
383
472
  if (item) {
384
- this.inputs.value().includes(item.value()) ? this.deselect() : this.select();
473
+ this.inputs.value().includes(item.value()) ? this.deselect(item) : this.select(item);
385
474
  }
386
475
  }
387
476
  toggleOne() {
@@ -522,8 +611,8 @@ class List {
522
611
  typeaheadBehavior;
523
612
  focusBehavior;
524
613
  disabled = computed(() => this.focusBehavior.isListDisabled());
525
- activedescendant = computed(() => this.focusBehavior.getActiveDescendant());
526
- tabindex = computed(() => this.focusBehavior.getListTabindex());
614
+ activeDescendant = computed(() => this.focusBehavior.getActiveDescendant());
615
+ tabIndex = computed(() => this.focusBehavior.getListTabIndex());
527
616
  activeIndex = computed(() => this.focusBehavior.activeIndex());
528
617
  _anchorIndex = signal(0);
529
618
  _wrap = signal(true);
@@ -545,7 +634,7 @@ class List {
545
634
  });
546
635
  }
547
636
  getItemTabindex(item) {
548
- return this.focusBehavior.getItemTabindex(item);
637
+ return this.focusBehavior.getItemTabIndex(item);
549
638
  }
550
639
  first(opts) {
551
640
  this._navigate(opts, () => this.navigationBehavior.first(opts));
@@ -580,14 +669,14 @@ class List {
580
669
  selectOne() {
581
670
  this.selectionBehavior.selectOne();
582
671
  }
583
- deselect() {
584
- this.selectionBehavior.deselect();
672
+ deselect(item) {
673
+ this.selectionBehavior.deselect(item);
585
674
  }
586
675
  deselectAll() {
587
676
  this.selectionBehavior.deselectAll();
588
677
  }
589
- toggle() {
590
- this.selectionBehavior.toggle();
678
+ toggle(item) {
679
+ this.selectionBehavior.toggle(item);
591
680
  }
592
681
  toggleOne() {
593
682
  this.selectionBehavior.toggleOne();
@@ -636,8 +725,8 @@ class ListboxPattern {
636
725
  orientation;
637
726
  disabled = computed(() => this.listBehavior.disabled());
638
727
  readonly;
639
- tabindex = computed(() => this.listBehavior.tabindex());
640
- activedescendant = computed(() => this.listBehavior.activedescendant());
728
+ tabIndex = computed(() => this.listBehavior.tabIndex());
729
+ activeDescendant = computed(() => this.listBehavior.activeDescendant());
641
730
  multi;
642
731
  setsize = computed(() => this.inputs.items().length);
643
732
  followFocus = computed(() => this.inputs.selectionMode() === 'follow');
@@ -805,7 +894,7 @@ class OptionPattern {
805
894
  disabled;
806
895
  searchTerm;
807
896
  listbox;
808
- tabindex = computed(() => this.listbox()?.listBehavior.getItemTabindex(this));
897
+ tabIndex = computed(() => this.listbox()?.listBehavior.getItemTabindex(this));
809
898
  element;
810
899
  constructor(args) {
811
900
  this.id = args.id;
@@ -821,12 +910,14 @@ class ComboboxListboxPattern extends ListboxPattern {
821
910
  inputs;
822
911
  id = computed(() => this.inputs.id());
823
912
  role = computed(() => 'listbox');
824
- activeId = computed(() => this.listBehavior.activedescendant());
913
+ activeId = computed(() => this.listBehavior.activeDescendant());
825
914
  items = computed(() => this.inputs.items());
826
- tabindex = () => -1;
915
+ tabIndex = () => -1;
916
+ multi = computed(() => {
917
+ return this.inputs.combobox()?.readonly() ? this.inputs.multi() : false;
918
+ });
827
919
  constructor(inputs) {
828
920
  if (inputs.combobox()) {
829
- inputs.multi = () => false;
830
921
  inputs.focusMode = () => 'activedescendant';
831
922
  inputs.element = inputs.combobox().inputs.inputEl;
832
923
  }
@@ -836,16 +927,28 @@ class ComboboxListboxPattern extends ListboxPattern {
836
927
  onKeydown(_) {}
837
928
  onPointerdown(_) {}
838
929
  setDefaultState() {}
839
- focus = item => this.listBehavior.goto(item);
930
+ focus = (item, opts) => {
931
+ this.listBehavior.goto(item, opts);
932
+ };
840
933
  next = () => this.listBehavior.next();
841
934
  prev = () => this.listBehavior.prev();
842
935
  last = () => this.listBehavior.last();
843
936
  first = () => this.listBehavior.first();
844
937
  unfocus = () => this.listBehavior.unfocus();
845
938
  select = item => this.listBehavior.select(item);
939
+ toggle = item => this.listBehavior.toggle(item);
846
940
  clearSelection = () => this.listBehavior.deselectAll();
847
941
  getItem = e => this._getItem(e);
848
- getSelectedItem = () => this.inputs.items().find(i => i.selected());
942
+ getSelectedItems = () => {
943
+ const items = [];
944
+ for (const value of this.inputs.value()) {
945
+ const item = this.items().find(i => i.value() === value);
946
+ if (item) {
947
+ items.push(item);
948
+ }
949
+ }
950
+ return items;
951
+ };
849
952
  setValue = value => this.inputs.value.set(value ? [value] : []);
850
953
  }
851
954
 
@@ -974,7 +1077,7 @@ class MenuPattern {
974
1077
  if (parent instanceof MenuItemPattern) {
975
1078
  const grandparent = parent.inputs.parent();
976
1079
  const siblings = grandparent?.inputs.items().filter(i => i !== parent);
977
- const item = siblings?.find(i => i.element().contains(relatedTarget));
1080
+ const item = siblings?.find(i => i.element()?.contains(relatedTarget));
978
1081
  if (item) {
979
1082
  return;
980
1083
  }
@@ -1011,17 +1114,20 @@ class MenuPattern {
1011
1114
  const isMenu = root instanceof MenuPattern;
1012
1115
  const isMenuBar = root instanceof MenuBarPattern;
1013
1116
  const isMenuTrigger = root instanceof MenuTriggerPattern;
1014
- if (!item.submenu() && (isMenuTrigger || isMenuBar)) {
1117
+ if (!item.submenu() && isMenuTrigger) {
1015
1118
  root.close({
1016
1119
  refocus: true
1017
1120
  });
1018
- root?.inputs.onSubmit?.(item.value());
1121
+ }
1122
+ if (!item.submenu() && isMenuBar) {
1123
+ root.close();
1124
+ root?.inputs.onSelect?.(item.value());
1019
1125
  }
1020
1126
  if (!item.submenu() && isMenu) {
1021
1127
  root.inputs.activeItem()?.close({
1022
1128
  refocus: true
1023
1129
  });
1024
- root?.inputs.onSubmit?.(item.value());
1130
+ root?.inputs.onSelect?.(item.value());
1025
1131
  }
1026
1132
  }
1027
1133
  }
@@ -1173,8 +1279,8 @@ class MenuTriggerPattern {
1173
1279
  expanded = signal(false);
1174
1280
  role = () => 'button';
1175
1281
  hasPopup = () => true;
1176
- submenu;
1177
- tabindex = computed(() => this.expanded() && this.submenu()?.inputs.activeItem() ? -1 : 0);
1282
+ menu;
1283
+ tabIndex = computed(() => this.expanded() && this.menu()?.inputs.activeItem() ? -1 : 0);
1178
1284
  keydownManager = computed(() => {
1179
1285
  return new KeyboardEventManager().on(' ', () => this.open({
1180
1286
  first: true
@@ -1190,7 +1296,7 @@ class MenuTriggerPattern {
1190
1296
  });
1191
1297
  constructor(inputs) {
1192
1298
  this.inputs = inputs;
1193
- this.submenu = this.inputs.submenu;
1299
+ this.menu = this.inputs.menu;
1194
1300
  }
1195
1301
  onKeydown(event) {
1196
1302
  this.keydownManager().handle(event);
@@ -1203,25 +1309,25 @@ class MenuTriggerPattern {
1203
1309
  onFocusOut(event) {
1204
1310
  const element = this.inputs.element();
1205
1311
  const relatedTarget = event.relatedTarget;
1206
- if (this.expanded() && !element?.contains(relatedTarget) && !this.inputs.submenu()?.inputs.element()?.contains(relatedTarget)) {
1312
+ if (this.expanded() && !element?.contains(relatedTarget) && !this.inputs.menu()?.inputs.element()?.contains(relatedTarget)) {
1207
1313
  this.close();
1208
1314
  }
1209
1315
  }
1210
1316
  open(opts) {
1211
1317
  this.expanded.set(true);
1212
1318
  if (opts?.first) {
1213
- this.inputs.submenu()?.first();
1319
+ this.inputs.menu()?.first();
1214
1320
  } else if (opts?.last) {
1215
- this.inputs.submenu()?.last();
1321
+ this.inputs.menu()?.last();
1216
1322
  }
1217
1323
  }
1218
1324
  close(opts = {}) {
1219
1325
  this.expanded.set(false);
1220
- this.submenu()?.listBehavior.unfocus();
1326
+ this.menu()?.listBehavior.unfocus();
1221
1327
  if (opts.refocus) {
1222
1328
  this.inputs.element()?.focus();
1223
1329
  }
1224
- let menuitems = this.inputs.submenu()?.inputs.items() ?? [];
1330
+ let menuitems = this.inputs.menu()?.inputs.items() ?? [];
1225
1331
  while (menuitems.length) {
1226
1332
  const menuitem = menuitems.pop();
1227
1333
  menuitem?._expanded.set(false);
@@ -1238,7 +1344,7 @@ class MenuItemPattern {
1238
1344
  searchTerm;
1239
1345
  element;
1240
1346
  isActive = computed(() => this.inputs.parent()?.inputs.activeItem() === this);
1241
- tabindex = computed(() => {
1347
+ tabIndex = computed(() => {
1242
1348
  if (this.submenu() && this.submenu()?.inputs.activeItem()) {
1243
1349
  return -1;
1244
1350
  }
@@ -1286,171 +1392,6 @@ class MenuItemPattern {
1286
1392
  }
1287
1393
  }
1288
1394
 
1289
- class RadioGroupPattern {
1290
- inputs;
1291
- listBehavior;
1292
- orientation;
1293
- wrap = signal(false);
1294
- selectionMode = signal('follow');
1295
- disabled = computed(() => this.inputs.disabled() || this.listBehavior.disabled());
1296
- selectedItem = computed(() => this.listBehavior.selectionBehavior.selectedItems()[0]);
1297
- readonly = computed(() => this.selectedItem()?.disabled() || this.inputs.readonly());
1298
- tabindex = computed(() => this.listBehavior.tabindex());
1299
- activedescendant = computed(() => this.listBehavior.activedescendant());
1300
- _prevKey = computed(() => {
1301
- if (this.inputs.orientation() === 'vertical') {
1302
- return 'ArrowUp';
1303
- }
1304
- return this.inputs.textDirection() === 'rtl' ? 'ArrowRight' : 'ArrowLeft';
1305
- });
1306
- _nextKey = computed(() => {
1307
- if (this.inputs.orientation() === 'vertical') {
1308
- return 'ArrowDown';
1309
- }
1310
- return this.inputs.textDirection() === 'rtl' ? 'ArrowLeft' : 'ArrowRight';
1311
- });
1312
- keydown = computed(() => {
1313
- const manager = new KeyboardEventManager();
1314
- if (this.readonly()) {
1315
- return manager.on(this._prevKey, () => this.listBehavior.prev()).on(this._nextKey, () => this.listBehavior.next()).on('Home', () => this.listBehavior.first()).on('End', () => this.listBehavior.last());
1316
- }
1317
- return manager.on(this._prevKey, () => this.listBehavior.prev({
1318
- selectOne: true
1319
- })).on(this._nextKey, () => this.listBehavior.next({
1320
- selectOne: true
1321
- })).on('Home', () => this.listBehavior.first({
1322
- selectOne: true
1323
- })).on('End', () => this.listBehavior.last({
1324
- selectOne: true
1325
- })).on(' ', () => this.listBehavior.selectOne()).on('Enter', () => this.listBehavior.selectOne());
1326
- });
1327
- pointerdown = computed(() => {
1328
- const manager = new PointerEventManager();
1329
- if (this.readonly()) {
1330
- return manager.on(e => this.listBehavior.goto(this.inputs.getItem(e)));
1331
- }
1332
- return manager.on(e => this.listBehavior.goto(this.inputs.getItem(e), {
1333
- selectOne: true
1334
- }));
1335
- });
1336
- constructor(inputs) {
1337
- this.inputs = inputs;
1338
- this.orientation = inputs.orientation;
1339
- this.listBehavior = new List({
1340
- ...inputs,
1341
- wrap: this.wrap,
1342
- selectionMode: this.selectionMode,
1343
- multi: () => false,
1344
- typeaheadDelay: () => 0
1345
- });
1346
- }
1347
- onKeydown(event) {
1348
- if (!this.disabled()) {
1349
- this.keydown().handle(event);
1350
- }
1351
- }
1352
- onPointerdown(event) {
1353
- if (!this.disabled()) {
1354
- this.pointerdown().handle(event);
1355
- }
1356
- }
1357
- setDefaultState() {
1358
- let firstItem = null;
1359
- for (const item of this.inputs.items()) {
1360
- if (this.listBehavior.isFocusable(item)) {
1361
- if (!firstItem) {
1362
- firstItem = item;
1363
- }
1364
- if (item.selected()) {
1365
- this.inputs.activeItem.set(item);
1366
- return;
1367
- }
1368
- }
1369
- }
1370
- if (firstItem) {
1371
- this.inputs.activeItem.set(firstItem);
1372
- }
1373
- }
1374
- validate() {
1375
- const violations = [];
1376
- if (this.selectedItem()?.disabled() && this.inputs.skipDisabled()) {
1377
- violations.push("Accessibility Violation: The selected radio button is disabled while 'skipDisabled' is true, making the selection unreachable via keyboard.");
1378
- }
1379
- return violations;
1380
- }
1381
- }
1382
-
1383
- class RadioButtonPattern {
1384
- inputs;
1385
- id;
1386
- value;
1387
- index = computed(() => this.group()?.listBehavior.inputs.items().indexOf(this) ?? -1);
1388
- active = computed(() => this.group()?.listBehavior.inputs.activeItem() === this);
1389
- selected = computed(() => !!this.group()?.listBehavior.inputs.value().includes(this.value()));
1390
- selectable = () => true;
1391
- disabled;
1392
- group;
1393
- tabindex = computed(() => this.group()?.listBehavior.getItemTabindex(this));
1394
- element;
1395
- searchTerm = () => '';
1396
- constructor(inputs) {
1397
- this.inputs = inputs;
1398
- this.id = inputs.id;
1399
- this.value = inputs.value;
1400
- this.group = inputs.group;
1401
- this.element = inputs.element;
1402
- this.disabled = inputs.disabled;
1403
- }
1404
- }
1405
-
1406
- class ToolbarRadioGroupPattern extends RadioGroupPattern {
1407
- inputs;
1408
- constructor(inputs) {
1409
- if (!!inputs.toolbar()) {
1410
- inputs.orientation = inputs.toolbar().orientation;
1411
- inputs.skipDisabled = inputs.toolbar().skipDisabled;
1412
- }
1413
- super(inputs);
1414
- this.inputs = inputs;
1415
- }
1416
- onKeydown(_) {}
1417
- onPointerdown(_) {}
1418
- isOnFirstItem() {
1419
- return this.listBehavior.navigationBehavior.peekPrev() === undefined;
1420
- }
1421
- isOnLastItem() {
1422
- return this.listBehavior.navigationBehavior.peekNext() === undefined;
1423
- }
1424
- next(wrap) {
1425
- this.wrap.set(wrap);
1426
- this.listBehavior.next();
1427
- this.wrap.set(false);
1428
- }
1429
- prev(wrap) {
1430
- this.wrap.set(wrap);
1431
- this.listBehavior.prev();
1432
- this.wrap.set(false);
1433
- }
1434
- first() {
1435
- this.listBehavior.first();
1436
- }
1437
- last() {
1438
- this.listBehavior.last();
1439
- }
1440
- unfocus() {
1441
- this.inputs.activeItem.set(undefined);
1442
- }
1443
- trigger() {
1444
- if (this.readonly()) return;
1445
- this.listBehavior.selectOne();
1446
- }
1447
- goto(e) {
1448
- this.listBehavior.goto(this.inputs.getItem(e), {
1449
- selectOne: !this.readonly()
1450
- });
1451
- }
1452
- }
1453
-
1454
1395
  function convertGetterSetterToWritableSignalLike(getter, setter) {
1455
1396
  return Object.assign(getter, {
1456
1397
  set: setter,
@@ -1556,7 +1497,7 @@ class TabPattern {
1556
1497
  expanded = computed(() => this.expansion.isExpanded());
1557
1498
  active = computed(() => this.inputs.tablist().inputs.activeItem() === this);
1558
1499
  selected = computed(() => !!this.inputs.tablist().inputs.value().includes(this.value()));
1559
- tabindex = computed(() => this.inputs.tablist().listBehavior.getItemTabindex(this));
1500
+ tabIndex = computed(() => this.inputs.tablist().listBehavior.getItemTabindex(this));
1560
1501
  controls = computed(() => this.inputs.tabpanel()?.id());
1561
1502
  constructor(inputs) {
1562
1503
  this.inputs = inputs;
@@ -1578,7 +1519,7 @@ class TabPanelPattern {
1578
1519
  value;
1579
1520
  labelManager;
1580
1521
  hidden = computed(() => this.inputs.tab()?.expanded() === false);
1581
- tabindex = computed(() => this.hidden() ? -1 : 0);
1522
+ tabIndex = computed(() => this.hidden() ? -1 : 0);
1582
1523
  labelledBy = computed(() => this.labelManager.labelledBy().length > 0 ? this.labelManager.labelledBy().join(' ') : undefined);
1583
1524
  constructor(inputs) {
1584
1525
  this.inputs = inputs;
@@ -1596,8 +1537,8 @@ class TabListPattern {
1596
1537
  expansionManager;
1597
1538
  orientation;
1598
1539
  disabled;
1599
- tabindex = computed(() => this.listBehavior.tabindex());
1600
- activedescendant = computed(() => this.listBehavior.activedescendant());
1540
+ tabIndex = computed(() => this.listBehavior.tabIndex());
1541
+ activeDescendant = computed(() => this.listBehavior.activeDescendant());
1601
1542
  followFocus = computed(() => this.inputs.selectionMode() === 'follow');
1602
1543
  prevKey = computed(() => {
1603
1544
  if (this.inputs.orientation() === 'vertical') {
@@ -1677,67 +1618,15 @@ class TabListPattern {
1677
1618
  }
1678
1619
  }
1679
1620
 
1680
- class ToolbarWidgetPattern {
1681
- inputs;
1682
- id;
1683
- element;
1684
- disabled;
1685
- toolbar;
1686
- tabindex = computed(() => this.toolbar().listBehavior.getItemTabindex(this));
1687
- searchTerm = () => '';
1688
- value = () => '';
1689
- selectable = () => true;
1690
- index = computed(() => this.toolbar().inputs.items().indexOf(this) ?? -1);
1691
- active = computed(() => this.toolbar().inputs.activeItem() === this);
1692
- constructor(inputs) {
1693
- this.inputs = inputs;
1694
- this.id = inputs.id;
1695
- this.element = inputs.element;
1696
- this.disabled = inputs.disabled;
1697
- this.toolbar = inputs.toolbar;
1698
- }
1699
- }
1700
-
1701
- class ToolbarWidgetGroupPattern {
1702
- inputs;
1703
- id;
1704
- element;
1705
- disabled;
1706
- toolbar;
1707
- searchTerm = () => '';
1708
- value = () => '';
1709
- selectable = () => true;
1710
- index = computed(() => this.toolbar()?.inputs.items().indexOf(this) ?? -1);
1711
- controls = computed(() => this.inputs.controls() ?? this._defaultControls);
1712
- _defaultControls = {
1713
- isOnFirstItem: () => true,
1714
- isOnLastItem: () => true,
1715
- next: () => {},
1716
- prev: () => {},
1717
- first: () => {},
1718
- last: () => {},
1719
- unfocus: () => {},
1720
- trigger: () => {},
1721
- goto: () => {},
1722
- setDefaultState: () => {}
1723
- };
1724
- constructor(inputs) {
1725
- this.inputs = inputs;
1726
- this.id = inputs.id;
1727
- this.element = inputs.element;
1728
- this.disabled = inputs.disabled;
1729
- this.toolbar = inputs.toolbar;
1730
- }
1731
- }
1732
-
1733
1621
  class ToolbarPattern {
1734
1622
  inputs;
1735
1623
  listBehavior;
1736
1624
  orientation;
1737
- skipDisabled;
1625
+ softDisabled;
1738
1626
  disabled = computed(() => this.listBehavior.disabled());
1739
- tabindex = computed(() => this.listBehavior.tabindex());
1740
- activedescendant = computed(() => this.listBehavior.activedescendant());
1627
+ tabIndex = computed(() => this.listBehavior.tabIndex());
1628
+ activeDescendant = computed(() => this.listBehavior.activeDescendant());
1629
+ activeItem = () => this.listBehavior.inputs.activeItem();
1741
1630
  _prevKey = computed(() => {
1742
1631
  if (this.inputs.orientation() === 'vertical') {
1743
1632
  return 'ArrowUp';
@@ -1764,92 +1653,53 @@ class ToolbarPattern {
1764
1653
  });
1765
1654
  _keydown = computed(() => {
1766
1655
  const manager = new KeyboardEventManager();
1767
- return manager.on(this._nextKey, () => this._next()).on(this._prevKey, () => this._prev()).on(this._altNextKey, () => this._groupNext()).on(this._altPrevKey, () => this._groupPrev()).on(' ', () => this._trigger()).on('Enter', () => this._trigger()).on('Home', () => this._first()).on('End', () => this._last());
1656
+ return manager.on(this._nextKey, () => this.listBehavior.next()).on(this._prevKey, () => this.listBehavior.prev()).on(this._altNextKey, () => this._groupNext()).on(this._altPrevKey, () => this._groupPrev()).on(' ', () => this.select()).on('Enter', () => this.select()).on('Home', () => this.listBehavior.first()).on('End', () => this.listBehavior.last());
1768
1657
  });
1769
- _pointerdown = computed(() => new PointerEventManager().on(e => this._goto(e)));
1770
- _next() {
1771
- const item = this.inputs.activeItem();
1772
- if (item instanceof ToolbarWidgetGroupPattern) {
1773
- if (!item.disabled() && !item.controls().isOnLastItem()) {
1774
- item.controls().next(false);
1775
- return;
1776
- }
1777
- item.controls().unfocus();
1778
- }
1779
- this.listBehavior.next();
1780
- const newItem = this.inputs.activeItem();
1781
- if (newItem instanceof ToolbarWidgetGroupPattern) {
1782
- newItem.controls().first();
1783
- }
1784
- }
1785
- _prev() {
1786
- const item = this.inputs.activeItem();
1787
- if (item instanceof ToolbarWidgetGroupPattern) {
1788
- if (!item.disabled() && !item.controls().isOnFirstItem()) {
1789
- item.controls().prev(false);
1790
- return;
1791
- }
1792
- item.controls().unfocus();
1793
- }
1794
- this.listBehavior.prev();
1795
- const newItem = this.inputs.activeItem();
1796
- if (newItem instanceof ToolbarWidgetGroupPattern) {
1797
- newItem.controls().last();
1798
- }
1799
- }
1800
1658
  _groupNext() {
1801
- const item = this.inputs.activeItem();
1802
- if (item instanceof ToolbarWidgetPattern) return;
1803
- item?.controls().next(true);
1804
- }
1805
- _groupPrev() {
1806
- const item = this.inputs.activeItem();
1807
- if (item instanceof ToolbarWidgetPattern) return;
1808
- item?.controls().prev(true);
1809
- }
1810
- _trigger() {
1811
- const item = this.inputs.activeItem();
1812
- if (item instanceof ToolbarWidgetGroupPattern) {
1813
- item.controls().trigger();
1814
- }
1815
- }
1816
- _first() {
1817
- const item = this.inputs.activeItem();
1818
- if (item instanceof ToolbarWidgetGroupPattern) {
1819
- item.controls().unfocus();
1659
+ const currGroup = this.inputs.activeItem()?.group();
1660
+ const nextGroup = this.listBehavior.navigationBehavior.peekNext()?.group();
1661
+ if (!currGroup) {
1662
+ return;
1820
1663
  }
1821
- this.listBehavior.first();
1822
- const newItem = this.inputs.activeItem();
1823
- if (newItem instanceof ToolbarWidgetGroupPattern) {
1824
- newItem.controls().first();
1664
+ if (currGroup !== nextGroup) {
1665
+ this.listBehavior.goto(this.listBehavior.navigationBehavior.peekFirst(currGroup.inputs.items()));
1666
+ return;
1825
1667
  }
1668
+ this.listBehavior.next();
1826
1669
  }
1827
- _last() {
1828
- const item = this.inputs.activeItem();
1829
- if (item instanceof ToolbarWidgetGroupPattern) {
1830
- item.controls().unfocus();
1670
+ _groupPrev() {
1671
+ const currGroup = this.inputs.activeItem()?.group();
1672
+ const nextGroup = this.listBehavior.navigationBehavior.peekPrev()?.group();
1673
+ if (!currGroup) {
1674
+ return;
1831
1675
  }
1832
- this.listBehavior.last();
1833
- const newItem = this.inputs.activeItem();
1834
- if (newItem instanceof ToolbarWidgetGroupPattern) {
1835
- newItem.controls().last();
1676
+ if (currGroup !== nextGroup) {
1677
+ this.listBehavior.goto(this.listBehavior.navigationBehavior.peekLast(currGroup.inputs.items()));
1678
+ return;
1836
1679
  }
1680
+ this.listBehavior.prev();
1837
1681
  }
1838
1682
  _goto(e) {
1839
1683
  const item = this.inputs.getItem(e.target);
1840
- if (!item) return;
1841
- this.listBehavior.goto(item);
1842
- if (item instanceof ToolbarWidgetGroupPattern) {
1843
- item.controls().goto(e);
1684
+ if (item) {
1685
+ this.listBehavior.goto(item);
1686
+ this.select();
1844
1687
  }
1845
1688
  }
1689
+ select() {
1690
+ const group = this.inputs.activeItem()?.group();
1691
+ if (!group?.multi()) {
1692
+ group?.inputs.items().forEach(i => this.listBehavior.deselect(i));
1693
+ }
1694
+ this.listBehavior.toggle();
1695
+ }
1846
1696
  constructor(inputs) {
1847
1697
  this.inputs = inputs;
1848
1698
  this.orientation = inputs.orientation;
1849
- this.skipDisabled = inputs.skipDisabled;
1699
+ this.softDisabled = inputs.softDisabled;
1850
1700
  this.listBehavior = new List({
1851
1701
  ...inputs,
1852
- multi: () => false,
1702
+ multi: () => true,
1853
1703
  focusMode: () => 'roving',
1854
1704
  selectionMode: () => 'explicit',
1855
1705
  value: signal([]),
@@ -1861,24 +1711,17 @@ class ToolbarPattern {
1861
1711
  this._keydown().handle(event);
1862
1712
  }
1863
1713
  onPointerdown(event) {
1714
+ event.preventDefault();
1715
+ }
1716
+ onClick(event) {
1864
1717
  if (this.disabled()) return;
1865
- this._pointerdown().handle(event);
1718
+ this._goto(event);
1866
1719
  }
1867
1720
  setDefaultState() {
1868
- let firstItem = null;
1869
- for (const item of this.inputs.items()) {
1870
- if (this.listBehavior.isFocusable(item)) {
1871
- if (!firstItem) {
1872
- firstItem = item;
1873
- }
1874
- }
1875
- }
1721
+ const firstItem = this.listBehavior.navigationBehavior.peekFirst(this.inputs.items());
1876
1722
  if (firstItem) {
1877
1723
  this.inputs.activeItem.set(firstItem);
1878
1724
  }
1879
- if (firstItem instanceof ToolbarWidgetGroupPattern) {
1880
- firstItem.controls().setDefaultState();
1881
- }
1882
1725
  }
1883
1726
  validate() {
1884
1727
  const violations = [];
@@ -1886,6 +1729,39 @@ class ToolbarPattern {
1886
1729
  }
1887
1730
  }
1888
1731
 
1732
+ class ToolbarWidgetPattern {
1733
+ inputs;
1734
+ id = () => this.inputs.id();
1735
+ element = () => this.inputs.element();
1736
+ disabled = () => this.inputs.disabled() || this.group()?.disabled() || false;
1737
+ group = () => this.inputs.group();
1738
+ toolbar = () => this.inputs.toolbar();
1739
+ tabIndex = computed(() => this.toolbar().listBehavior.getItemTabindex(this));
1740
+ searchTerm = () => '';
1741
+ value = () => this.inputs.value();
1742
+ selectable = () => true;
1743
+ index = computed(() => this.toolbar().inputs.items().indexOf(this) ?? -1);
1744
+ selected = computed(() => this.toolbar().listBehavior.inputs.value().includes(this.value()));
1745
+ active = computed(() => this.toolbar().activeItem() === this);
1746
+ constructor(inputs) {
1747
+ this.inputs = inputs;
1748
+ }
1749
+ }
1750
+
1751
+ class ToolbarWidgetGroupPattern {
1752
+ inputs;
1753
+ disabled = () => this.inputs.disabled();
1754
+ toolbar = () => this.inputs.toolbar();
1755
+ multi = () => this.inputs.multi();
1756
+ searchTerm = () => '';
1757
+ value = () => '';
1758
+ selectable = () => true;
1759
+ element = () => undefined;
1760
+ constructor(inputs) {
1761
+ this.inputs = inputs;
1762
+ }
1763
+ }
1764
+
1889
1765
  const focusMode = () => 'roving';
1890
1766
  class AccordionGroupPattern {
1891
1767
  inputs;
@@ -1902,7 +1778,7 @@ class AccordionGroupPattern {
1902
1778
  this.multiExpandable = inputs.multiExpandable;
1903
1779
  this.items = inputs.items;
1904
1780
  this.expandedIds = inputs.expandedIds;
1905
- this.skipDisabled = inputs.skipDisabled;
1781
+ this.softDisabled = inputs.softDisabled;
1906
1782
  this.focusManager = new ListFocus({
1907
1783
  ...inputs,
1908
1784
  focusMode
@@ -1925,7 +1801,7 @@ class AccordionTriggerPattern {
1925
1801
  expansionControl;
1926
1802
  active = computed(() => this.inputs.accordionGroup().activeItem() === this);
1927
1803
  controls = computed(() => this.inputs.accordionPanel()?.id());
1928
- tabindex = computed(() => this.inputs.accordionGroup().focusManager.isFocusable(this) ? 0 : -1);
1804
+ tabIndex = computed(() => this.inputs.accordionGroup().focusManager.isFocusable(this) ? 0 : -1);
1929
1805
  disabled = computed(() => this.inputs.disabled() || this.inputs.accordionGroup().disabled());
1930
1806
  index = computed(() => this.inputs.accordionGroup().items().indexOf(this));
1931
1807
  constructor(inputs) {
@@ -2017,11 +1893,11 @@ class TreeItemPattern {
2017
1893
  selectable;
2018
1894
  level = computed(() => this.parent().level() + 1);
2019
1895
  expanded = computed(() => this.expansion.isExpanded());
2020
- visible = computed(() => this.parent().expanded());
1896
+ visible = computed(() => this.parent().expanded() && this.parent().visible());
2021
1897
  setsize = computed(() => this.parent().children().length);
2022
1898
  posinset = computed(() => this.parent().children().indexOf(this) + 1);
2023
1899
  active = computed(() => this.tree().activeItem() === this);
2024
- tabindex = computed(() => this.tree().listBehavior.getItemTabindex(this));
1900
+ tabIndex = computed(() => this.tree().listBehavior.getItemTabindex(this));
2025
1901
  selected = computed(() => {
2026
1902
  if (this.tree().nav()) {
2027
1903
  return undefined;
@@ -2074,8 +1950,9 @@ class TreePattern {
2074
1950
  expansionManager;
2075
1951
  level = () => 0;
2076
1952
  expanded = () => true;
2077
- tabindex = computed(() => this.listBehavior.tabindex());
2078
- activedescendant = computed(() => this.listBehavior.activedescendant());
1953
+ visible = () => true;
1954
+ tabIndex = computed(() => this.listBehavior.tabIndex());
1955
+ activeDescendant = computed(() => this.listBehavior.activeDescendant());
2079
1956
  children = computed(() => this.inputs.allItems().filter(item => item.level() === this.level() + 1));
2080
1957
  visibleItems = computed(() => this.inputs.allItems().filter(item => item.visible()));
2081
1958
  followFocus = computed(() => this.inputs.selectionMode() === 'follow');
@@ -2143,11 +2020,15 @@ class TreePattern {
2143
2020
  }));
2144
2021
  }
2145
2022
  if (!this.followFocus() && this.inputs.multi()) {
2146
- manager.on(this.dynamicSpaceKey, () => list.toggle()).on('Enter', () => list.toggle()).on([Modifier.Ctrl, Modifier.Meta], 'A', () => list.toggleAll());
2023
+ manager.on(this.dynamicSpaceKey, () => list.toggle()).on('Enter', () => list.toggle(), {
2024
+ preventDefault: !this.nav()
2025
+ }).on([Modifier.Ctrl, Modifier.Meta], 'A', () => list.toggleAll());
2147
2026
  }
2148
2027
  if (!this.followFocus() && !this.inputs.multi()) {
2149
2028
  manager.on(this.dynamicSpaceKey, () => list.selectOne());
2150
- manager.on('Enter', () => list.selectOne());
2029
+ manager.on('Enter', () => list.selectOne(), {
2030
+ preventDefault: !this.nav()
2031
+ });
2151
2032
  }
2152
2033
  if (this.inputs.multi() && this.followFocus()) {
2153
2034
  manager.on([Modifier.Ctrl, Modifier.Meta], this.prevKey, () => list.prev()).on([Modifier.Ctrl, Modifier.Meta], this.nextKey, () => list.next()).on([Modifier.Ctrl, Modifier.Meta], this.expandKey, () => this.expand()).on([Modifier.Ctrl, Modifier.Meta], this.collapseKey, () => this.collapse()).on([Modifier.Ctrl, Modifier.Meta], ' ', () => list.toggle()).on([Modifier.Ctrl, Modifier.Meta], 'Enter', () => list.toggle()).on([Modifier.Ctrl, Modifier.Meta], 'Home', () => list.first()).on([Modifier.Ctrl, Modifier.Meta], 'End', () => list.last()).on([Modifier.Ctrl, Modifier.Meta], 'A', () => {
@@ -2189,7 +2070,7 @@ class TreePattern {
2189
2070
  allItems;
2190
2071
  disabled;
2191
2072
  activeItem = signal(undefined);
2192
- skipDisabled;
2073
+ softDisabled;
2193
2074
  wrap;
2194
2075
  orientation;
2195
2076
  textDirection;
@@ -2206,7 +2087,7 @@ class TreePattern {
2206
2087
  this.focusMode = inputs.focusMode;
2207
2088
  this.disabled = inputs.disabled;
2208
2089
  this.activeItem = inputs.activeItem;
2209
- this.skipDisabled = inputs.skipDisabled;
2090
+ this.softDisabled = inputs.softDisabled;
2210
2091
  this.wrap = inputs.wrap;
2211
2092
  this.orientation = inputs.orientation;
2212
2093
  this.textDirection = inputs.textDirection;
@@ -2308,9 +2189,9 @@ class ComboboxTreePattern extends TreePattern {
2308
2189
  inputs;
2309
2190
  isItemCollapsible = () => this.inputs.activeItem()?.parent() instanceof TreeItemPattern;
2310
2191
  role = () => 'tree';
2311
- activeId = computed(() => this.listBehavior.activedescendant());
2192
+ activeId = computed(() => this.listBehavior.activeDescendant());
2312
2193
  items = computed(() => this.inputs.allItems());
2313
- tabindex = () => -1;
2194
+ tabIndex = () => -1;
2314
2195
  constructor(inputs) {
2315
2196
  if (inputs.combobox()) {
2316
2197
  inputs.multi = () => false;
@@ -2330,9 +2211,10 @@ class ComboboxTreePattern extends TreePattern {
2330
2211
  first = () => this.listBehavior.first();
2331
2212
  unfocus = () => this.listBehavior.unfocus();
2332
2213
  select = item => this.listBehavior.select(item);
2214
+ toggle = item => this.listBehavior.toggle(item);
2333
2215
  clearSelection = () => this.listBehavior.deselectAll();
2334
2216
  getItem = e => this._getItem(e);
2335
- getSelectedItem = () => this.inputs.allItems().find(i => i.selected());
2217
+ getSelectedItems = () => this.inputs.allItems().filter(item => item.selected());
2336
2218
  setValue = value => this.inputs.value.set(value ? [value] : []);
2337
2219
  expandItem = () => this.expand();
2338
2220
  collapseItem = () => this.collapse();
@@ -2341,7 +2223,116 @@ class ComboboxTreePattern extends TreePattern {
2341
2223
  }
2342
2224
  expandAll = () => this.items().forEach(item => item.expansion.open());
2343
2225
  collapseAll = () => this.items().forEach(item => item.expansion.close());
2226
+ isItemSelectable = (item = this.inputs.activeItem()) => {
2227
+ return item ? item.selectable() : false;
2228
+ };
2229
+ }
2230
+
2231
+ class DeferredContentAware {
2232
+ contentVisible = signal(false, ...(ngDevMode ? [{
2233
+ debugName: "contentVisible"
2234
+ }] : []));
2235
+ preserveContent = model(false, ...(ngDevMode ? [{
2236
+ debugName: "preserveContent"
2237
+ }] : []));
2238
+ static ɵfac = i0.ɵɵngDeclareFactory({
2239
+ minVersion: "12.0.0",
2240
+ version: "20.2.0-next.2",
2241
+ ngImport: i0,
2242
+ type: DeferredContentAware,
2243
+ deps: [],
2244
+ target: i0.ɵɵFactoryTarget.Directive
2245
+ });
2246
+ static ɵdir = i0.ɵɵngDeclareDirective({
2247
+ minVersion: "17.1.0",
2248
+ version: "20.2.0-next.2",
2249
+ type: DeferredContentAware,
2250
+ isStandalone: true,
2251
+ inputs: {
2252
+ preserveContent: {
2253
+ classPropertyName: "preserveContent",
2254
+ publicName: "preserveContent",
2255
+ isSignal: true,
2256
+ isRequired: false,
2257
+ transformFunction: null
2258
+ }
2259
+ },
2260
+ outputs: {
2261
+ preserveContent: "preserveContentChange"
2262
+ },
2263
+ ngImport: i0
2264
+ });
2265
+ }
2266
+ i0.ɵɵngDeclareClassMetadata({
2267
+ minVersion: "12.0.0",
2268
+ version: "20.2.0-next.2",
2269
+ ngImport: i0,
2270
+ type: DeferredContentAware,
2271
+ decorators: [{
2272
+ type: Directive
2273
+ }]
2274
+ });
2275
+ class DeferredContent {
2276
+ _deferredContentAware = inject(DeferredContentAware, {
2277
+ optional: true
2278
+ });
2279
+ _templateRef = inject(TemplateRef);
2280
+ _viewContainerRef = inject(ViewContainerRef);
2281
+ _currentViewRef = null;
2282
+ _isRendered = false;
2283
+ deferredContentAware = signal(this._deferredContentAware, ...(ngDevMode ? [{
2284
+ debugName: "deferredContentAware"
2285
+ }] : []));
2286
+ constructor() {
2287
+ afterRenderEffect(() => {
2288
+ if (this.deferredContentAware()?.contentVisible()) {
2289
+ if (!this._isRendered) {
2290
+ this._destroyContent();
2291
+ this._currentViewRef = this._viewContainerRef.createEmbeddedView(this._templateRef);
2292
+ this._isRendered = true;
2293
+ }
2294
+ } else if (!this.deferredContentAware()?.preserveContent()) {
2295
+ this._destroyContent();
2296
+ this._isRendered = false;
2297
+ }
2298
+ });
2299
+ }
2300
+ ngOnDestroy() {
2301
+ this._destroyContent();
2302
+ }
2303
+ _destroyContent() {
2304
+ const ref = this._currentViewRef;
2305
+ if (ref && !ref.destroyed) {
2306
+ ref.destroy();
2307
+ this._currentViewRef = null;
2308
+ }
2309
+ }
2310
+ static ɵfac = i0.ɵɵngDeclareFactory({
2311
+ minVersion: "12.0.0",
2312
+ version: "20.2.0-next.2",
2313
+ ngImport: i0,
2314
+ type: DeferredContent,
2315
+ deps: [],
2316
+ target: i0.ɵɵFactoryTarget.Directive
2317
+ });
2318
+ static ɵdir = i0.ɵɵngDeclareDirective({
2319
+ minVersion: "14.0.0",
2320
+ version: "20.2.0-next.2",
2321
+ type: DeferredContent,
2322
+ isStandalone: true,
2323
+ ngImport: i0
2324
+ });
2344
2325
  }
2326
+ i0.ɵɵngDeclareClassMetadata({
2327
+ minVersion: "12.0.0",
2328
+ version: "20.2.0-next.2",
2329
+ ngImport: i0,
2330
+ type: DeferredContent,
2331
+ decorators: [{
2332
+ type: Directive
2333
+ }],
2334
+ ctorParameters: () => []
2335
+ });
2345
2336
 
2346
- export { AccordionGroupPattern, AccordionPanelPattern, AccordionTriggerPattern, ComboboxListboxPattern, ComboboxPattern, ComboboxTreePattern, ListboxPattern, MenuBarPattern, MenuItemPattern, MenuPattern, MenuTriggerPattern, OptionPattern, RadioButtonPattern, RadioGroupPattern, TabListPattern, TabPanelPattern, TabPattern, ToolbarPattern, ToolbarRadioGroupPattern, ToolbarWidgetGroupPattern, ToolbarWidgetPattern, TreeItemPattern, TreePattern, convertGetterSetterToWritableSignalLike };
2337
+ export { AccordionGroupPattern, AccordionPanelPattern, AccordionTriggerPattern, ComboboxListboxPattern, ComboboxPattern, ComboboxTreePattern, DeferredContent, DeferredContentAware, ListboxPattern, MenuBarPattern, MenuItemPattern, MenuPattern, MenuTriggerPattern, OptionPattern, TabListPattern, TabPanelPattern, TabPattern, ToolbarPattern, ToolbarWidgetGroupPattern, ToolbarWidgetPattern, TreeItemPattern, TreePattern, convertGetterSetterToWritableSignalLike };
2347
2338
  //# sourceMappingURL=private.mjs.map