@radix-ng/primitives 0.37.0 → 0.38.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 (78) hide show
  1. package/accordion/index.d.ts +3 -1
  2. package/accordion/src/accordion-content-presence.directive.d.ts +6 -0
  3. package/accordion/src/accordion-content.directive.d.ts +4 -7
  4. package/accordion/src/accordion-header.directive.d.ts +2 -2
  5. package/accordion/src/accordion-item.directive.d.ts +24 -83
  6. package/accordion/src/accordion-root.directive.d.ts +33 -87
  7. package/accordion/src/accordion-trigger.directive.d.ts +5 -11
  8. package/collapsible/index.d.ts +11 -0
  9. package/collapsible/src/collapsible-content-presence.directive.d.ts +6 -0
  10. package/collapsible/src/collapsible-content.directive.d.ts +10 -9
  11. package/collapsible/src/collapsible-root.directive.d.ts +19 -37
  12. package/collapsible/src/collapsible-trigger.directive.d.ts +1 -21
  13. package/core/index.d.ts +5 -0
  14. package/core/src/accessor/control-value-accessor.d.ts +67 -0
  15. package/core/src/create-context.d.ts +10 -0
  16. package/core/src/date-time/comparators.d.ts +7 -1
  17. package/core/src/date-time/useDateField.d.ts +2 -2
  18. package/core/src/types.d.ts +24 -0
  19. package/{stepper/src/utils → core/src}/useArrowNavigation.d.ts +2 -2
  20. package/core/src/useResizeObserver.d.ts +15 -0
  21. package/fesm2022/radix-ng-primitives-accordion.mjs +196 -408
  22. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  23. package/fesm2022/radix-ng-primitives-avatar.mjs +2 -10
  24. package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
  25. package/fesm2022/radix-ng-primitives-calendar.mjs +3 -14
  26. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  27. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-collapsible.mjs +138 -143
  29. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-core.mjs +248 -7
  31. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-hover-card.mjs +1 -3
  33. package/fesm2022/radix-ng-primitives-hover-card.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-menubar.mjs +1 -8
  35. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  36. package/fesm2022/radix-ng-primitives-pagination.mjs +2 -6
  37. package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
  38. package/fesm2022/radix-ng-primitives-popover.mjs +2 -6
  39. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  40. package/fesm2022/radix-ng-primitives-presence.mjs +34 -1
  41. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  42. package/fesm2022/radix-ng-primitives-progress.mjs +2 -7
  43. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  44. package/fesm2022/radix-ng-primitives-radio.mjs +1 -3
  45. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  46. package/fesm2022/radix-ng-primitives-select.mjs +75 -33
  47. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  48. package/fesm2022/radix-ng-primitives-stepper.mjs +1 -84
  49. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  50. package/fesm2022/radix-ng-primitives-switch.mjs +61 -100
  51. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-tabs.mjs +4 -19
  53. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-time-field.mjs +351 -0
  55. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -0
  56. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  57. package/fesm2022/radix-ng-primitives-toggle.mjs +1 -6
  58. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  59. package/fesm2022/radix-ng-primitives-tooltip.mjs +1 -3
  60. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  61. package/hover-card/src/hover-card-root.directive.d.ts +4 -4
  62. package/package.json +5 -1
  63. package/popover/src/popover-root.directive.d.ts +4 -4
  64. package/presence/index.d.ts +1 -0
  65. package/presence/src/presence.directive.d.ts +27 -0
  66. package/select/src/select-trigger.directive.d.ts +8 -2
  67. package/select/src/select.component.d.ts +23 -6
  68. package/switch/index.d.ts +0 -1
  69. package/switch/src/switch-input.directive.d.ts +1 -1
  70. package/switch/src/switch-root.directive.d.ts +23 -46
  71. package/switch/src/switch-thumb.directive.d.ts +1 -1
  72. package/time-field/README.md +1 -0
  73. package/time-field/index.d.ts +11 -0
  74. package/time-field/src/time-field-context.token.d.ts +19 -0
  75. package/time-field/src/time-field-input.directive.d.ts +53 -0
  76. package/time-field/src/time-field-root.directive.d.ts +125 -0
  77. package/tooltip/src/tooltip-root.directive.d.ts +4 -4
  78. package/collapsible/src/collapsible-content.token.d.ts +0 -3
