@radix-ng/primitives 0.10.0 → 0.11.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 (106) hide show
  1. package/accordion/src/accordion-content.directive.d.ts +12 -60
  2. package/accordion/src/accordion-header.directive.d.ts +2 -18
  3. package/accordion/src/accordion-item.directive.d.ts +52 -26
  4. package/accordion/src/accordion-root.directive.d.ts +41 -20
  5. package/accordion/src/accordion-trigger.directive.d.ts +6 -22
  6. package/collapsible/src/collapsible-content.directive.d.ts +8 -2
  7. package/collapsible/src/collapsible-content.token.d.ts +3 -0
  8. package/collapsible/src/collapsible-root.directive.d.ts +7 -4
  9. package/compodoc/documentation.json +11395 -0
  10. package/esm2022/accordion/src/accordion-content.directive.mjs +21 -122
  11. package/esm2022/accordion/src/accordion-header.directive.mjs +10 -31
  12. package/esm2022/accordion/src/accordion-item.directive.mjs +144 -57
  13. package/esm2022/accordion/src/accordion-root.directive.mjs +101 -64
  14. package/esm2022/accordion/src/accordion-trigger.directive.mjs +22 -41
  15. package/esm2022/alert-dialog/src/alert-dialog-cancel.directive.mjs +3 -3
  16. package/esm2022/alert-dialog/src/alert-dialog-content.directive.mjs +3 -3
  17. package/esm2022/alert-dialog/src/alert-dialog-root.directive.mjs +3 -3
  18. package/esm2022/alert-dialog/src/alert-dialog-title.directive.mjs +3 -3
  19. package/esm2022/alert-dialog/src/alert-dialog-trigger.directive.mjs +3 -3
  20. package/esm2022/alert-dialog/src/alert-dialog.service.mjs +3 -3
  21. package/esm2022/avatar/src/avatar-fallback.directive.mjs +3 -3
  22. package/esm2022/avatar/src/avatar-image.directive.mjs +3 -3
  23. package/esm2022/avatar/src/avatar-root.directive.mjs +3 -3
  24. package/esm2022/checkbox/src/checkbox-button.directive.mjs +3 -3
  25. package/esm2022/checkbox/src/checkbox-indicator.directive.mjs +3 -3
  26. package/esm2022/checkbox/src/checkbox-input.directive.mjs +3 -3
  27. package/esm2022/checkbox/src/checkbox.directive.mjs +3 -3
  28. package/esm2022/collapsible/src/collapsible-content.directive.mjs +20 -7
  29. package/esm2022/collapsible/src/collapsible-content.token.mjs +3 -0
  30. package/esm2022/collapsible/src/collapsible-root.directive.mjs +17 -13
  31. package/esm2022/collapsible/src/collapsible-trigger.directive.mjs +3 -3
  32. package/esm2022/dropdown-menu/src/dropdown-menu-content.directive.mjs +3 -3
  33. package/esm2022/dropdown-menu/src/dropdown-menu-item-checkbox.directive.mjs +3 -3
  34. package/esm2022/dropdown-menu/src/dropdown-menu-item-indicator.directive.mjs +3 -3
  35. package/esm2022/dropdown-menu/src/dropdown-menu-item-radio-group.directive.mjs +3 -3
  36. package/esm2022/dropdown-menu/src/dropdown-menu-item-radio.directive.mjs +3 -3
  37. package/esm2022/dropdown-menu/src/dropdown-menu-item-selectable.mjs +3 -3
  38. package/esm2022/dropdown-menu/src/dropdown-menu-item.directive.mjs +3 -3
  39. package/esm2022/dropdown-menu/src/dropdown-menu-label.directive.mjs +3 -3
  40. package/esm2022/dropdown-menu/src/dropdown-menu-separator.directive.mjs +3 -3
  41. package/esm2022/dropdown-menu/src/dropdown-menu-trigger.directive.mjs +3 -3
  42. package/esm2022/label/src/label.directive.mjs +10 -5
  43. package/esm2022/menu/index.mjs +4 -4
  44. package/esm2022/menu/src/menu-content.directive.mjs +3 -3
  45. package/esm2022/menu/src/menu-directive.mjs +3 -3
  46. package/esm2022/menu/src/menu-group.directive.mjs +3 -3
  47. package/esm2022/menu/src/menu-item.directive.mjs +3 -3
  48. package/esm2022/menu/src/menu-label.directive.mjs +3 -3
  49. package/esm2022/menu/src/menu-separator.directive.mjs +3 -3
  50. package/esm2022/menubar/index.mjs +4 -4
  51. package/esm2022/menubar/src/menubar-content.directive.mjs +3 -3
  52. package/esm2022/menubar/src/menubar-item-checkbox.directive.mjs +3 -3
  53. package/esm2022/menubar/src/menubar-item-indicator.directive.mjs +3 -3
  54. package/esm2022/menubar/src/menubar-item-radio.directive.mjs +3 -3
  55. package/esm2022/menubar/src/menubar-item.directive.mjs +3 -3
  56. package/esm2022/menubar/src/menubar-radio-group.directive.mjs +3 -3
  57. package/esm2022/menubar/src/menubar-root.directive.mjs +3 -3
  58. package/esm2022/menubar/src/menubar-separator.directive.mjs +3 -3
  59. package/esm2022/menubar/src/menubar-trigger.directive.mjs +3 -3
  60. package/esm2022/progress/src/progress-indicator.directive.mjs +3 -3
  61. package/esm2022/progress/src/progress-root.directive.mjs +3 -3
  62. package/esm2022/radio/src/radio-indicator.directive.mjs +10 -10
  63. package/esm2022/radio/src/radio-item.directive.mjs +29 -18
  64. package/esm2022/radio/src/radio-root.directive.mjs +110 -16
  65. package/esm2022/radio/src/radio-tokens.mjs +3 -0
  66. package/esm2022/separator/src/separator.directive.mjs +3 -3
  67. package/esm2022/switch/index.mjs +4 -4
  68. package/esm2022/switch/src/switch-input.directive.mjs +3 -3
  69. package/esm2022/switch/src/switch-root.directive.mjs +3 -3
  70. package/esm2022/switch/src/switch-thumb.directive.mjs +3 -3
  71. package/esm2022/tabs/index.mjs +4 -4
  72. package/esm2022/tabs/src/tabs-content.directive.mjs +3 -3
  73. package/esm2022/tabs/src/tabs-context.service.mjs +3 -3
  74. package/esm2022/tabs/src/tabs-list.directive.mjs +3 -3
  75. package/esm2022/tabs/src/tabs-root.directive.mjs +3 -3
  76. package/esm2022/tabs/src/tabs-trigger.directive.mjs +3 -3
  77. package/esm2022/toggle/src/toggle.directive.mjs +3 -3
  78. package/esm2022/toggle-group/src/toggle-group-button.directive.mjs +3 -3
  79. package/esm2022/toggle-group/src/toggle-group-multi.directive.mjs +3 -3
  80. package/esm2022/toggle-group/src/toggle-group.directive.mjs +3 -3
  81. package/fesm2022/radix-ng-primitives-accordion.mjs +305 -324
  82. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  83. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +18 -18
  84. package/fesm2022/radix-ng-primitives-avatar.mjs +9 -9
  85. package/fesm2022/radix-ng-primitives-checkbox.mjs +12 -12
  86. package/fesm2022/radix-ng-primitives-collapsible.mjs +61 -44
  87. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  88. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +30 -30
  89. package/fesm2022/radix-ng-primitives-label.mjs +9 -4
  90. package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
  91. package/fesm2022/radix-ng-primitives-menu.mjs +22 -22
  92. package/fesm2022/radix-ng-primitives-menubar.mjs +31 -31
  93. package/fesm2022/radix-ng-primitives-progress.mjs +6 -6
  94. package/fesm2022/radix-ng-primitives-radio.mjs +182 -77
  95. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  96. package/fesm2022/radix-ng-primitives-separator.mjs +3 -3
  97. package/fesm2022/radix-ng-primitives-switch.mjs +13 -13
  98. package/fesm2022/radix-ng-primitives-tabs.mjs +19 -19
  99. package/fesm2022/radix-ng-primitives-toggle-group.mjs +9 -9
  100. package/fesm2022/radix-ng-primitives-toggle.mjs +3 -3
  101. package/label/src/label.directive.d.ts +9 -3
  102. package/package.json +1 -1
  103. package/radio/src/radio-indicator.directive.d.ts +4 -2
  104. package/radio/src/radio-item.directive.d.ts +10 -5
  105. package/radio/src/radio-root.directive.d.ts +19 -18
  106. package/radio/src/radio-tokens.d.ts +12 -0
