@angular/aria 22.0.0-next.7 → 22.0.0-rc.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.
Files changed (96) hide show
  1. package/fesm2022/_accordion-chunk.mjs +11 -1
  2. package/fesm2022/_accordion-chunk.mjs.map +1 -1
  3. package/fesm2022/_click-event-manager-chunk.mjs +1 -1
  4. package/fesm2022/_deferred-content-chunk.mjs +6 -6
  5. package/fesm2022/_list-chunk.mjs +4 -1
  6. package/fesm2022/_list-chunk.mjs.map +1 -1
  7. package/fesm2022/_list-navigation-chunk.mjs +1 -1
  8. package/fesm2022/_list-typeahead-chunk.mjs +1 -1
  9. package/fesm2022/_menu-chunk.mjs +10 -1
  10. package/fesm2022/_menu-chunk.mjs.map +1 -1
  11. package/fesm2022/{_combobox-listbox-chunk.mjs → _option-chunk.mjs} +13 -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 +10 -1
  15. package/fesm2022/_toolbar-widget-group-chunk.mjs.map +1 -1
  16. package/fesm2022/_transforms-chunk.mjs +8 -0
  17. package/fesm2022/_transforms-chunk.mjs.map +1 -0
  18. package/fesm2022/{_combobox-tree-chunk.mjs → _tree-chunk.mjs} +8 -48
  19. package/fesm2022/_tree-chunk.mjs.map +1 -0
  20. package/fesm2022/{_signal-like-chunk.mjs → _violations-chunk.mjs} +60 -2
  21. package/fesm2022/_violations-chunk.mjs.map +1 -0
  22. package/fesm2022/_widget-chunk.mjs +46 -15
  23. package/fesm2022/_widget-chunk.mjs.map +1 -1
  24. package/fesm2022/accordion.mjs +116 -89
  25. package/fesm2022/accordion.mjs.map +1 -1
  26. package/fesm2022/aria.mjs +1 -1
  27. package/fesm2022/aria.mjs.map +1 -1
  28. package/fesm2022/combobox-testing.mjs +79 -0
  29. package/fesm2022/combobox-testing.mjs.map +1 -0
  30. package/fesm2022/combobox.mjs +273 -307
  31. package/fesm2022/combobox.mjs.map +1 -1
  32. package/fesm2022/grid-testing.mjs +8 -0
  33. package/fesm2022/grid-testing.mjs.map +1 -1
  34. package/fesm2022/grid.mjs +75 -87
  35. package/fesm2022/grid.mjs.map +1 -1
  36. package/fesm2022/listbox-testing.mjs +4 -0
  37. package/fesm2022/listbox-testing.mjs.map +1 -1
  38. package/fesm2022/listbox.mjs +192 -215
  39. package/fesm2022/listbox.mjs.map +1 -1
  40. package/fesm2022/menu-testing.mjs +11 -0
  41. package/fesm2022/menu-testing.mjs.map +1 -1
  42. package/fesm2022/menu.mjs +60 -66
  43. package/fesm2022/menu.mjs.map +1 -1
  44. package/fesm2022/private.mjs +19 -13
  45. package/fesm2022/private.mjs.map +1 -1
  46. package/fesm2022/tabs.mjs +172 -115
  47. package/fesm2022/tabs.mjs.map +1 -1
  48. package/fesm2022/toolbar-testing.mjs +5 -1
  49. package/fesm2022/toolbar-testing.mjs.map +1 -1
  50. package/fesm2022/toolbar.mjs +41 -30
  51. package/fesm2022/toolbar.mjs.map +1 -1
  52. package/fesm2022/tree-testing.mjs +12 -0
  53. package/fesm2022/tree-testing.mjs.map +1 -1
  54. package/fesm2022/tree.mjs +126 -156
  55. package/fesm2022/tree.mjs.map +1 -1
  56. package/package.json +6 -6
  57. package/types/_accordion-chunk.d.ts +4 -2
  58. package/types/_collection-chunk.d.ts +42 -0
  59. package/types/_expansion-chunk.d.ts +1 -1
  60. package/types/_grid-chunk.d.ts +11 -3
  61. package/types/_keyboard-event-manager-chunk.d.ts +1 -1
  62. package/types/_list-chunk.d.ts +1 -1
  63. package/types/_list-navigation-chunk.d.ts +1 -1
  64. package/types/_listbox-chunk.d.ts +1 -1
  65. package/types/_menu-chunk.d.ts +3 -1
  66. package/types/_tabs-chunk.d.ts +1 -1
  67. package/types/_toolbar-chunk.d.ts +3 -1
  68. package/types/_tree-chunk.d.ts +1 -1
  69. package/types/accordion.d.ts +10 -18
  70. package/types/combobox-testing.d.ts +63 -0
  71. package/types/combobox.d.ts +96 -193
  72. package/types/grid-testing.d.ts +4 -0
  73. package/types/grid.d.ts +99 -103
  74. package/types/listbox-testing.d.ts +25 -0
  75. package/types/listbox.d.ts +53 -62
  76. package/types/menu-testing.d.ts +6 -0
  77. package/types/menu.d.ts +17 -23
  78. package/types/private.d.ts +26 -137
  79. package/types/tabs.d.ts +69 -80
  80. package/types/toolbar-testing.d.ts +4 -0
  81. package/types/toolbar.d.ts +6 -12
  82. package/types/tree-testing.d.ts +8 -0
  83. package/types/tree.d.ts +7 -20
  84. package/fesm2022/_combobox-chunk.mjs +0 -478
  85. package/fesm2022/_combobox-chunk.mjs.map +0 -1
  86. package/fesm2022/_combobox-listbox-chunk.mjs.map +0 -1
  87. package/fesm2022/_combobox-tree-chunk.mjs.map +0 -1
  88. package/fesm2022/_element-chunk.mjs +0 -6
  89. package/fesm2022/_element-chunk.mjs.map +0 -1
  90. package/fesm2022/_signal-like-chunk.mjs.map +0 -1
  91. package/fesm2022/simple-combobox.mjs +0 -443
  92. package/fesm2022/simple-combobox.mjs.map +0 -1
  93. package/types/_combobox-chunk.d.ts +0 -224
  94. package/types/_element-chunk.d.ts +0 -10
  95. package/types/_signal-like-chunk.d.ts +0 -14
  96. package/types/simple-combobox.d.ts +0 -124
@@ -1,29 +1,29 @@
1
1
  export { AccordionGroupPattern, AccordionTriggerPattern } from './_accordion-chunk.mjs';
2
- export { ComboboxDialogPattern, ComboboxPattern } from './_combobox-chunk.mjs';
3
- export { ComboboxListboxPattern, ListboxPattern, OptionPattern } from './_combobox-listbox-chunk.mjs';
4
- export { ComboboxTreePattern, TreeItemPattern, TreePattern } from './_combobox-tree-chunk.mjs';
2
+ import { computed, signal, untracked } from '@angular/core';
3
+ import { KeyboardEventManager, Modifier } from './_violations-chunk.mjs';
4
+ export { SortedCollection, computed, convertGetterSetterToWritableSignalLike, linkedSignal, reportViolations, signal, sortDirectives } from './_violations-chunk.mjs';
5
+ import { ClickEventManager } from './_click-event-manager-chunk.mjs';
5
6
  export { DeferredContent, DeferredContentAware } from './_deferred-content-chunk.mjs';