@@ -1,495 +1,281 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, EventEmitter, booleanAttribute, Output, Input, forwardRef, ContentChildren, Directive, ElementRef, ChangeDetectorRef, ContentChild, NgModule } 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, TAB } from '@angular/cdk/keycodes';
2
+ import { Directive, inject, ElementRef, input, booleanAttribute, model, output, computed, effect, NgModule } from '@angular/core';
3
+ import * as i1 from '@radix-ng/primitives/collapsible';
4
+ import { RdxCollapsibleContentPresenceDirective, injectCollapsibleRootContext, RdxCollapsibleRootDirective, RdxCollapsibleContentDirective, RdxCollapsibleTriggerDirective } from '@radix-ng/primitives/collapsible';
5
+ import { createContext, useArrowNavigation } from '@radix-ng/primitives/core';
6
+ import { _IdGenerator } from '@angular/cdk/a11y';
8
7
 
9
- const RdxAccordionRootToken = new InjectionToken('RdxAccordionRootDirective');
10
- let nextId$1 = 0;
8
+ class RdxAccordionContentPresenceDirective {
9
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionContentPresenceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
10
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.4", type: RdxAccordionContentPresenceDirective, isStandalone: true, selector: "ng-template[rdxAccordionContentPresence]", hostDirectives: [{ directive: i1.RdxCollapsibleContentPresenceDirective }], ngImport: i0 }); }
11
+ }
12
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionContentPresenceDirective, decorators: [{
13
+ type: Directive,
14
+ args: [{
15
+ selector: 'ng-template[rdxAccordionContentPresence]',
16
+ hostDirectives: [RdxCollapsibleContentPresenceDirective]
17
+ }]
18
+ }] });
19
+
20
+ const [injectAccordionRootContext, provideAccordionRootContext] = createContext('AccordionRootContext');
21
+ const rootContext = () => {
22
+ const instance = inject(RdxAccordionRootDirective);
23
+ return {
24
+ disabled: instance.disabled,
25
+ direction: instance.dir,
26
+ collapsible: instance.isCollapsible,
27
+ orientation: instance.orientation,
28
+ elementRef: instance.elementRef,
29
+ value: instance.value,
30
+ isSingle: instance.isSingle,
31
+ changeModelValue: instance.changeModelValue,
32
+ isItemOpen: instance.isItemOpen
33
+ };
34
+ };
11
35
  /**
12
36
  * @group Components
13
37
  */