@@ -1,430 +1,411 @@
1
- import * as i1 from '@angular/cdk/accordion';
2
- import { CdkAccordionItem, CdkAccordion } from '@angular/cdk/accordion';
3
1
  import * as i0 from '@angular/core';
4
- import { InjectionToken, inject, ElementRef, signal, input, effect, Directive, contentChild, Input, contentChildren } from '@angular/core';
5
- import { animationFrameScheduler } from 'rxjs';
2
+ import { InjectionToken, inject, EventEmitter, booleanAttribute, Directive, Input, ContentChildren, forwardRef, Output, ElementRef, ChangeDetectorRef, ContentChild } from '@angular/core';
3
+ import { UniqueSelectionDispatcher } from '@angular/cdk/collections';
4
+ import { Subject, merge, Subscription } from 'rxjs';
5
+ import { FocusKeyManager } from '@angular/cdk/a11y';
6
+ import { Directionality } from '@angular/cdk/bidi';
7
+ import { ENTER, SPACE } from '@angular/cdk/keycodes';
6
8
 
7
- const RdxAccordionContentToken = new InjectionToken('RdxAccordionContentToken');
8
- class RdxAccordionContentDirective {
9
+ const RdxAccordionRootToken = new InjectionToken('RdxAccordionRootDirective');
10
+ let nextId$1 = 0;
11
+ class RdxAccordionRootDirective {
9
12
  constructor() {
13
+ this.selectionDispatcher = inject(UniqueSelectionDispatcher);
14
+ this.dir = inject(Directionality, { optional: true });
15
+ this.id = `rdx-accordion-${nextId$1++}`;
16
+ this.openCloseAllActions = new Subject();
10
17
  /**
11
- * @ignore
12
- */
13
- this.elementRef = inject(ElementRef);
14
- /**
15
- * @ignore
18
+ * The orientation of the accordion.
16
19
  */
17
- this.initialized = signal(false);
18
- /**
19
- * Current item state
20
- */
21
- this.state = signal('closed');
22
- /**
23
- * When true, prevents the user from interacting with the accordion and all its items.
24
- */
25
- this.disabled = input(false);
20
+ this.orientation = 'vertical';
26
21
  /**
27
- * @ignore
22
+ * Determines whether one or multiple items can be opened at the same time.
28
23
  */
29
- this.accordionItem = inject(CdkAccordionItem);
24
+ this.type = 'single';
30
25
  /**
31
26
  * @ignore
32
27
  */
33
- this.orientation = 'vertical';
34
- effect(() => {
35
- if (this.state()) {
36
- this.setPresence();
37
- }
38
- });
28
+ this.collapsible = true;
29
+ this.onValueChange = new EventEmitter();
39
30
  }
40
- /**
41
- * @ignore
42
- */
43
- ngOnInit() {
44
- this.togglePresence();
31
+ get isMultiple() {
32
+ return this.type === 'multiple';
45
33
  }
46
34
  /**
47
- * @ignore
35
+ * The value of the item to expand when initially rendered and type is "single". Use when you do not need to control the state of the items.
48
36
  */
49
- setOpen(state) {
50
- if (this.disabled()) {
51
- return;
52
- }
53
- if (state === undefined) {
54
- this.state.update(() => (this.state() === 'open' ? 'closed' : 'open'));
55
- }
56
- else {
57
- this.state.update(() => state);
37
+ set defaultValue(value) {
38
+ if (value !== this._defaultValue) {
39
+ this._defaultValue = Array.isArray(value) ? value : [value];
40
+ this.selectionDispatcher.notify(this.defaultValue, this.id);
58
41
  }
59
42
  }
60
- /**
61
- * @ignore
62
- */
63
- initialize() {
64
- if (!this.initialized()) {
65
- this.togglePresence();
66
- animationFrameScheduler.schedule(() => {
67
- this.elementRef.nativeElement.getAnimations().forEach((animation) => animation.cancel());
68
- this.initialized.set(true);
69
- });
70
- }
43
+ get defaultValue() {
44
+ return this._defaultValue ?? this.defaultValue;
71
45
  }
72
46
  /**
73
- * @ignore
47
+ * The controlled value of the item to expand
74
48
  */
75
- setPresence() {
76
- if (!this.initialized()) {
77
- this.initialize();
78
- return;
49
+ set value(value) {
50
+ if (value !== this._value) {
51
+ this._value = Array.isArray(value) ? value : [value];
52
+ this.selectionDispatcher.notify(this.value, this.id);
79
53
  }
80
- animationFrameScheduler.schedule(() => {
81
- const animations = this.elementRef.nativeElement.getAnimations();
82
- const hidden = this.elementRef.nativeElement.hasAttribute('hidden');
83
- if (hidden) {
84
- this.show();
85
- const rect = this.elementRef.nativeElement.getBoundingClientRect();
86
- const height = `${this.elementRef.nativeElement.scrollHeight /*rect.height*/}px`;
87
- const width = `${rect.width}px`;
88
- this.elementRef.nativeElement.style.setProperty('--radix-accordion-content-height', height);
89
- this.elementRef.nativeElement.style.setProperty('--radix-accordion-content-width', width);
90
- this.hide();
91
- }
92
- Promise.all(animations.map((animation) => animation.finished)).then(() => {
93
- this.togglePresence();
94
- });
95
- });
54
+ }
55
+ get value() {
56
+ return this._value ?? this.defaultValue;
96
57
  }
97
58
  /**
98
59
  * @ignore
99
60
  */
100
- togglePresence() {
101
- if (this.state() === 'open') {
102
- this.show();
61
+ ngAfterContentInit() {
62
+ this.selectionDispatcher.notify(this.value, this.id);
63
+ this.keyManager = new FocusKeyManager(this.items).withHomeAndEnd();
64
+ if (this.orientation === 'horizontal') {
65
+ this.keyManager.withHorizontalOrientation(this.dir?.value || 'ltr');
103
66
  }
104
67
  else {
105
- this.hide();
68
+ this.keyManager.withVerticalOrientation();
106
69
  }
70
+ this.onValueChangeSubscription = merge(...this.items.map((item) => item.expandedChange)).subscribe(() => this.onValueChange.emit());
107
71
  }
108
72
  /**
109
73
  * @ignore
110
74
  */
111
- show() {
112
- this.elementRef.nativeElement.removeAttribute('hidden');
75
+ ngOnDestroy() {
76
+ this.openCloseAllActions.complete();
77
+ this.onValueChangeSubscription.unsubscribe();
113
78
  }
114
79
  /**
115
80
  * @ignore
116
81
  */
117
- hide() {
118
- this.elementRef.nativeElement.setAttribute('hidden', '');
119
- }
120
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
121
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.1.2", type: RdxAccordionContentDirective, isStandalone: true, selector: "[rdxAccordionContent]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-state": "state()", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-orientation": "orientation" } }, providers: [{ provide: RdxAccordionContentToken, useExisting: RdxAccordionContentDirective }], exportAs: ["rdxAccordionContent"], hostDirectives: [{ directive: i1.CdkAccordionItem }], ngImport: i0 }); }
122
- }
123
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionContentDirective, decorators: [{
124
- type: Directive,
125
- args: [{
126
- selector: '[rdxAccordionContent]',
127
- standalone: true,
128
- exportAs: 'rdxAccordionContent',
129
- providers: [{ provide: RdxAccordionContentToken, useExisting: RdxAccordionContentDirective }],
130
- host: {
131
- '[attr.data-state]': 'state()',
132
- '[attr.data-disabled]': 'disabled() ? "" : undefined',
133
- '[attr.data-orientation]': 'orientation'
134
- },
135
- hostDirectives: [CdkAccordionItem]
136
- }]
137
- }], ctorParameters: () => [] });
138
-
139
- const RdxAccordionItemToken = new InjectionToken('RdxAccordionItemToken');
140
- function injectAccordionItem() {
141
- return inject(RdxAccordionItemDirective);
142
- }
143
- class RdxAccordionItemDirective {
144
- constructor() {
145
- /**
146
- * @ignore
147
- */
148
- this.accordionContent = contentChild.required(RdxAccordionContentToken);
149
- /**
150
- * Current item state
151
- */
152
- this.state = signal('closed');
153
- /**
154
- * When true, prevents the user from interacting with the item.
155
- */
156
- this.disabled = input(false);
157
- /**
158
- * @ignore
159
- */
160
- this.orientation = 'vertical';
161
- }
162
- /**
163
- * Changes current item state
164
- */
165
- setOpen(state) {
166
- if (this.disabled()) {
167
- return;
82
+ handleKeydown(event) {
83
+ if (!this.keyManager.activeItem) {
84
+ this.keyManager.setFirstItemActive();
168
85
  }
169
- if (state === undefined) {
170
- this.state.update(() => (this.state() === 'open' ? 'closed' : 'open'));
86
+ const activeItem = this.keyManager.activeItem;
87
+ if ((event.keyCode === ENTER || event.keyCode === SPACE) &&
88
+ !this.keyManager.isTyping() &&
89
+ activeItem &&
90
+ !activeItem.disabled) {
91
+ event.preventDefault();
92
+ activeItem.toggle();
171
93
  }
172
94
  else {
173
- this.state.update(() => state);
95
+ this.keyManager.onKeydown(event);
174
96
  }
175
- this.accordionContent().setOpen(this.state());
97
+ }
98
+ /** Opens all enabled accordion items in an accordion where multi is enabled.
99
+ * @ignore
100
+ */
101
+ openAll() {
102
+ if (this.isMultiple) {
103
+ this.openCloseAllActions.next(true);
104
+ }
105
+ }
106
+ /** Closes all enabled accordion items.
107
+ * @ignore
108
+ */
109
+ closeAll() {
110
+ this.openCloseAllActions.next(false);
176
111
  }
177
112
  /**
178
113
  * @ignore
179
114
  */
180
- setOrientation(orientation) {
181
- this.orientation = orientation;
182
- this.accordionContent().orientation = orientation;
183
- }
184
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
185
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "18.1.2", type: RdxAccordionItemDirective, isStandalone: true, selector: "[rdxAccordionItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-state": "state()", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-orientation": "orientation" } }, providers: [
186
- {
187
- provide: RdxAccordionItemToken,
188
- useExisting: RdxAccordionItemDirective,
189
- multi: true
190
- }
191
- ], queries: [{ propertyName: "accordionContent", first: true, predicate: RdxAccordionContentToken, descendants: true, isSignal: true }], exportAs: ["rdxAccordionItem"], hostDirectives: [{ directive: i1.CdkAccordion }], ngImport: i0 }); }
115
+ setActiveItem(item) {
116
+ this.keyManager.setActiveItem(item);
117
+ }
118
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
119
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.1", type: RdxAccordionRootDirective, isStandalone: true, selector: "[rdxAccordionRoot]", inputs: { disabled: ["disabled", "disabled", booleanAttribute], orientation: "orientation", defaultValue: "defaultValue", type: "type", collapsible: "collapsible", value: "value" }, outputs: { onValueChange: "onValueChange" }, host: { listeners: { "keydown": "handleKeydown($event)" }, properties: { "attr.data-orientation": "orientation" } }, providers: [
120
+ { provide: RdxAccordionRootToken, useExisting: RdxAccordionRootDirective },
121
+ { provide: UniqueSelectionDispatcher, useClass: UniqueSelectionDispatcher }
122
+ ], queries: [{ propertyName: "items", predicate: i0.forwardRef(() => RdxAccordionItemDirective), descendants: true }], ngImport: i0 }); }
192
123
  }