6
7
  export { GridCellPattern, GridCellWidgetPattern, GridPattern, GridRowPattern, resolveElement } from './_widget-chunk.mjs';
8
+ export { ListboxPattern, OptionPattern } from './_option-chunk.mjs';
7
9
  export { MenuBarPattern, MenuItemPattern, MenuPattern, MenuTriggerPattern } from './_menu-chunk.mjs';
8
- import { computed, signal, untracked } from '@angular/core';
9
- import { KeyboardEventManager } from './_signal-like-chunk.mjs';
10
- export { computed, convertGetterSetterToWritableSignalLike, linkedSignal, signal } from './_signal-like-chunk.mjs';
11
- import { ClickEventManager } from './_click-event-manager-chunk.mjs';
12
10
  export { TabListPattern, TabPanelPattern, TabPattern } from './_tabs-chunk.mjs';
13
11
  export { ToolbarPattern, ToolbarWidgetGroupPattern, ToolbarWidgetPattern } from './_toolbar-widget-group-chunk.mjs';
14
- export { sortDirectives } from './_element-chunk.mjs';
12
+ export { TreeItemPattern, TreePattern } from './_tree-chunk.mjs';
13
+ export { tabIndexTransform } from './_transforms-chunk.mjs';
15
14
  export { untracked } from '@angular/core/primitives/signals';
16
15
  import './_expansion-chunk.mjs';
17
16
  import './_list-navigation-chunk.mjs';
18
17
  import './_list-chunk.mjs';
19
18
  import './_list-typeahead-chunk.mjs';
20
19
 