14
38
  class RdxAccordionRootDirective {
15
39
  constructor() {
16
- /**
17
- * @ignore
18
- */
19
- this.selectionDispatcher = inject(UniqueSelectionDispatcher);
20
- /**
21
- * @ignore
22
- */
23
- this.dir = inject(Directionality, { optional: true });
24
- /**
25
- * @ignore
26
- */
27
- this.id = `rdx-accordion-${nextId$1++}`;
28
- /**
29
- * @ignore
40
+ this.elementRef = inject(ElementRef);
41
+ this.id = input(inject(_IdGenerator).getId('rdx-accordion-'));
42
+ this.dir = input('ltr');
43
+ /** Whether the Accordion is disabled.
44
+ * @defaultValue false
45
+ * @group Props
30
46
  */
31
- this.openCloseAllActions = new Subject();
47
+ this.disabled = input(false, { transform: booleanAttribute });
32
48
  /**
33
49
  * The orientation of the accordion.
34
50
  *
35
51
  * @defaultValue 'vertical'
36
52
  * @group Props
37
53
  */
38
- this.orientation = 'vertical';
54
+ this.orientation = input('vertical');
55
+ this.defaultValue = input();
39
56
  /**
40
- * Determines whether one or multiple items can be opened at the same time.
57
+ * The controlled value of the item to expand.
58
+ *
41
59
  * @group Props
42
- * @defaultValue 'single'
43
- */
44
- this.type = 'single';
45
- /**
46
- * @ignore
47
60
  */
48
- this.collapsible = true;
61
+ this.value = model();
62
+ this.collapsible = input(false, { transform: booleanAttribute });
63
+ this.type = input('single');
49
64
  /**
50
65
  * Event handler called when the expanded state of an item changes and type is "multiple".
51
66
  * @group Emits
52
67
  */
53
- this.onValueChange = new EventEmitter();
54
- this._defaultValue = [];
55
- }
56
- get isMultiple() {
57
- return this.type === 'multiple';
58
- }
59
- /**
60
- * The value of the item to expand when initially rendered and type is "single".
61
- * Use when you do not need to control the state of the items.
62
- * @group Props
63
- */
64
- set defaultValue(value) {
65
- if (value !== this._defaultValue) {
66
- this._defaultValue = Array.isArray(value) ? value : [value];
67
- }
68
- }
69
- get defaultValue() {
70
- return this.isMultiple ? this._defaultValue : this._defaultValue[0];
71
- }
72
- /**
73
- * The controlled value of the item to expand.
74
- *
75
- * @group Props
76
- */
77
- set value(value) {
78
- if (value !== this._value) {
79
- this._value = Array.isArray(value) ? value : [value];
80
- this.selectionDispatcher.notify(this.value, this.id);
81
- }
82
- }
83
- get value() {
84
- if (this._value === undefined) {
85
- return this.defaultValue;
86
- }
87
- return this.isMultiple ? this._value : this._value[0];
88
- }
89
- /**
90
- * @ignore
91
- */
92
- ngAfterContentInit() {
93
- this.selectionDispatcher.notify((this._value ?? this._defaultValue), this.id);
94
- this.keyManager = new FocusKeyManager(this.items).withHomeAndEnd();
95
- if (this.orientation === 'horizontal') {
96
- this.keyManager.withHorizontalOrientation(this.dir?.value || 'ltr');
97
- }
98
- else {
99
- this.keyManager.withVerticalOrientation();
100
- }
101
- this.onValueChangeSubscription = merge(...this.items.map((item) => item.expandedChange)).subscribe(() => this.onValueChange.emit());
102
- }
103
- /**
104
- * @ignore
105
- */
106
- ngOnDestroy() {
107
- this.openCloseAllActions.complete();
108
- this.onValueChangeSubscription.unsubscribe();
109
- }
110
- /**
111
- * @ignore
112
- */
113
- handleKeydown(event) {
114
- if (!this.keyManager.activeItem) {
115
- this.keyManager.setFirstItemActive();
116
- }
117
- const activeItem = this.keyManager.activeItem;
118
- if ((event.keyCode === ENTER || event.keyCode === SPACE) &&
119
- !this.keyManager.isTyping() &&
120
- activeItem &&
121
- !activeItem.disabled) {
122
- event.preventDefault();
123
- activeItem.toggle();
124
- }
125
- else if (event.keyCode === TAB && event.shiftKey) {
126
- if (this.keyManager.activeItemIndex === 0)
127
- return;
128
- this.keyManager.setPreviousItemActive();
129
- event.preventDefault();
130
- }
131
- else if (event.keyCode === TAB) {
132
- if (this.keyManager.activeItemIndex === this.items.length - 1)
68
+ this.onValueChange = output();
69
+ this.isCollapsible = computed(() => {
70
+ return this.collapsible();
71
+ });
72
+ this.isSingle = computed(() => this.type() === 'single');
73
+ this.changeModelValue = (value, isOpen) => {
74
+ if (!isOpen && !this.isCollapsible()) {
133
75
  return;
134
- this.keyManager.setNextItemActive();
135
- event.preventDefault();
136
- }
137
- else {
138
- this.keyManager.onKeydown(event);
139
- }
140
- }
141
- /** Opens all enabled accordion items in an accordion where multi is enabled.
142
- * @ignore
143
- */
144
- openAll() {
145
- if (this.isMultiple) {
146
- this.openCloseAllActions.next(true);
147
- }
148
- }
149
- /** Closes all enabled accordion items.
150
- * @ignore
151
- */
152
- closeAll() {
153
- this.openCloseAllActions.next(false);
154
- }
155
- /**
156
- * @ignore
157
- */
158
- setActiveItem(item) {
159
- this.keyManager.setActiveItem(item);
76
+ }
77
+ if (this.type() === 'multiple') {
78
+ this.value.update((v) => {
79
+ if (Array.isArray(v)) {
80
+ return isOpen ? [...v, value] : v.filter((i) => i !== value);
81
+ }
82
+ return isOpen ? [value] : [];
83
+ });
84
+ }
85
+ else {
86
+ if (isOpen) {
87
+ this.value.set(value);
88
+ }
89
+ }
90
+ };
91
+ this.isItemOpen = (value) => {
92
+ if (this.type() == 'multiple') {
93
+ return !!this.value()?.includes(value);
94
+ }
95
+ return this.value() === value;
96
+ };
97
+ effect(() => {
98
+ if (this.defaultValue() !== undefined) {
99
+ this.value.set(this.defaultValue());
100
+ }
101
+ });
160
102
  }
161
103
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
162
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.4", 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: [
163
- { provide: RdxAccordionRootToken, useExisting: RdxAccordionRootDirective },
164
- { provide: UniqueSelectionDispatcher, useClass: UniqueSelectionDispatcher }
165
- ], queries: [{ propertyName: "items", predicate: i0.forwardRef(() => RdxAccordionItemDirective), descendants: true }], ngImport: i0 }); }
104
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.4", type: RdxAccordionRootDirective, isStandalone: true, selector: "[rdxAccordionRoot]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChange: "onValueChange" }, host: { properties: { "attr.data-orientation": "orientation()" } }, providers: [provideAccordionRootContext(rootContext)], exportAs: ["rdxAccordionRoot"], ngImport: i0 }); }
166
105
  }