193
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionItemDirective, decorators: [{
124
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionRootDirective, decorators: [{
194
125
  type: Directive,
195
126
  args: [{
196
- selector: '[rdxAccordionItem]',
127
+ selector: '[rdxAccordionRoot]',
197
128
  standalone: true,
198
- exportAs: 'rdxAccordionItem',
199
129
  providers: [
200
- {
201
- provide: RdxAccordionItemToken,
202
- useExisting: RdxAccordionItemDirective,
203
- multi: true
204
- }
130
+ { provide: RdxAccordionRootToken, useExisting: RdxAccordionRootDirective },
131
+ { provide: UniqueSelectionDispatcher, useClass: UniqueSelectionDispatcher }
205
132
  ],
206
133
  host: {
207
- '[attr.data-state]': 'state()',
208
- '[attr.data-disabled]': 'disabled() ? "" : undefined',
209
- '[attr.data-orientation]': 'orientation'
210
- },
211
- hostDirectives: [CdkAccordion]
134
+ '[attr.data-orientation]': 'orientation',
135
+ '(keydown)': 'handleKeydown($event)'
136
+ }
212
137
  }]
213
- }], propDecorators: { value: [{
138
+ }], propDecorators: { disabled: [{
139
+ type: Input,
140
+ args: [{ transform: booleanAttribute }]
141
+ }], orientation: [{
214
142
  type: Input
143
+ }], items: [{
144
+ type: ContentChildren,
145
+ args: [forwardRef(() => RdxAccordionItemDirective), { descendants: true }]
146
+ }], defaultValue: [{
147
+ type: Input
148
+ }], type: [{
149
+ type: Input
150
+ }], collapsible: [{
151
+ type: Input
152
+ }], value: [{
153
+ type: Input
154
+ }], onValueChange: [{
155
+ type: Output
215
156
  }] } });