21
- class SimpleComboboxPattern {
20
+ class ComboboxPattern {
22
21
  inputs;
23
22
  isExpanded = computed(() => this.inputs.alwaysExpanded() || this.inputs.expanded());
24
23
  value;
25
24
  element = () => this.inputs.element();
26
25
  disabled = () => this.inputs.disabled();
26
+ softDisabled = () => this.inputs.softDisabled?.() ?? true;
27
27
  inlineSuggestion = () => this.inputs.inlineSuggestion();
28
28
  activeDescendant = computed(() => this.inputs.popup()?.activeDescendant());
29
29
  popupId = computed(() => this.inputs.popup()?.popupId());
@@ -52,7 +52,8 @@ class SimpleComboboxPattern {
52
52
  if (!this.isExpanded()) {
53
53
  manager.on('ArrowDown', () => this.inputs.expanded.set(true));
54
54
  if (!this.isEditable()) {
55
- manager.on(/^(Enter| )$/, () => this.inputs.expanded.set(true));
55
+ manager.on('Enter', () => this.inputs.expanded.set(true));
56
+ manager.on(' ', () => this.inputs.expanded.set(true));
56
57
  }
57
58
  return manager;
58
59
  }
@@ -70,13 +71,17 @@ class SimpleComboboxPattern {
70
71
  ignoreRepeat: false
71
72
  }).on('ArrowDown', e => this.keyboardEventRelay.set(e), {
72
73
  ignoreRepeat: false
74
+ }).on(Modifier.Shift, 'ArrowUp', e => this.keyboardEventRelay.set(e), {
75
+ ignoreRepeat: false
76
+ }).on(Modifier.Shift, 'ArrowDown', e => this.keyboardEventRelay.set(e), {
77
+ ignoreRepeat: false
73
78
  }).on('Home', e => this.keyboardEventRelay.set(e)).on('End', e => this.keyboardEventRelay.set(e)).on('Enter', e => this.keyboardEventRelay.set(e)).on('PageUp', e => this.keyboardEventRelay.set(e)).on('PageDown', e => this.keyboardEventRelay.set(e)).on('Escape', () => {
74
79
  if (!this.inputs.alwaysExpanded()) {
75
80
  this.inputs.expanded.set(false);
76
81
  }
77
82
  });
78
83
  if (!this.isEditable()) {
79
- manager.on(' ', e => this.keyboardEventRelay.set(e)).on(/^.$/, e => {
84
+ manager.on(' ', e => this.keyboardEventRelay.set(e)).on([Modifier.Ctrl, Modifier.Meta], 'a', e => this.keyboardEventRelay.set(e)).on([Modifier.Ctrl, Modifier.Meta], 'A', e => this.keyboardEventRelay.set(e)).on(Modifier.Shift, 'Home', e => this.keyboardEventRelay.set(e)).on(Modifier.Shift, 'End', e => this.keyboardEventRelay.set(e)).on(/^.$/, e => {
80
85
  this.keyboardEventRelay.set(e);
81
86
  });
82
87
  }
@@ -132,6 +137,7 @@ class SimpleComboboxPattern {
132
137
  keyboardEventRelayEffect() {
133
138
  const event = this.keyboardEventRelay();
134
139
  if (event === undefined) return;
140
+ this.isDeleting.set(false);
135
141
  const popup = untracked(() => this.inputs.popup());
136
142
  const popupExpanded = untracked(() => this.isExpanded());
137
143
  if (popupExpanded) {
@@ -147,7 +153,7 @@ class SimpleComboboxPattern {
147
153
  }
148
154
  }
149
155
  }
150
- class SimpleComboboxPopupPattern {
156
+ class ComboboxPopupPattern {
151
157
  inputs;
152
158
  popupType = () => this.inputs.popupType();
153
159
  controlTarget = () => this.inputs.controlTarget();
@@ -167,5 +173,5 @@ class SimpleComboboxPopupPattern {
167
173
  }
168
174
  }
169
175
 
170
- export { SimpleComboboxPattern, SimpleComboboxPopupPattern };
176
+ export { ComboboxPattern, ComboboxPopupPattern };
171
177
  //# sourceMappingURL=private.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"private.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/aria/private/simple-combobox/simple-combobox.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {KeyboardEventManager, ClickEventManager} from '../behaviors/event-manager';\nimport {computed, signal, untracked} from '@angular/core';\nimport {SignalLike, WritableSignalLike} from '../behaviors/signal-like/signal-like';\nimport {ExpansionItem} from '../behaviors/expansion/expansion';\n\n/** Represents the required inputs for a simple combobox. */\nexport interface SimpleComboboxInputs extends ExpansionItem {\n /** Whether the combobox should always remain expanded. */\n alwaysExpanded: SignalLike<boolean>;\n\n /** The value of the combobox. */\n value: WritableSignalLike<string>;\n\n /** The element that the combobox is attached to. */\n element: SignalLike<HTMLElement>;\n\n /** The popup associated with the combobox. */\n popup: SignalLike<SimpleComboboxPopupPattern | undefined>;\n\n /** An inline suggestion to be displayed in the input. */\n inlineSuggestion: SignalLike<string | undefined>;\n\n /** Whether the combobox is disabled. */\n disabled: SignalLike<boolean>;\n}\n\n/** Controls the state of a simple combobox. */\nexport class SimpleComboboxPattern {\n /** The expanded state of the combobox. */\n readonly isExpanded = computed(() => this.inputs.alwaysExpanded() || this.inputs.expanded());\n\n /** The value of the combobox. */\n readonly value: WritableSignalLike<string>;\n\n /** The element that the combobox is attached to. */\n readonly element = () => this.inputs.element();\n\n /** Whether the combobox is disabled. */\n readonly disabled = () => this.inputs.disabled();\n\n /** An inline suggestion to be displayed in the input. */\n readonly inlineSuggestion = () => this.inputs.inlineSuggestion();\n\n /** The ID of the active descendant in the popup. */\n readonly activeDescendant = computed(() => this.inputs.popup()?.activeDescendant());\n\n /** The ID of the popup. */\n readonly popupId = computed(() => this.inputs.popup()?.popupId());\n\n /** The type of the popup. */\n readonly popupType = computed(() => this.inputs.popup()?.popupType());\n\n /** The autocomplete behavior of the combobox. */\n readonly autocomplete = computed<'none' | 'inline' | 'list' | 'both'>(() => {\n const popupType = this.popupType();\n const hasAutocompletePopup = !!this.inputs.popup() && popupType !== 'dialog';\n const hasInlineSuggestion = !!this.inlineSuggestion();\n if (hasAutocompletePopup && hasInlineSuggestion) {\n return 'both';\n }\n if (hasAutocompletePopup) {\n return 'list';\n }\n if (hasInlineSuggestion) {\n return 'inline';\n }\n return 'none';\n });\n\n /** A relay for keyboard events to the popup. */\n readonly keyboardEventRelay = signal<KeyboardEvent | undefined>(undefined);\n\n /** Whether the combobox is focused. */\n readonly isFocused = signal(false);\n\n /** Whether the most recent input event was a deletion. */\n readonly isDeleting = signal(false);\n\n /** Whether the combobox is editable (i.e., an input or textarea). */\n readonly isEditable = computed(\n () =>\n this.element().tagName.toLowerCase() === 'input' ||\n this.element().tagName.toLowerCase() === 'textarea',\n );\n\n /** The keydown event manager for the combobox. */\n // TODO(tjshiu): Allow combo keys in combobox (#33101).\n keydown = computed(() => {\n const manager = new KeyboardEventManager();\n\n if (!this.isExpanded()) {\n manager.on('ArrowDown', () => this.inputs.expanded.set(true));\n\n if (!this.isEditable()) {\n manager.on(/^(Enter| )$/, () => this.inputs.expanded.set(true));\n }\n\n return manager;\n }\n\n manager\n .on(\n 'ArrowLeft',\n e => {\n this.keyboardEventRelay.set(e);\n },\n {preventDefault: this.popupType() !== 'listbox', ignoreRepeat: false},\n )\n .on(\n 'ArrowRight',\n e => {\n this.keyboardEventRelay.set(e);\n },\n {preventDefault: this.popupType() !== 'listbox', ignoreRepeat: false},\n )\n .on('ArrowUp', e => this.keyboardEventRelay.set(e), {ignoreRepeat: false})\n .on('ArrowDown', e => this.keyboardEventRelay.set(e), {ignoreRepeat: false})\n .on('Home', e => this.keyboardEventRelay.set(e))\n .on('End', e => this.keyboardEventRelay.set(e))\n .on('Enter', e => this.keyboardEventRelay.set(e))\n .on('PageUp', e => this.keyboardEventRelay.set(e))\n .on('PageDown', e => this.keyboardEventRelay.set(e))\n .on('Escape', () => {\n if (!this.inputs.alwaysExpanded()) {\n this.inputs.expanded.set(false);\n }\n });\n\n if (!this.isEditable()) {\n manager\n .on(' ', e => this.keyboardEventRelay.set(e))\n .on(/^.$/, e => {\n this.keyboardEventRelay.set(e);\n });\n }\n\n return manager;\n });\n\n /** The click event manager for the combobox. */\n click = computed(() => {\n const manager = new ClickEventManager<PointerEvent>();\n\n if (this.isEditable()) return manager;\n\n manager.on(() => this.inputs.expanded.update(v => !v));\n\n return manager;\n });\n\n constructor(readonly inputs: SimpleComboboxInputs) {\n this.value = inputs.value;\n }\n\n /** Handles keydown events for the combobox. */\n onKeydown(event: KeyboardEvent) {\n if (!this.inputs.disabled()) {\n this.keydown().handle(event);\n }\n }\n\n /** Handles click events for the combobox. */\n onClick(event: PointerEvent) {\n if (!this.disabled()) {\n this.click().handle(event);\n }\n }\n\n /** Handles focus in events for the combobox. */\n onFocusin() {\n this.isFocused.set(true);\n }\n\n /** Handles focus out events for the combobox. */\n onFocusout(event: FocusEvent) {\n this.isFocused.set(false);\n }\n\n /** Handles input events for the combobox. */\n onInput(event: Event) {\n if (!(event.target instanceof HTMLInputElement)) return;\n if (this.disabled()) return;\n\n this.inputs.expanded.set(true);\n this.value.set(event.target.value);\n this.isDeleting.set(event instanceof InputEvent && !!event.inputType.match(/^delete/));\n }\n\n /** Highlights the currently selected item in the combobox. */\n highlightEffect() {\n const value = this.value();\n const inlineSuggestion = this.inlineSuggestion();\n\n const isDeleting = untracked(() => this.isDeleting());\n const isFocused = untracked(() => this.isFocused());\n const isExpanded = this.isExpanded();\n\n if (!inlineSuggestion || !isFocused || !isExpanded || isDeleting) return;\n\n const inputEl = this.element() as HTMLInputElement;\n const isHighlightable = inlineSuggestion.toLowerCase().startsWith(value.toLowerCase());\n\n if (isHighlightable) {\n inputEl.value = value + inlineSuggestion.slice(value.length);\n inputEl.setSelectionRange(value.length, inlineSuggestion.length);\n }\n }\n\n /** Relays keyboard events to the popup. */\n keyboardEventRelayEffect() {\n const event = this.keyboardEventRelay();\n if (event === undefined) return;\n\n const popup = untracked(() => this.inputs.popup());\n const popupExpanded = untracked(() => this.isExpanded());\n if (popupExpanded) {\n popup?.controlTarget()?.dispatchEvent(event);\n }\n }\n\n /** Closes the popup when focus leaves the combobox and popup. */\n closePopupOnBlurEffect() {\n const expanded = this.isExpanded();\n const comboboxFocused = this.isFocused();\n const popupFocused = !!this.inputs.popup()?.isFocused();\n if (expanded && !this.inputs.alwaysExpanded() && !comboboxFocused && !popupFocused) {\n this.inputs.expanded.set(false);\n }\n }\n}\n\n/** Represents the required inputs for a simple combobox popup. */\nexport interface SimpleComboboxPopupInputs {\n /** The type of the popup. */\n popupType: SignalLike<'listbox' | 'tree' | 'grid' | 'dialog'>;\n\n /** The element that serves as the control target for the popup. */\n controlTarget: SignalLike<HTMLElement | undefined>;\n\n /** The ID of the active descendant in the popup. */\n activeDescendant: SignalLike<string | undefined>;\n\n /** The ID of the popup. */\n popupId: SignalLike<string | undefined>;\n}\n\n/** Controls the state of a simple combobox popup. */\nexport class SimpleComboboxPopupPattern {\n /** The type of the popup. */\n readonly popupType = () => this.inputs.popupType();\n\n /** The element that serves as the control target for the popup. */\n readonly controlTarget = () => this.inputs.controlTarget();\n\n /** The ID of the active descendant in the popup. */\n readonly activeDescendant = () => this.inputs.activeDescendant();\n\n /** The ID of the popup. */\n readonly popupId = () => this.inputs.popupId();\n\n /** Whether the popup is focused. */\n readonly isFocused = signal(false);\n\n constructor(readonly inputs: SimpleComboboxPopupInputs) {}\n\n /** Handles focus in events for the popup. */\n onFocusin() {\n this.isFocused.set(true);\n }\n\n /** Handles focus out events for the popup. */\n onFocusout(event: FocusEvent) {\n const focusTarget = event.relatedTarget as Element | null;\n if (this.controlTarget()?.contains(focusTarget)) return;\n\n this.isFocused.set(false);\n }\n}\n"],"names":["SimpleComboboxPattern","inputs","isExpanded","computed","alwaysExpanded","expanded","value","element","disabled","inlineSuggestion","activeDescendant","popup","popupId","popupType","autocomplete","hasAutocompletePopup","hasInlineSuggestion","keyboardEventRelay","signal","undefined","isFocused","isDeleting","isEditable","tagName","toLowerCase","keydown","manager","KeyboardEventManager","on","set","e","preventDefault","ignoreRepeat","click","ClickEventManager","update","v","constructor","onKeydown","event","handle","onClick","onFocusin","onFocusout","onInput","target","HTMLInputElement","InputEvent","inputType","match","highlightEffect","untracked","inputEl","isHighlightable","startsWith","slice","length","setSelectionRange","keyboardEventRelayEffect","popupExpanded","controlTarget","dispatchEvent","closePopupOnBlurEffect","comboboxFocused","popupFocused","SimpleComboboxPopupPattern","focusTarget","relatedTarget","contains"],"mappings":"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"}
1
+ {"version":3,"file":"private.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-fdfa778d11ba/bin/src/aria/private/combobox/combobox.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {KeyboardEventManager, ClickEventManager, Modifier} from '../behaviors/event-manager';\nimport {computed, signal, untracked} from '@angular/core';\nimport {SignalLike, WritableSignalLike} from '../behaviors/signal-like/signal-like';\nimport {ExpansionItem} from '../behaviors/expansion/expansion';\n\n/** Represents the required inputs for a simple combobox. */\nexport interface ComboboxInputs extends ExpansionItem {\n /** Whether the combobox should always remain expanded. */\n alwaysExpanded: SignalLike<boolean>;\n\n /** The value of the combobox. */\n value: WritableSignalLike<string>;\n\n /** The element that the combobox is attached to. */\n element: SignalLike<HTMLElement>;\n\n /** The popup associated with the combobox. */\n popup: SignalLike<ComboboxPopupPattern | undefined>;\n\n /** An inline suggestion to be displayed in the input. */\n inlineSuggestion: SignalLike<string | undefined>;\n\n /** Whether the combobox is disabled. */\n disabled: SignalLike<boolean>;\n\n /** Whether the combobox is soft disabled. */\n softDisabled?: SignalLike<boolean>;\n}\n\n/** Controls the state of a simple combobox. */\nexport class ComboboxPattern {\n /** The expanded state of the combobox. */\n readonly isExpanded = computed(() => this.inputs.alwaysExpanded() || this.inputs.expanded());\n\n /** The value of the combobox. */\n readonly value: WritableSignalLike<string>;\n\n /** The element that the combobox is attached to. */\n readonly element = () => this.inputs.element();\n\n /** Whether the combobox is disabled. */\n readonly disabled = () => this.inputs.disabled();\n\n /** Whether the combobox is soft disabled. */\n readonly softDisabled = () => this.inputs.softDisabled?.() ?? true;\n\n /** An inline suggestion to be displayed in the input. */\n readonly inlineSuggestion = () => this.inputs.inlineSuggestion();\n\n /** The ID of the active descendant in the popup. */\n readonly activeDescendant = computed(() => this.inputs.popup()?.activeDescendant());\n\n /** The ID of the popup. */\n readonly popupId = computed(() => this.inputs.popup()?.popupId());\n\n /** The type of the popup. */\n readonly popupType = computed(() => this.inputs.popup()?.popupType());\n\n /** The autocomplete behavior of the combobox. */\n readonly autocomplete = computed<'none' | 'inline' | 'list' | 'both'>(() => {\n const popupType = this.popupType();\n const hasAutocompletePopup = !!this.inputs.popup() && popupType !== 'dialog';\n const hasInlineSuggestion = !!this.inlineSuggestion();\n if (hasAutocompletePopup && hasInlineSuggestion) {\n return 'both';\n }\n if (hasAutocompletePopup) {\n return 'list';\n }\n if (hasInlineSuggestion) {\n return 'inline';\n }\n return 'none';\n });\n\n /** A relay for keyboard events to the popup. */\n readonly keyboardEventRelay = signal<KeyboardEvent | undefined>(undefined);\n\n /** Whether the combobox is focused. */\n readonly isFocused = signal(false);\n\n /** Whether the most recent input event was a deletion. */\n readonly isDeleting = signal(false);\n\n /** Whether the combobox is editable (i.e., an input or textarea). */\n readonly isEditable = computed(\n () =>\n this.element().tagName.toLowerCase() === 'input' ||\n this.element().tagName.toLowerCase() === 'textarea',\n );\n\n /** The keydown event manager for the combobox. */\n // TODO(tjshiu): Allow combo keys in combobox (#33101).\n keydown = computed(() => {\n const manager = new KeyboardEventManager();\n\n if (!this.isExpanded()) {\n manager.on('ArrowDown', () => this.inputs.expanded.set(true));\n\n if (!this.isEditable()) {\n manager.on('Enter', () => this.inputs.expanded.set(true));\n manager.on(' ', () => this.inputs.expanded.set(true));\n }\n\n return manager;\n }\n\n manager\n .on(\n 'ArrowLeft',\n e => {\n this.keyboardEventRelay.set(e);\n },\n {preventDefault: this.popupType() !== 'listbox', ignoreRepeat: false},\n )\n .on(\n 'ArrowRight',\n e => {\n this.keyboardEventRelay.set(e);\n },\n {preventDefault: this.popupType() !== 'listbox', ignoreRepeat: false},\n )\n .on('ArrowUp', e => this.keyboardEventRelay.set(e), {ignoreRepeat: false})\n .on('ArrowDown', e => this.keyboardEventRelay.set(e), {ignoreRepeat: false})\n .on(Modifier.Shift, 'ArrowUp', e => this.keyboardEventRelay.set(e), {ignoreRepeat: false})\n .on(Modifier.Shift, 'ArrowDown', e => this.keyboardEventRelay.set(e), {ignoreRepeat: false})\n .on('Home', e => this.keyboardEventRelay.set(e))\n .on('End', e => this.keyboardEventRelay.set(e))\n .on('Enter', e => this.keyboardEventRelay.set(e))\n .on('PageUp', e => this.keyboardEventRelay.set(e))\n .on('PageDown', e => this.keyboardEventRelay.set(e))\n .on('Escape', () => {\n if (!this.inputs.alwaysExpanded()) {\n this.inputs.expanded.set(false);\n }\n });\n\n if (!this.isEditable()) {\n manager\n .on(' ', e => this.keyboardEventRelay.set(e))\n .on([Modifier.Ctrl, Modifier.Meta], 'a', e => this.keyboardEventRelay.set(e))\n .on([Modifier.Ctrl, Modifier.Meta], 'A', e => this.keyboardEventRelay.set(e))\n .on(Modifier.Shift, 'Home', e => this.keyboardEventRelay.set(e))\n .on(Modifier.Shift, 'End', e => this.keyboardEventRelay.set(e))\n .on(/^.$/, e => {\n this.keyboardEventRelay.set(e);\n });\n }\n\n return manager;\n });\n\n /** The click event manager for the combobox. */\n click = computed(() => {\n const manager = new ClickEventManager<PointerEvent>();\n\n if (this.isEditable()) return manager;\n\n manager.on(() => this.inputs.expanded.update(v => !v));\n\n return manager;\n });\n\n constructor(readonly inputs: ComboboxInputs) {\n this.value = inputs.value;\n }\n\n /** Handles keydown events for the combobox. */\n onKeydown(event: KeyboardEvent) {\n if (!this.inputs.disabled()) {\n this.keydown().handle(event);\n }\n }\n\n /** Handles click events for the combobox. */\n onClick(event: PointerEvent) {\n if (!this.disabled()) {\n this.click().handle(event);\n }\n }\n\n /** Handles focus in events for the combobox. */\n onFocusin() {\n this.isFocused.set(true);\n }\n\n /** Handles focus out events for the combobox. */\n onFocusout(event: FocusEvent) {\n this.isFocused.set(false);\n }\n\n /** Handles input events for the combobox. */\n onInput(event: Event) {\n if (!(event.target instanceof HTMLInputElement)) return;\n if (this.disabled()) return;\n\n this.inputs.expanded.set(true);\n this.value.set(event.target.value);\n this.isDeleting.set(event instanceof InputEvent && !!event.inputType.match(/^delete/));\n }\n\n /** Highlights the currently selected item in the combobox. */\n highlightEffect() {\n const value = this.value();\n const inlineSuggestion = this.inlineSuggestion();\n\n const isDeleting = untracked(() => this.isDeleting());\n const isFocused = untracked(() => this.isFocused());\n const isExpanded = this.isExpanded();\n\n if (!inlineSuggestion || !isFocused || !isExpanded || isDeleting) return;\n\n const inputEl = this.element() as HTMLInputElement;\n const isHighlightable = inlineSuggestion.toLowerCase().startsWith(value.toLowerCase());\n\n if (isHighlightable) {\n inputEl.value = value + inlineSuggestion.slice(value.length);\n inputEl.setSelectionRange(value.length, inlineSuggestion.length);\n }\n }\n\n /** Relays keyboard events to the popup. */\n keyboardEventRelayEffect() {\n const event = this.keyboardEventRelay();\n if (event === undefined) return;\n\n // Reset isDeleting when the user navigates, so that the highlight effect can run again.\n this.isDeleting.set(false);\n\n const popup = untracked(() => this.inputs.popup());\n const popupExpanded = untracked(() => this.isExpanded());\n if (popupExpanded) {\n popup?.controlTarget()?.dispatchEvent(event);\n }\n }\n\n /** Closes the popup when focus leaves the combobox and popup. */\n closePopupOnBlurEffect() {\n const expanded = this.isExpanded();\n const comboboxFocused = this.isFocused();\n const popupFocused = !!this.inputs.popup()?.isFocused();\n if (expanded && !this.inputs.alwaysExpanded() && !comboboxFocused && !popupFocused) {\n this.inputs.expanded.set(false);\n }\n }\n}\n\n/** Represents the required inputs for a simple combobox popup. */\nexport interface ComboboxPopupInputs {\n /** The type of the popup. */\n popupType: SignalLike<'listbox' | 'tree' | 'grid' | 'dialog'>;\n\n /** The element that serves as the control target for the popup. */\n controlTarget: SignalLike<HTMLElement | undefined>;\n\n /** The ID of the active descendant in the popup. */\n activeDescendant: SignalLike<string | undefined>;\n\n /** The ID of the popup. */\n popupId: SignalLike<string | undefined>;\n}\n\n/** Controls the state of a simple combobox popup. */\nexport class ComboboxPopupPattern {\n /** The type of the popup. */\n readonly popupType = () => this.inputs.popupType();\n\n /** The element that serves as the control target for the popup. */\n readonly controlTarget = () => this.inputs.controlTarget();\n\n /** The ID of the active descendant in the popup. */\n readonly activeDescendant = () => this.inputs.activeDescendant();\n\n /** The ID of the popup. */\n readonly popupId = () => this.inputs.popupId();\n\n /** Whether the popup is focused. */\n readonly isFocused = signal(false);\n\n constructor(readonly inputs: ComboboxPopupInputs) {}\n\n /** Handles focus in events for the popup. */\n onFocusin() {\n this.isFocused.set(true);\n }\n\n /** Handles focus out events for the popup. */\n onFocusout(event: FocusEvent) {\n const focusTarget = event.relatedTarget as Element | null;\n if (this.controlTarget()?.contains(focusTarget)) return;\n\n this.isFocused.set(false);\n }\n}\n"],"names":["ComboboxPattern","inputs","isExpanded","computed","alwaysExpanded","expanded","value","element","disabled","softDisabled","inlineSuggestion","activeDescendant","popup","popupId","popupType","autocomplete","hasAutocompletePopup","hasInlineSuggestion","keyboardEventRelay","signal","undefined","isFocused","isDeleting","isEditable","tagName","toLowerCase","keydown","manager","KeyboardEventManager","on","set","e","preventDefault","ignoreRepeat","Modifier","Shift","Ctrl","Meta","click","ClickEventManager","update","v","constructor","onKeydown","event","handle","onClick","onFocusin","onFocusout","onInput","target","HTMLInputElement","InputEvent","inputType","match","highlightEffect","untracked","inputEl","isHighlightable","startsWith","slice","length","setSelectionRange","keyboardEventRelayEffect","popupExpanded","controlTarget","dispatchEvent","closePopupOnBlurEffect","comboboxFocused","popupFocused","ComboboxPopupPattern","focusTarget","relatedTarget","contains"],"mappings":"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"}
package/fesm2022/tabs.mjs CHANGED
@@ -1,15 +1,14 @@
1
1
  import { _IdGenerator } from '@angular/cdk/a11y';
2
2
  import * as i0 from '@angular/core';
3
- import { InjectionToken, inject, ElementRef, signal, computed, afterRenderEffect, Directive, input, booleanAttribute, model, linkedSignal } from '@angular/core';
3
+ import { InjectionToken, inject, ElementRef, signal, computed, afterNextRender, Directive, input, booleanAttribute, model, linkedSignal, afterRenderEffect, contentChild } from '@angular/core';
4
4
  import { TabListPattern, TabPattern, TabPanelPattern } from './_tabs-chunk.mjs';
5
- import { DeferredContentAware, DeferredContent } from './_deferred-content-chunk.mjs';
5
+ import { SortedCollection, reportViolations } from './_violations-chunk.mjs';
6
+ import { DeferredContent, DeferredContentAware } from './_deferred-content-chunk.mjs';
6
7
  import { Directionality } from '@angular/cdk/bidi';
7
- import { sortDirectives } from './_element-chunk.mjs';
8
8
  import './_expansion-chunk.mjs';
9
- import './_signal-like-chunk.mjs';
10
- import '@angular/core/primitives/signals';
11
9
  import './_list-navigation-chunk.mjs';
12
10
  import './_click-event-manager-chunk.mjs';
11
+ import '@angular/core/primitives/signals';
13
12
 
14
13
  const TABS = new InjectionToken('TABS');
15
14
  const TAB_LIST = new InjectionToken('TAB_LIST');
@@ -20,46 +19,51 @@ class Tabs {
20
19
  _tabList = signal(undefined, ...(ngDevMode ? [{
21
20
  debugName: "_tabList"
22
21
  }] : []));
23
- _tabPanels = signal(new Set(), ...(ngDevMode ? [{
24
- debugName: "_tabPanels"
22
+ _collection = new SortedCollection();
23
+ _tabPatterns = computed(() => this._tabList()?._tabPatterns(), ...(ngDevMode ? [{
24
+ debugName: "_tabPatterns"
25
25
  }] : []));
26
- _tabPanelsList = computed(() => [...this._tabPanels()], ...(ngDevMode ? [{
27
- debugName: "_tabPanelsList"
26
+ _tabPanelPatterns = computed(() => this._collection.orderedItems().map(tabpanel => tabpanel._pattern), ...(ngDevMode ? [{
27
+ debugName: "_tabPanelPatterns"
28
28
  }] : []));
29
- constructor() {
30
- afterRenderEffect({
31
- write: () => {
32
- if (this._tabList()) {
33
- for (const tab of this._tabList()._sortedTabs()) {
34
- const panel = this._tabPanelsList().find(panel => panel === tab.panel());
35
- if (panel) {
36
- panel._tabPattern.set(tab._pattern);
37
- }
38
- }
39
- }
29
+ _panelMap = computed(() => {
30
+ const map = new Map();
31
+ for (const panel of this._collection.orderedItems()) {
32
+ map.set(panel.value(), panel._pattern);
33
+ }
34
+ return map;
35
+ }, ...(ngDevMode ? [{
36
+ debugName: "_panelMap"
37
+ }] : []));
38
+ _tabMap = computed(() => {
39
+ const map = new Map();
40
+ const tabList = this._tabList();
41
+ if (tabList) {
42
+ for (const tab of tabList._collection.orderedItems()) {
43
+ map.set(tab.value(), tab._pattern);
40
44
  }
45
+ }
46
+ return map;
47
+ }, ...(ngDevMode ? [{
48
+ debugName: "_tabMap"
49
+ }] : []));
50
+ constructor() {
51
+ afterNextRender(() => {
52
+ this._collection.startObserving(this.element);
41
53
  });
42
54
  }
43
- _registerList(list) {
44
- this._tabList.set(list);
45
- }
46
- _unregisterList(list) {
47
- this._tabList.set(undefined);
48
- }
49
- _registerPanel(panel) {
50
- this._tabPanels().add(panel);
51
- this._tabPanels.set(new Set(this._tabPanels()));
55
+ ngOnDestroy() {
56
+ this._collection.stopObserving();
52
57
  }
53
- _unregisterPanel(panel) {
54
- this._tabPanels().delete(panel);
55
- this._tabPanels.set(new Set(this._tabPanels()));
58
+ _register(child) {
59
+ this._tabList.set(child);
56
60
  }
57
- findTabPanel(value) {
58
- return value ? this._tabPanelsList().find(panel => panel.value() === value) : undefined;
61
+ _unregister() {
62
+ this._tabList.set(undefined);
59
63
  }
60
64
  static ɵfac = i0.ɵɵngDeclareFactory({
61
65
  minVersion: "12.0.0",
62
- version: "22.0.0-next.9",
66
+ version: "22.0.0-next.12",
63
67
  ngImport: i0,
64
68
  type: Tabs,
65
69
  deps: [],
@@ -67,7 +71,7 @@ class Tabs {
67
71
  });
68
72
  static ɵdir = i0.ɵɵngDeclareDirective({
69
73
  minVersion: "14.0.0",
70
- version: "22.0.0-next.9",
74
+ version: "22.0.0-next.12",
71
75
  type: Tabs,
72
76
  isStandalone: true,
73
77
  selector: "[ngTabs]",
@@ -81,7 +85,7 @@ class Tabs {
81
85
  }
82
86
  i0.ɵɵngDeclareClassMetadata({
83
87
  minVersion: "12.0.0",
84
- version: "22.0.0-next.9",
88
+ version: "22.0.0-next.12",
85
89
  ngImport: i0,
86
90
  type: Tabs,
87
91
  decorators: [{
@@ -102,13 +106,8 @@ class TabList {
102
106
  _elementRef = inject(ElementRef);
103
107
  element = this._elementRef.nativeElement;
104
108
  _tabsParent = inject(TABS);
105
- _tabs = signal(new Set(), ...(ngDevMode ? [{
106
- debugName: "_tabs"
107
- }] : []));
108
- _sortedTabs = computed(() => [...this._tabs()].sort(sortDirectives), ...(ngDevMode ? [{
109
- debugName: "_sortedTabs"
110
- }] : []));
111
- _tabPatterns = computed(() => [...this._sortedTabs()].map(tab => tab._pattern), ...(ngDevMode ? [{
109
+ _collection = new SortedCollection();
110
+ _tabPatterns = computed(() => this._collection.orderedItems().map(tab => tab._pattern), ...(ngDevMode ? [{
112
111
  debugName: "_tabPatterns"
113
112
  }] : []));
114
113
  orientation = input('horizontal', ...(ngDevMode ? [{
@@ -156,40 +155,49 @@ class TabList {
156
155
  selectedTab: this._selectedTabPattern
157
156
  });
158
157
  constructor() {
158
+ afterNextRender(() => {
159
+ this._collection.startObserving(this.element);
160
+ });
161
+ afterRenderEffect(() => {
162
+ this._pattern.setDefaultStateEffect();
163
+ });
159
164
  afterRenderEffect({
160
165
  write: () => {
161
166
  const pattern = this._selectedTabPattern();
162
- const tab = this._sortedTabs().find(tab => tab._pattern == pattern);
167
+ const tab = this._collection.orderedItems().find(tab => tab._pattern == pattern);
163
168
  this.selectedTab.set(tab?.value());
164
169
  }
165
170
  });
166
- afterRenderEffect({
167
- write: () => this._pattern.setDefaultStateEffect()
168
- });
171
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
172
+ afterRenderEffect({
173
+ read: () => {
174
+ const violations = [];
175
+ const values = this._collection.orderedItems().map(t => t.value());
176
+ const duplicates = values.filter((item, index) => values.indexOf(item) !== index);
177
+ if (duplicates.length > 0) {
178
+ violations.push(`Duplicate value '${duplicates[0]}' detected inside ngTabList.`);
179
+ }
180
+ reportViolations(violations, this.element);
181
+ }
182
+ });
183
+ }
169
184
  }
170
185
  ngOnInit() {
171
- this._tabsParent._registerList(this);
186
+ this._tabsParent._register(this);
172
187
  }
173
188
  ngOnDestroy() {
174
- this._tabsParent._registerList(this);
175
- }
176
- _registerTab(child) {
177
- this._tabs().add(child);
178
- this._tabs.set(new Set(this._tabs()));
179
- }
180
- _unregisterTab(child) {
181
- this._tabs().delete(child);
182
- this._tabs.set(new Set(this._tabs()));
189
+ this._tabsParent._unregister();
190
+ this._collection.stopObserving();
183
191
  }
184
192
  open(value) {
185
193
  return this._pattern.open(this.findTab(value)?._pattern);
186
194
  }
187
195
  findTab(value) {
188
- return value ? this._sortedTabs().find(tab => tab.value() === value) : undefined;
196
+ return value ? this._collection.orderedItems().find(tab => tab.value() === value) : undefined;
189
197
  }
190
198
  static ɵfac = i0.ɵɵngDeclareFactory({
191
199
  minVersion: "12.0.0",
192
- version: "22.0.0-next.9",
200
+ version: "22.0.0-next.12",
193
201
  ngImport: i0,
194
202
  type: TabList,
195
203
  deps: [],
@@ -197,7 +205,7 @@ class TabList {
197
205
  });
198
206
  static ɵdir = i0.ɵɵngDeclareDirective({
199
207
  minVersion: "17.1.0",
200
- version: "22.0.0-next.9",
208
+ version: "22.0.0-next.12",
201
209
  type: TabList,
202
210
  isStandalone: true,
203
211
  selector: "[ngTabList]",
@@ -281,7 +289,7 @@ class TabList {
281
289
  }
282
290
  i0.ɵɵngDeclareClassMetadata({
283
291
  minVersion: "12.0.0",
284
- version: "22.0.0-next.9",
292
+ version: "22.0.0-next.12",
285
293
  ngImport: i0,
286
294
  type: TabList,
287
295
  decorators: [{
@@ -372,13 +380,14 @@ i0.ɵɵngDeclareClassMetadata({
372
380
  class Tab {
373
381
  _elementRef = inject(ElementRef);
374
382
  element = this._elementRef.nativeElement;
375
- _tabsWrapper = inject(TABS);
376
383
  _tabList = inject(TAB_LIST);
377
384
  id = input(inject(_IdGenerator).getId('ng-tab-', true), ...(ngDevMode ? [{
378
385
  debugName: "id"
379
386
  }] : []));
380
- panel = computed(() => this._tabsWrapper.findTabPanel(this.value()), ...(ngDevMode ? [{
381
- debugName: "panel"
387
+ _tabpanelPattern = computed(() => {
388
+ return this._tabList._tabsParent._panelMap().get(this.value());
389
+ }, ...(ngDevMode ? [{
390
+ debugName: "_tabpanelPattern"
382
391
  }] : []));
383
392
  disabled = input(false, {
384
393
  ...(ngDevMode ? {
@@ -399,20 +408,35 @@ class Tab {
399
408
  ...this,
400
409
  element: () => this.element,
401
410
  tabList: () => this._tabList._pattern,
402
- tabPanel: computed(() => this.panel()?._pattern)
411
+ tabPanel: this._tabpanelPattern
403
412
  });
404
413
  open() {
405
414
  this._pattern.open();
406
415
  }
416
+ constructor() {
417
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
418
+ afterRenderEffect({
419
+ read: () => {
420
+ const violations = [];
421
+ if (this._tabList && this._tabList._tabsParent) {
422
+ if (!this._tabList._tabsParent._panelMap().has(this.value())) {
423
+ violations.push(`ngTab with value '${this.value()}' does not have a corresponding ngTabPanel.`);
424
+ }
425
+ }
426
+ reportViolations(violations, this.element);
427
+ }
428
+ });
429
+ }
430
+ }
407
431
  ngOnInit() {
408
- this._tabList._registerTab(this);
432
+ this._tabList._collection.register(this);
409
433
  }
410
434
  ngOnDestroy() {
411
- this._tabList._unregisterTab(this);
435
+ this._tabList._collection.unregister(this);
412
436
  }
413
437
  static ɵfac = i0.ɵɵngDeclareFactory({
414
438
  minVersion: "12.0.0",
415
- version: "22.0.0-next.9",
439
+ version: "22.0.0-next.12",
416
440
  ngImport: i0,
417
441
  type: Tab,
418
442
  deps: [],
@@ -420,7 +444,7 @@ class Tab {
420
444
  });
421
445
  static ɵdir = i0.ɵɵngDeclareDirective({
422
446
  minVersion: "17.1.0",
423
- version: "22.0.0-next.9",
447
+ version: "22.0.0-next.12",
424
448
  type: Tab,
425
449
  isStandalone: true,
426
450
  selector: "[ngTab]",
@@ -466,7 +490,7 @@ class Tab {
466
490
  }
467
491
  i0.ɵɵngDeclareClassMetadata({
468
492
  minVersion: "12.0.0",
469
- version: "22.0.0-next.9",
493
+ version: "22.0.0-next.12",
470
494
  ngImport: i0,
471
495
  type: Tab,
472
496
  decorators: [{
@@ -485,6 +509,7 @@ i0.ɵɵngDeclareClassMetadata({
485
509
  }
486
510
  }]
487
511
  }],
512
+ ctorParameters: () => [],
488
513
  propDecorators: {
489
514
  id: [{
490
515
  type: i0.Input,
@@ -513,6 +538,43 @@ i0.ɵɵngDeclareClassMetadata({
513
538
  }
514
539
  });
515
540
 
541
+ class TabContent {
542
+ static ɵfac = i0.ɵɵngDeclareFactory({
543
+ minVersion: "12.0.0",
544
+ version: "22.0.0-next.12",
545
+ ngImport: i0,
546
+ type: TabContent,
547
+ deps: [],
548
+ target: i0.ɵɵFactoryTarget.Directive
549
+ });
550
+ static ɵdir = i0.ɵɵngDeclareDirective({
551
+ minVersion: "14.0.0",
552
+ version: "22.0.0-next.12",
553
+ type: TabContent,
554
+ isStandalone: true,
555
+ selector: "ng-template[ngTabContent]",
556
+ exportAs: ["ngTabContent"],
557
+ hostDirectives: [{
558
+ directive: DeferredContent
559
+ }],
560
+ ngImport: i0
561
+ });
562
+ }
563
+ i0.ɵɵngDeclareClassMetadata({
564
+ minVersion: "12.0.0",
565
+ version: "22.0.0-next.12",
566
+ ngImport: i0,
567
+ type: TabContent,
568
+ decorators: [{
569
+ type: Directive,
570
+ args: [{
571
+ selector: 'ng-template[ngTabContent]',
572
+ exportAs: 'ngTabContent',
573
+ hostDirectives: [DeferredContent]
574
+ }]
575
+ }]
576
+ });
577
+
516
578
  class TabPanel {
517
579
  _elementRef = inject(ElementRef);
518
580
  element = this._elementRef.nativeElement;
@@ -521,7 +583,9 @@ class TabPanel {
521
583
  id = input(inject(_IdGenerator).getId('ng-tabpanel-', true), ...(ngDevMode ? [{
522
584
  debugName: "id"
523
585
  }] : []));
524
- _tabPattern = signal(undefined, ...(ngDevMode ? [{
586
+ _tabPattern = computed(() => {
587
+ return this._tabs._tabMap().get(this.value());
588
+ }, ...(ngDevMode ? [{
525
589
  debugName: "_tabPattern"
526
590
  }] : []));
527
591
  value = input.required(...(ngDevMode ? [{
@@ -534,30 +598,47 @@ class TabPanel {
534
598
  ...this,
535
599
  tab: this._tabPattern
536
600
  });
601
+ _tabContent = contentChild(TabContent, ...(ngDevMode ? [{
602
+ debugName: "_tabContent"
603
+ }] : []));
537
604
  constructor() {
538
605
  afterRenderEffect({
539
606
  write: () => {
540
607
  this._deferredContentAware.contentVisible.set(this.visible());
541
608
  }
542
609
  });
610
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
611
+ afterRenderEffect({
612
+ read: () => {
613
+ const violations = [];
614
+ if (!this._tabContent()) {
615
+ violations.push('ngTabPanel must have an ngTabContent structural directive to render.');
616
+ }
617
+ if (!this._tabs._tabMap().has(this.value())) {
618
+ violations.push(`ngTabPanel with value '${this.value()}' does not have a corresponding ngTab.`);
619
+ }
620
+ reportViolations(violations, this.element);
621
+ }
622
+ });
623
+ }
543
624
  }
544
625
  ngOnInit() {
545
- this._tabs._registerPanel(this);
626
+ this._tabs._collection.register(this);
546
627
  }
547
628
  ngOnDestroy() {
548
- this._tabs._unregisterPanel(this);
629
+ this._tabs._collection.unregister(this);
549
630
  }
550
631
  static ɵfac = i0.ɵɵngDeclareFactory({
551
632
  minVersion: "12.0.0",
552
- version: "22.0.0-next.9",
633
+ version: "22.0.0-next.12",
553
634
  ngImport: i0,
554
635
  type: TabPanel,
555
636
  deps: [],
556
637
  target: i0.ɵɵFactoryTarget.Directive
557
638
  });
558
639
  static ɵdir = i0.ɵɵngDeclareDirective({
559
- minVersion: "17.1.0",
560
- version: "22.0.0-next.9",
640
+ minVersion: "17.2.0",
641
+ version: "22.0.0-next.12",
561
642
  type: TabPanel,
562
643
  isStandalone: true,
563
644
  selector: "[ngTabPanel]",
@@ -588,6 +669,13 @@ class TabPanel {
588
669
  "attr.aria-labelledby": "_pattern.labelledBy()"
589
670
  }
590
671
  },
672
+ queries: [{
673
+ propertyName: "_tabContent",
674
+ first: true,
675
+ predicate: TabContent,
676
+ descendants: true,
677
+ isSignal: true
678
+ }],
591
679
  exportAs: ["ngTabPanel"],
592
680
  hostDirectives: [{
593
681
  directive: DeferredContentAware,
@@ -598,7 +686,7 @@ class TabPanel {
598
686
  }
599
687
  i0.ɵɵngDeclareClassMetadata({
600
688
  minVersion: "12.0.0",
601
- version: "22.0.0-next.9",
689
+ version: "22.0.0-next.12",
602
690
  ngImport: i0,
603
691
  type: TabPanel,
604
692
  decorators: [{
@@ -636,45 +724,14 @@ i0.ɵɵngDeclareClassMetadata({
636
724
  alias: "value",
637
725
  required: true
638
726
  }]
639
- }]
640
- }
641
- });
642
-
643
- class TabContent {
644
- static ɵfac = i0.ɵɵngDeclareFactory({
645
- minVersion: "12.0.0",
646
- version: "22.0.0-next.9",
647
- ngImport: i0,
648
- type: TabContent,
649
- deps: [],
650
- target: i0.ɵɵFactoryTarget.Directive
651
- });
652
- static ɵdir = i0.ɵɵngDeclareDirective({
653
- minVersion: "14.0.0",
654
- version: "22.0.0-next.9",
655
- type: TabContent,
656
- isStandalone: true,
657
- selector: "ng-template[ngTabContent]",
658
- exportAs: ["ngTabContent"],
659
- hostDirectives: [{
660
- directive: DeferredContent
661
727
  }],
662
- ngImport: i0
663
- });
664
- }
665
- i0.ɵɵngDeclareClassMetadata({
666
- minVersion: "12.0.0",
667
- version: "22.0.0-next.9",
668
- ngImport: i0,
669
- type: TabContent,
670
- decorators: [{
671
- type: Directive,
672
- args: [{
673
- selector: 'ng-template[ngTabContent]',
674
- exportAs: 'ngTabContent',
675
- hostDirectives: [DeferredContent]
728
+ _tabContent: [{
729
+ type: i0.ContentChild,
730
+ args: [i0.forwardRef(() => TabContent), {
731
+ isSignal: true
732
+ }]
676
733
  }]
677
- }]
734
+ }
678
735
  });
679
736
 
680
737
  export { Tab, TabContent, TabList, TabPanel, Tabs, DeferredContent as ɵɵDeferredContent, DeferredContentAware as ɵɵDeferredContentAware };