167
106
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionRootDirective, decorators: [{
168
107
  type: Directive,
169
108
  args: [{
170
109
  selector: '[rdxAccordionRoot]',
171
- standalone: true,
172
- providers: [
173
- { provide: RdxAccordionRootToken, useExisting: RdxAccordionRootDirective },
174
- { provide: UniqueSelectionDispatcher, useClass: UniqueSelectionDispatcher }
175
- ],
110
+ exportAs: 'rdxAccordionRoot',
111
+ providers: [provideAccordionRootContext(rootContext)],
176
112
  host: {
177
- '[attr.data-orientation]': 'orientation',
178
- '(keydown)': 'handleKeydown($event)'
113
+ '[attr.data-orientation]': 'orientation()'
179
114
  }
180
115
  }]
181
- }], propDecorators: { disabled: [{
182
- type: Input,
183
- args: [{ transform: booleanAttribute }]
184
- }], orientation: [{
185
- type: Input
186
- }], items: [{
187
- type: ContentChildren,
188
- args: [forwardRef(() => RdxAccordionItemDirective), { descendants: true }]
189
- }], defaultValue: [{
190
- type: Input
191
- }], type: [{
192
- type: Input
193
- }], collapsible: [{
194
- type: Input
195
- }], value: [{
196
- type: Input
197
- }], onValueChange: [{
198
- type: Output
199
- }] } });
116
+ }], ctorParameters: () => [] });
200
117
 
201
- class RdxAccordionTriggerDirective {
202
- constructor() {
203
- this.nativeElement = inject(ElementRef).nativeElement;
204
- this.accordionRoot = inject(RdxAccordionRootDirective);
205
- this.item = inject(RdxAccordionItemDirective);
206
- }
207
- /**
208
- * Fires when trigger clicked
209
- */
210
- onClick() {
211
- if (!this.accordionRoot.collapsible && this.item.expanded)
212
- return;
213
- this.item.toggle();
214
- this.accordionRoot.setActiveItem(this.item);
215
- }
216
- focus() {
217
- this.nativeElement.focus();
218
- }
219
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
220
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.4", 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 }); }
221
- }
222
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionTriggerDirective, decorators: [{
223
- type: Directive,
224
- args: [{
225
- selector: '[rdxAccordionTrigger]',
226
- standalone: true,
227
- host: {
228
- '[attr.role]': '"button"',
229
- '[attr.aria-expanded]': 'item.expanded',
230
- '[attr.data-state]': 'item.dataState',
231
- '[attr.data-disabled]': 'item.disabled',
232
- '[attr.disabled]': 'item.disabled ? "" : null',
233
- '[attr.data-orientation]': 'item.orientation',
234
- '(click)': 'onClick()'
235
- }
236
- }]
237
- }] });
238
-
239
- let nextId = 0;
118
+ const [injectAccordionItemContext, provideAccordionItemContext] = createContext('AccordionItemContext');
119
+ const itemContext = () => {
120
+ const instance = inject(RdxAccordionItemDirective);
121
+ return {
122
+ open: instance.open,
123
+ dataState: instance.dataState,
124
+ disabled: instance.disabled,
125
+ dataDisabled: instance.isDisabled,
126
+ triggerId: '',
127
+ currentElement: instance.elementRef,
128
+ value: computed(() => instance.value())
129
+ };
130
+ };
240
131
  /**
241
132
  * @group Components
242
133
  */