216
157
 
217
- class RdxAccordionHeaderDirective {
158
+ class RdxAccordionTriggerDirective {
218
159
  constructor() {
219
- /**
220
- * @ignore
221
- */
222
- this.accordionItem = injectAccordionItem();
223
- }
224
- /**
225
- * @ignore
226
- */
227
- getState() {
228
- return this.accordionItem.state();
160
+ this.nativeElement = inject(ElementRef).nativeElement;
161
+ this.accordionRoot = inject(RdxAccordionRootDirective);
162
+ this.item = inject(RdxAccordionItemDirective);
229
163
  }
230
164
  /**
231
- * @ignore
165
+ * Fires when trigger clicked
232
166
  */
233
- getDisabled() {
234
- return this.accordionItem.disabled() ? '' : undefined;
167
+ onClick() {
168
+ if (!this.accordionRoot.collapsible && this.item.expanded)
169
+ return;
170
+ this.item.toggle();
171
+ this.accordionRoot.setActiveItem(this.item);
235
172
  }
236
- /**
237
- * @ignore
238
- */
239
- getOrientation() {
240
- return this.accordionItem.orientation;
173
+ focus() {
174
+ this.nativeElement.focus();
241
175
  }
242
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
243
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.2", type: RdxAccordionHeaderDirective, isStandalone: true, selector: "[rdxAccordionHeader]", host: { properties: { "attr.data-state": "getState()", "attr.data-disabled": "getDisabled()", "attr.data-orientation": "getOrientation()" } }, ngImport: i0 }); }
176
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
177
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.1", type: RdxAccordionTriggerDirective, isStandalone: true, selector: "[rdxAccordionTrigger]", host: { listeners: { "click": "onClick()" }, properties: { "attr.role": "\"button\"", "attr.aria-expanded": "item.expanded", "attr.data-state": "item.dataState", "attr.data-disabled": "item.disabled", "attr.disabled": "item.disabled ? \"\" : null", "attr.data-orientation": "item.orientation" } }, ngImport: i0 }); }
244
178
  }