243
134
  class RdxAccordionItemDirective {
244
- get dataState() {
245
- return this.expanded ? 'open' : 'closed';
246
- }
247
- get orientation() {
248
- return this.accordion.orientation;
249
- }
250
- /**
251
- * @defaultValue false
252
- * @group Props
253
- */
254
- set expanded(expanded) {
255
- // Only emit events and update the internal value if the value changes.
256
- if (this._expanded !== expanded) {
257
- this._expanded = expanded;
258
- this.expandedChange.emit(expanded);
259
- if (expanded) {
260
- this.opened.emit();
261
- /**
262
- * In the unique selection dispatcher, the id parameter is the id of the CdkAccordionItem,
263
- * the name value is the id of the accordion.
264
- */
265
- const accordionId = this.accordion ? this.accordion.id : this.value;
266
- this.expansionDispatcher.notify(this.value, accordionId);
267
- }
268
- else {
269
- this.closed.emit();
270
- }
271
- // Ensures that the animation will run when the value is set outside of an `@Input`.
272
- // This includes cases like the open, close and toggle methods.
273
- this.changeDetectorRef.markForCheck();
274
- }
275
- }
276
- get expanded() {
277
- return this._expanded;
278
- }
279
- /**
280
- * Accordion value.
281
- *
282
- * @group Props
283
- */
284
- set value(value) {
285
- this._value = value;
286
- }
287
- get value() {
288
- return this._value || this.id;
289
- }
290
- /**
291
- * Whether the AccordionItem is disabled.
292
- *
293
- * @defaultValue false
294
- * @group Props
295
- */
296
- set disabled(value) {
297
- this._disabled = value;
298
- }
299
- get disabled() {
300
- return this.accordion.disabled ?? this._disabled;
301
- }
302
135
  constructor() {
303
- this.accordion = inject(RdxAccordionRootToken, { skipSelf: true });
304
- this.changeDetectorRef = inject(ChangeDetectorRef);
305
- this.expansionDispatcher = inject(UniqueSelectionDispatcher);
306
- /**
307
- * The unique AccordionItem id.
308
- * @ignore
309
- */
310
- this.id = `rdx-accordion-item-${nextId++}`;
311
- this._expanded = false;
312
- this._disabled = false;
313
- /**
314
- * Event emitted every time the AccordionItem is closed.
315
- */
316
- this.closed = new EventEmitter();
317
- /** Event emitted every time the AccordionItem is opened. */
318
- this.opened = new EventEmitter();
319
- /**
320
- * Event emitted when the AccordionItem is destroyed.
321
- * @ignore
322
- */
323
- this.destroyed = new EventEmitter();
324
- /**
325
- * Emits whenever the expanded state of the accordion changes.
326
- * Primarily used to facilitate two-way binding.
327
- * @group Emits
328
- */
329
- this.expandedChange = new EventEmitter();
330
- /** Subscription to openAll/closeAll events. */
331
- this.openCloseAllSubscription = Subscription.EMPTY;
332
- this.removeUniqueSelectionListener = this.expansionDispatcher.listen((id, accordionId) => {
333
- if (this.accordion.isMultiple) {
334
- if (this.accordion.id === accordionId && id.includes(this.value)) {
335
- this.expanded = true;
336
- }
136
+ this.elementRef = inject(ElementRef);
137
+ this.collapsibleContext = injectCollapsibleRootContext();
138
+ this.rootContext = injectAccordionRootContext();
139
+ this.value = input();
140
+ this.disabled = input(false, { transform: booleanAttribute });
141
+ this.isDisabled = computed(() => {
142
+ return this.rootContext.disabled() || this.disabled();
143
+ });
144
+ this.open = computed(() => this.rootContext.isItemOpen(this.value()));
145
+ this.dataState = computed(() => (this.open() ? 'open' : 'closed'));
146
+ effect(() => {
147
+ this.rootContext.changeModelValue(this.value(), this.collapsibleContext.open());
148
+ });
149
+ let onMount = false;
150
+ effect(() => {
151
+ if (!onMount && this.open() && !this.collapsibleContext.open()) {
152
+ this.collapsibleContext.toggle();
153
+ onMount = true;
337
154
  }
338
- else {
339
- this.expanded = this.accordion.id === accordionId && id.includes(this.value);
155
+ if (!this.open() && this.collapsibleContext.open()) {
156
+ this.collapsibleContext.toggle();
340
157
  }
341
158
  });
342
- // When an accordion item is hosted in an accordion, subscribe to open/close events.
343
- if (this.accordion) {
344
- this.openCloseAllSubscription = this.subscribeToOpenCloseAllActions();
345
- }
346
- }
347
- /** Emits an event for the accordion item being destroyed. */
348
- ngOnDestroy() {
349
- this.opened.complete();
350
- this.closed.complete();
351
- this.destroyed.emit();
352
- this.destroyed.complete();
353
- this.removeUniqueSelectionListener();
354
- this.openCloseAllSubscription.unsubscribe();
355
- }
356
- focus() {
357
- this.trigger.focus();
358
- }
359
- /** Toggles the expanded state of the accordion item. */
360
- toggle() {
361
- if (!this.disabled) {
362
- this.content.onToggle();
363
- this.expanded = !this.expanded;
364
- }
365
159
  }
366
- /** Sets the expanded state of the accordion item to false. */
367
- close() {
368
- if (!this.disabled) {
369
- this.expanded = false;
370
- }
371
- }
372
- /** Sets the expanded state of the accordion item to true. */
373
- open() {
374
- if (!this.disabled) {
375
- this.expanded = true;
376
- }
377
- }
378
- subscribeToOpenCloseAllActions() {
379
- return this.accordion.openCloseAllActions.subscribe((expanded) => {
380
- // Only change expanded state if item is enabled
381
- if (!this.disabled) {
382
- this.expanded = expanded;
383
- }
160
+ handleArrowKey(event) {
161
+ const target = event.target;
162
+ const allCollectionItems = Array.from(this.rootContext.elementRef.nativeElement?.querySelectorAll('[data-rdx-collection-item]') ?? []);
163
+ const collectionItemIndex = allCollectionItems.findIndex((item) => item === target);
164
+ if (collectionItemIndex === -1)
165
+ return;
166
+ useArrowNavigation(event, this.elementRef.nativeElement.querySelector('[data-rdx-collection-item]'), this.rootContext.elementRef.nativeElement, {
167
+ arrowKeyOptions: this.rootContext.orientation(),
168
+ dir: this.rootContext.direction(),
169
+ focus: true
384
170
  });
385
171
  }
386
172
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
387
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.4", 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: [
388
- { provide: RdxAccordionRootToken, useValue: undefined }
389
- ], queries: [{ propertyName: "trigger", first: true, predicate: RdxAccordionTriggerDirective, descendants: true }, { propertyName: "content", first: true, predicate: i0.forwardRef(() => RdxAccordionContentDirective), descendants: true }], exportAs: ["rdxAccordionItem"], ngImport: i0 }); }
173
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.4", type: RdxAccordionItemDirective, isStandalone: true, selector: "[rdxAccordionItem]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown.arrowDown": "handleArrowKey($event)", "keydown.arrowUp": "handleArrowKey($event)", "keydown.arrowLeft": "handleArrowKey($event)", "keydown.arrowRight": "handleArrowKey($event)", "keydown.home": "handleArrowKey($event)", "keydown.end": "handleArrowKey($event)" }, properties: { "attr.data-orientation": "rootContext.orientation()", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-state": "dataState()" } }, providers: [provideAccordionItemContext(itemContext)], exportAs: ["rdxAccordionItem"], hostDirectives: [{ directive: i1.RdxCollapsibleRootDirective, inputs: ["disabled", "disabled"] }], ngImport: i0 }); }
390
174
  }
391
175
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionItemDirective, decorators: [{
392
176
  type: Directive,
393
177
  args: [{
394
178
  selector: '[rdxAccordionItem]',
395
- standalone: true,
396
179
  exportAs: 'rdxAccordionItem',
180
+ providers: [provideAccordionItemContext(itemContext)],
181
+ hostDirectives: [
182
+ {
183
+ directive: RdxCollapsibleRootDirective,
184
+ inputs: ['disabled: disabled']
185
+ }
186
+ ],
397
187
  host: {
398
- '[attr.data-state]': 'dataState',
399
- '[attr.data-disabled]': 'disabled',
400
- '[attr.data-orientation]': 'orientation'
401
- },
402
- providers: [
403
- { provide: RdxAccordionRootToken, useValue: undefined }
404
- ]
188
+ '[attr.data-orientation]': 'rootContext.orientation()',
189
+ '[attr.data-disabled]': 'disabled() ? "" : undefined',
190
+ '[attr.data-state]': 'dataState()',
191
+ '(keydown.arrowDown)': 'handleArrowKey($event)',
192
+ '(keydown.arrowUp)': 'handleArrowKey($event)',
193
+ '(keydown.arrowLeft)': 'handleArrowKey($event)',
194
+ '(keydown.arrowRight)': 'handleArrowKey($event)',
195
+ '(keydown.home)': 'handleArrowKey($event)',
196
+ '(keydown.end)': 'handleArrowKey($event)'
197
+ }
405
198
  }]
406
- }], ctorParameters: () => [], propDecorators: { trigger: [{
407
- type: ContentChild,
408
- args: [RdxAccordionTriggerDirective, { descendants: true }]
409
- }], content: [{
410
- type: ContentChild,
411
- args: [forwardRef(() => RdxAccordionContentDirective), { descendants: true }]
412
- }], expanded: [{
413
- type: Input,
414
- args: [{ transform: booleanAttribute }]
415
- }], value: [{
416
- type: Input
417
- }], disabled: [{
418
- type: Input,
419
- args: [{ transform: booleanAttribute }]
420
- }], closed: [{
421
- type: Output
422
- }], opened: [{
423
- type: Output
424
- }], expandedChange: [{
425
- type: Output
426
- }] } });
199
+ }], ctorParameters: () => [] });
427
200
 