245
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionHeaderDirective, decorators: [{
179
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionTriggerDirective, decorators: [{
246
180
  type: Directive,
247
181
  args: [{
248
- selector: '[rdxAccordionHeader]',
182
+ selector: '[rdxAccordionTrigger]',
249
183
  standalone: true,
250
184
  host: {
251
- '[attr.data-state]': 'getState()',
252
- '[attr.data-disabled]': 'getDisabled()',
253
- '[attr.data-orientation]': 'getOrientation()'
185
+ '[attr.role]': '"button"',
186
+ '[attr.aria-expanded]': 'item.expanded',
187
+ '[attr.data-state]': 'item.dataState',
188
+ '[attr.data-disabled]': 'item.disabled',
189
+ '[attr.disabled]': 'item.disabled ? "" : null',
190
+ '[attr.data-orientation]': 'item.orientation',
191
+ '(click)': 'onClick()'
254
192
  }
255
193
  }]
256
194
  }] });
257
195
 
258
- const RdxAccordionRootToken = new InjectionToken('RdxAccordionRootDirective');
259
- function injectAccordionRoot() {
260
- return inject(RdxAccordionRootDirective);
261
- }
262
- class RdxAccordionRootDirective {
196
+ let nextId = 0;
197
+ class RdxAccordionItemDirective {
198
+ get dataState() {
199
+ return this.expanded ? 'open' : 'closed';
200
+ }
201
+ get orientation() {
202
+ return this.accordion.orientation;
203
+ }
204
+ /** Whether the AccordionItem is expanded. */
205
+ set expanded(expanded) {
206
+ // Only emit events and update the internal value if the value changes.
207
+ if (this._expanded !== expanded) {
208
+ this._expanded = expanded;
209
+ this.expandedChange.emit(expanded);
210
+ if (expanded) {
211
+ this.opened.emit();
212
+ /**
213
+ * In the unique selection dispatcher, the id parameter is the id of the CdkAccordionItem,
214
+ * the name value is the id of the accordion.
215
+ */
216
+ const accordionId = this.accordion ? this.accordion.id : this.value;
217
+ this.expansionDispatcher.notify(this.value, accordionId);
218
+ }
219
+ else {
220
+ this.closed.emit();
221
+ }
222
+ // Ensures that the animation will run when the value is set outside of an `@Input`.
223
+ // This includes cases like the open, close and toggle methods.
224
+ this.changeDetectorRef.markForCheck();
225
+ }
226
+ }
227
+ get expanded() {
228
+ return this._expanded;
229
+ }
230
+ set value(value) {
231
+ this._value = value;
232
+ }
233
+ get value() {
234
+ return this._value || this.id;
235
+ }
236
+ /** Whether the AccordionItem is disabled. */
237
+ set disabled(value) {
238
+ this._disabled = value;
239
+ }
240
+ get disabled() {
241
+ return this.accordion.disabled ?? this._disabled;
242
+ }
263
243
  constructor() {
244
+ this.accordion = inject(RdxAccordionRootToken, { skipSelf: true });
245
+ this.changeDetectorRef = inject(ChangeDetectorRef);
246
+ this.expansionDispatcher = inject(UniqueSelectionDispatcher);
264
247
  /**
265
- * @private
248
+ * The unique AccordionItem id.
266
249
  * @ignore
267
250
  */
268
- this.accordionItems = contentChildren(RdxAccordionItemToken);
251
+ this.id = `rdx-accordion-item-${nextId++}`;
252
+ this._expanded = false;
253
+ this._disabled = false;
254
+ /** Event emitted every time the AccordionItem is closed. */
255
+ this.closed = new EventEmitter();
256
+ /** Event emitted every time the AccordionItem is opened. */
257
+ this.opened = new EventEmitter();
258
+ /** Event emitted when the AccordionItem is destroyed. */
259
+ this.destroyed = new EventEmitter();
269
260
  /**
270
- * @private
271
- * @ignore
261
+ * Emits whenever the expanded state of the accordion changes.
262
+ * Primarily used to facilitate two-way binding.
263
+ * @docs-private
272
264
  */
273
- this._orientation = 'vertical';
274
- /**
275
- * @private
276
- * @ignore
277
- */
278
- this._value = [];
279
- /**
280
- * The value of the item to expand when initially rendered and type is "single". Use when you do not need to control the state of the items.
281
- */
282
- this.defaultValue = [];
283
- /**
284
- * Determines whether one or multiple items can be opened at the same time.
285
- */
286
- this.type = 'single';
287
- /**
288
- * @ignore
289
- */
290
- this.collapsible = true;
291
- }
292
- /**
293
- * The controlled value of the item to expand
294
- */
295
- set value(value) {
296
- if (value !== undefined) {
297
- this._value = Array.isArray(value) ? value : [value];
298
- }
299
- else {
300
- this._value = [];
265
+ this.expandedChange = new EventEmitter();
266
+ /** Subscription to openAll/closeAll events. */
267
+ this.openCloseAllSubscription = Subscription.EMPTY;
268
+ this.removeUniqueSelectionListener = this.expansionDispatcher.listen((id, accordionId) => {
269
+ if (this.accordion.isMultiple) {
270
+ if (this.accordion.id === accordionId && id.includes(this.value)) {
271
+ this.expanded = true;
272
+ }
273
+ }
274
+ else {
275
+ this.expanded = this.accordion.id === accordionId && id.includes(this.value);
276
+ }
277
+ });
278
+ // When an accordion item is hosted in an accordion, subscribe to open/close events.
279
+ if (this.accordion) {
280
+ this.openCloseAllSubscription = this.subscribeToOpenCloseAllActions();
301
281
  }
302
- this.onValueChange(this._value);
303
282
  }
304
- /**
305
- * The orientation of the accordion.
306
- */
307
- set orientation(orientation) {
308
- this._orientation = orientation ?? 'vertical';
309
- this.accordionItems().forEach((accordionItem) => accordionItem.setOrientation(this._orientation));
283
+ /** Emits an event for the accordion item being destroyed. */
284
+ ngOnDestroy() {
285
+ this.opened.complete();
286
+ this.closed.complete();
287
+ this.destroyed.emit();
288
+ this.destroyed.complete();
289
+ this.removeUniqueSelectionListener();
290
+ this.openCloseAllSubscription.unsubscribe();
310
291
  }
311
- /**
312
- * @ignore
313
- */
314
- ngOnInit() {
315
- if (this.defaultValue) {
316
- this.value = this.defaultValue;
292
+ focus() {
293
+ this.trigger.focus();
294
+ }
295
+ /** Toggles the expanded state of the accordion item. */
296
+ toggle() {
297
+ if (!this.disabled) {
298
+ this.expanded = !this.expanded;
317
299
  }
318
300
  }
319
- /**
320
- * @ignore
321
- */
322
- onValueChange(value) {
323
- if (this.type === 'single') {
324
- const currentValue = value.length > 0 ? value[0] : undefined;
325
- this.accordionItems().forEach((accordionItem) => {
326
- if (accordionItem.value === currentValue) {
327
- accordionItem.setOpen();
328
- }
329
- else {
330
- accordionItem.setOpen('closed');
331
- }
332
- });
301
+ /** Sets the expanded state of the accordion item to false. */
302
+ close() {
303
+ if (!this.disabled) {
304
+ this.expanded = false;
333
305
  }
334
- else {
335
- value.forEach((valueItem) => {
336
- this.accordionItems().forEach((accordionItem) => {
337
- if (accordionItem.value === valueItem) {
338
- accordionItem.setOpen();
339
- }
340
- });
341
- });
306
+ }
307
+ /** Sets the expanded state of the accordion item to true. */
308
+ open() {
309
+ if (!this.disabled) {
310
+ this.expanded = true;
342
311
  }
343
312
  }
344
- /**
345
- * @ignore
346
- */
347
- getOrientation() {
348
- return this._orientation;
313
+ subscribeToOpenCloseAllActions() {
314
+ return this.accordion.openCloseAllActions.subscribe((expanded) => {
315
+ // Only change expanded state if item is enabled
316
+ if (!this.disabled) {
317
+ this.expanded = expanded;
318
+ }
319
+ });
349
320
  }
350
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
351
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "18.1.2", type: RdxAccordionRootDirective, isStandalone: true, selector: "[rdxAccordionRoot]", inputs: { defaultValue: "defaultValue", type: "type", collapsible: "collapsible", value: "value", orientation: "orientation" }, host: { properties: { "attr.data-orientation": "getOrientation()" } }, providers: [{ provide: RdxAccordionRootToken, useExisting: RdxAccordionRootDirective }], queries: [{ propertyName: "accordionItems", predicate: RdxAccordionItemToken, isSignal: true }], ngImport: i0 }); }
321
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
322
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.1", type: RdxAccordionItemDirective, isStandalone: true, selector: "[rdxAccordionItem]", inputs: { expanded: ["expanded", "expanded", booleanAttribute], value: "value", disabled: ["disabled", "disabled", booleanAttribute] }, outputs: { closed: "closed", opened: "opened", expandedChange: "expandedChange" }, host: { properties: { "attr.data-state": "dataState", "attr.data-disabled": "disabled", "attr.data-orientation": "orientation" } }, providers: [
323
+ { provide: RdxAccordionRootToken, useValue: undefined }
324
+ ], queries: [{ propertyName: "trigger", first: true, predicate: RdxAccordionTriggerDirective, descendants: true }], exportAs: ["rdxAccordionItem"], ngImport: i0 }); }
352
325
  }
353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionRootDirective, decorators: [{
326
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionItemDirective, decorators: [{
354
327
  type: Directive,
355
328
  args: [{
356
- selector: '[rdxAccordionRoot]',
329
+ selector: '[rdxAccordionItem]',
357
330
  standalone: true,
358
- providers: [{ provide: RdxAccordionRootToken, useExisting: RdxAccordionRootDirective }],
331
+ exportAs: 'rdxAccordionItem',
359
332
  host: {
360
- '[attr.data-orientation]': 'getOrientation()'
361
- }
333
+ '[attr.data-state]': 'dataState',
334
+ '[attr.data-disabled]': 'disabled',
335
+ '[attr.data-orientation]': 'orientation'
336
+ },
337
+ providers: [
338
+ { provide: RdxAccordionRootToken, useValue: undefined }
339
+ ]
362
340
  }]
363
- }], propDecorators: { defaultValue: [{
364
- type: Input
365
- }], type: [{
366
- type: Input
367
- }], collapsible: [{
368
- type: Input
341
+ }], ctorParameters: () => [], propDecorators: { trigger: [{
342
+ type: ContentChild,
343
+ args: [RdxAccordionTriggerDirective, { descendants: true }]
344
+ }], expanded: [{
345
+ type: Input,
346
+ args: [{ transform: booleanAttribute }]
369
347
  }], value: [{
370
348
  type: Input
371
- }], orientation: [{
372
- type: Input
349
+ }], disabled: [{
350
+ type: Input,
351
+ args: [{ transform: booleanAttribute }]
352
+ }], closed: [{
353
+ type: Output
354
+ }], opened: [{
355
+ type: Output
356
+ }], expandedChange: [{
357
+ type: Output
373
358
  }] } });
374
359
 
375
- class RdxAccordionTriggerDirective {
360
+ const RdxAccordionContentToken = new InjectionToken('RdxAccordionContentToken');
361
+ class RdxAccordionContentDirective {
376
362
  constructor() {
377
- /**
378
- * @ignore
379
- */
380
- this.accordionRoot = injectAccordionRoot();
381
- /**
382
- * @ignore
383
- */
384
- this.accordionItem = injectAccordionItem();
363
+ this.item = inject(RdxAccordionItemDirective);
385
364
  }
386
- /**
387
- * Fires when trigger clicked
388
- */
389
- onClick() {
390
- if (!this.accordionRoot.collapsible) {
391
- return;
392
- }
393
- if (this.accordionItem.value) {
394
- this.accordionRoot.value = [this.accordionItem.value];
365
+ get style() {
366
+ if (this.item.orientation === 'horizontal') {
367
+ return { width: this.item.expanded ? 'var(--rdx-accordion-content-width)' : 0 };
395
368
  }
369
+ return { height: this.item.expanded ? 'var(--rdx-accordion-content-height)' : 0 };
396
370
  }
397
- /**
398
- * @ignore
399
- */
400
- getState() {
401
- return this.accordionItem.state();
402
- }
403
- /**
404
- * @ignore
405
- */
406
- getDisabled() {
407
- return this.accordionItem.disabled() || undefined;
408
- }
409
- /**
410
- * @ignore
411
- */
412
- getOrientation() {
413
- return this.accordionRoot.getOrientation();
371
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
372
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.1", type: RdxAccordionContentDirective, isStandalone: true, selector: "[rdxAccordionContent]", host: { properties: { "attr.role": "\"region\"", "style": "style", "attr.data-state": "item.dataState", "attr.data-disabled": "item.disabled", "attr.data-orientation": "item.orientation" } }, exportAs: ["rdxAccordionContent"], ngImport: i0 }); }
373
+ }
374
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionContentDirective, decorators: [{
375
+ type: Directive,
376
+ args: [{
377
+ selector: '[rdxAccordionContent]',
378
+ standalone: true,
379
+ exportAs: 'rdxAccordionContent',
380
+ host: {
381
+ '[attr.role]': '"region"',
382
+ // todo need hide content after animation
383
+ // '[style.display]': 'item.expanded ? "" : "none"',
384
+ // '[attr.hidden]': 'hidden ? "" : null',
385
+ '[style]': 'style',
386
+ '[attr.data-state]': 'item.dataState',
387
+ '[attr.data-disabled]': 'item.disabled',
388
+ '[attr.data-orientation]': 'item.orientation'
389
+ }
390
+ }]
391
+ }] });
392
+
393
+ class RdxAccordionHeaderDirective {
394
+ constructor() {
395
+ this.item = inject(RdxAccordionItemDirective);
414
396
  }
415
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
416
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.2", type: RdxAccordionTriggerDirective, isStandalone: true, selector: "[rdxAccordionTrigger]", host: { listeners: { "click": "onClick()" }, properties: { "attr.data-state": "getState()", "attr.data-disabled": "getDisabled()", "attr.data-orientation": "getOrientation()" } }, ngImport: i0 }); }
397
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
398
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.1", type: RdxAccordionHeaderDirective, isStandalone: true, selector: "[rdxAccordionHeader]", host: { properties: { "attr.data-state": "item.dataState", "attr.data-disabled": "item.disabled", "attr.data-orientation": "item.orientation" } }, ngImport: i0 }); }
417
399
  }