428
201
  class RdxAccordionContentDirective {
429
202
  constructor() {
430
- this.item = inject(RdxAccordionItemDirective);
431
- this.nativeElement = inject(ElementRef).nativeElement;
432
- this.hidden = false;
433
- }
434
- onAnimationEnd() {
435
- this.hidden = !this.item.expanded;
436
- const { height, width } = this.nativeElement.getBoundingClientRect();
437
- this.nativeElement.style.setProperty('--radix-collapsible-content-height', `${height}px`);
438
- this.nativeElement.style.setProperty('--radix-collapsible-content-width', `${width}px`);
439
- this.nativeElement.style.setProperty('--radix-accordion-content-height', 'var(--radix-collapsible-content-height)');
440
- this.nativeElement.style.setProperty('--radix-accordion-content-width', 'var(--radix-collapsible-content-width)');
441
- }
442
- onToggle() {
443
- if (!this.item.expanded) {
444
- this.hidden = false;
445
- }
203
+ this.rootContext = injectAccordionRootContext();
204
+ this.itemContext = injectAccordionItemContext();
446
205
  }
447
206
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
448
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.4", type: RdxAccordionContentDirective, isStandalone: true, selector: "[rdxAccordionContent]", host: { listeners: { "animationend": "onAnimationEnd()" }, properties: { "attr.role": "\"region\"", "style.display": "hidden ? \"none\" : \"\"", "attr.data-state": "item.dataState", "attr.data-disabled": "item.disabled", "attr.data-orientation": "item.orientation" } }, exportAs: ["rdxAccordionContent"], ngImport: i0 }); }
207
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.4", type: RdxAccordionContentDirective, isStandalone: true, selector: "[rdxAccordionContent]", host: { attributes: { "role": "region" }, properties: { "attr.aria-labelledby": "itemContext.triggerId", "attr.data-state": "itemContext.dataState()", "attr.data-disabled": "itemContext.dataDisabled()", "attr.data-orientation": "rootContext.orientation()", "style": "{\n '--radix-accordion-content-height': 'var(--radix-collapsible-content-height)',\n '--radix-accordion-content-width': 'var(--radix-collapsible-content-width)',\n }" } }, hostDirectives: [{ directive: i1.RdxCollapsibleContentDirective }], ngImport: i0 }); }
449
208
  }
450
209
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionContentDirective, decorators: [{
451
210
  type: Directive,
452
211
  args: [{
453
212
  selector: '[rdxAccordionContent]',
454
- standalone: true,
455
- exportAs: 'rdxAccordionContent',
213
+ hostDirectives: [RdxCollapsibleContentDirective],
456
214
  host: {
457
- '[attr.role]': '"region"',
458
- '[style.display]': 'hidden ? "none" : ""',
459
- '[attr.data-state]': 'item.dataState',
460
- '[attr.data-disabled]': 'item.disabled',
461
- '[attr.data-orientation]': 'item.orientation',
462
- '(animationend)': 'onAnimationEnd()'
215
+ role: 'region',
216
+ '[attr.aria-labelledby]': 'itemContext.triggerId',
217
+ '[attr.data-state]': 'itemContext.dataState()',
218
+ '[attr.data-disabled]': 'itemContext.dataDisabled()',
219
+ '[attr.data-orientation]': 'rootContext.orientation()',
220
+ '[style]': `{
221
+ '--radix-accordion-content-height': 'var(--radix-collapsible-content-height)',
222
+ '--radix-accordion-content-width': 'var(--radix-collapsible-content-width)',
223
+ }`
463
224
  }
464
225
  }]
465
226
  }] });
466
227
 
467
228
  class RdxAccordionHeaderDirective {
468
229
  constructor() {
469
- this.item = inject(RdxAccordionItemDirective);
230
+ this.rootContext = injectAccordionRootContext();
231
+ this.itemContext = injectAccordionItemContext();
470
232
  }
471
233
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
472
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.4", 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 }); }
234
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.4", type: RdxAccordionHeaderDirective, isStandalone: true, selector: "[rdxAccordionHeader]", host: { properties: { "attr.data-state": "itemContext.dataState()", "attr.data-disabled": "itemContext.dataDisabled()", "attr.data-orientation": "rootContext.orientation()" } }, ngImport: i0 }); }
473
235
  }