418
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: RdxAccordionTriggerDirective, decorators: [{
400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: RdxAccordionHeaderDirective, decorators: [{
419
401
  type: Directive,
420
402
  args: [{
421
- selector: '[rdxAccordionTrigger]',
403
+ selector: '[rdxAccordionHeader]',
422
404
  standalone: true,
423
405
  host: {
424
- '(click)': 'onClick()',
425
- '[attr.data-state]': 'getState()',
426
- '[attr.data-disabled]': 'getDisabled()',
427
- '[attr.data-orientation]': 'getOrientation()'
406
+ '[attr.data-state]': 'item.dataState',
407
+ '[attr.data-disabled]': 'item.disabled',
408
+ '[attr.data-orientation]': 'item.orientation'
428
409
  }
429
410
  }]
430
411
  }] });
@@ -433,5 +414,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImpor
433
414
  * Generated bundle index. Do not edit.
434
415
  */
435
416
 
436
- export { RdxAccordionContentDirective, RdxAccordionContentToken, RdxAccordionHeaderDirective, RdxAccordionItemDirective, RdxAccordionItemToken, RdxAccordionRootDirective, RdxAccordionRootToken, RdxAccordionTriggerDirective, injectAccordionItem, injectAccordionRoot };
417
+ export { RdxAccordionContentDirective, RdxAccordionContentToken, RdxAccordionHeaderDirective, RdxAccordionItemDirective, RdxAccordionRootDirective, RdxAccordionRootToken, RdxAccordionTriggerDirective };
437
418
  //# sourceMappingURL=radix-ng-primitives-accordion.mjs.map