474
236
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionHeaderDirective, decorators: [{
475
237
  type: Directive,
476
238
  args: [{
477
239
  selector: '[rdxAccordionHeader]',
478
- standalone: true,
479
240
  host: {
480
- '[attr.data-state]': 'item.dataState',
481
- '[attr.data-disabled]': 'item.disabled',
482
- '[attr.data-orientation]': 'item.orientation'
241
+ '[attr.data-state]': 'itemContext.dataState()',
242
+ '[attr.data-disabled]': 'itemContext.dataDisabled()',
243
+ '[attr.data-orientation]': 'rootContext.orientation()'
483
244
  }
484
245
  }]
485
246
  }] });
486
247
 
248
+ class RdxAccordionTriggerDirective {
249
+ constructor() {
250
+ this.rootContext = injectAccordionRootContext();
251
+ this.itemContext = injectAccordionItemContext();
252
+ this.itemContext.triggerId = inject(_IdGenerator).getId('rdx-accordion-trigger-');
253
+ }
254
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
255
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.4", type: RdxAccordionTriggerDirective, isStandalone: true, selector: "[rdxAccordionTrigger]", host: { properties: { "id": "itemContext.triggerId", "attr.data-rdx-collection-item": "\"\"", "attr.role": "\"button\"", "attr.aria-disabled": "itemContext.disabled() || undefined", "attr.data-orientation": "rootContext.orientation()" } }, hostDirectives: [{ directive: i1.RdxCollapsibleTriggerDirective }], ngImport: i0 }); }
256
+ }
257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionTriggerDirective, decorators: [{
258
+ type: Directive,
259
+ args: [{
260
+ selector: '[rdxAccordionTrigger]',
261
+ hostDirectives: [RdxCollapsibleTriggerDirective],
262
+ host: {
263
+ '[id]': 'itemContext.triggerId',
264
+ '[attr.data-rdx-collection-item]': '""',
265
+ '[attr.role]': '"button"',
266
+ '[attr.aria-disabled]': 'itemContext.disabled() || undefined',
267
+ '[attr.data-orientation]': 'rootContext.orientation()'
268
+ }
269
+ }]
270
+ }], ctorParameters: () => [] });
271
+
487
272
  const _imports = [
488
273
  RdxAccordionContentDirective,
489
274
  RdxAccordionHeaderDirective,
490
275
  RdxAccordionItemDirective,
491
276
  RdxAccordionRootDirective,
492
- RdxAccordionTriggerDirective
277
+ RdxAccordionTriggerDirective,
278
+ RdxAccordionContentPresenceDirective
493
279
  ];
494
280
  class RdxAccordionModule {
495
281
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -497,11 +283,13 @@ class RdxAccordionModule {
497
283
  RdxAccordionHeaderDirective,
498
284
  RdxAccordionItemDirective,
499
285
  RdxAccordionRootDirective,
500
- RdxAccordionTriggerDirective], exports: [RdxAccordionContentDirective,
286
+ RdxAccordionTriggerDirective,
287
+ RdxAccordionContentPresenceDirective], exports: [RdxAccordionContentDirective,
501
288
  RdxAccordionHeaderDirective,
502
289
  RdxAccordionItemDirective,
503
290
  RdxAccordionRootDirective,
504
- RdxAccordionTriggerDirective] }); }
291
+ RdxAccordionTriggerDirective,
292
+ RdxAccordionContentPresenceDirective] }); }
505
293
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionModule }); }
506
294
  }
507
295
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: RdxAccordionModule, decorators: [{
@@ -516,5 +304,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
516
304
  * Generated bundle index. Do not edit.
517
305
  */
518
306
 
519
- export { RdxAccordionContentDirective, RdxAccordionHeaderDirective, RdxAccordionItemDirective, RdxAccordionModule, RdxAccordionRootDirective, RdxAccordionRootToken, RdxAccordionTriggerDirective };
307
+ export { RdxAccordionContentDirective, RdxAccordionContentPresenceDirective, RdxAccordionHeaderDirective, RdxAccordionItemDirective, RdxAccordionModule, RdxAccordionRootDirective, RdxAccordionTriggerDirective, injectAccordionItemContext, injectAccordionRootContext, provideAccordionItemContext, provideAccordionRootContext };
520
308
  //# sourceMappingURL=radix-ng-primitives-accordion.mjs.map