@radix-ng/primitives 1.0.0-beta.5 → 1.0.2

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 (62) hide show
  1. package/composite/README.md +3 -0
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +20 -44
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-checkbox.mjs +134 -58
  5. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-composite.mjs +599 -0
  7. package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -0
  8. package/fesm2022/radix-ng-primitives-drawer.mjs +442 -2
  9. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-menu.mjs +315 -68
  11. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-menubar.mjs +91 -36
  13. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  14. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +281 -88
  15. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-popover.mjs +40 -15
  17. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-popper.mjs +73 -65
  19. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-radio.mjs +63 -27
  21. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  22. package/fesm2022/radix-ng-primitives-scroll-area.mjs +56 -25
  23. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-select.mjs +59 -29
  25. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-slider.mjs +57 -13
  27. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-tabs.mjs +335 -73
  29. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-toggle-group.mjs +66 -21
  31. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-toggle.mjs +29 -11
  33. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-toolbar.mjs +68 -36
  35. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  36. package/navigation-menu/README.md +5 -2
  37. package/package.json +6 -10
  38. package/types/radix-ng-primitives-accordion.d.ts +12 -16
  39. package/types/radix-ng-primitives-checkbox.d.ts +98 -70
  40. package/types/radix-ng-primitives-composite.d.ts +195 -0
  41. package/types/radix-ng-primitives-drawer.d.ts +40 -2
  42. package/types/radix-ng-primitives-menu.d.ts +46 -16
  43. package/types/radix-ng-primitives-menubar.d.ts +12 -5
  44. package/types/radix-ng-primitives-navigation-menu.d.ts +65 -33
  45. package/types/radix-ng-primitives-popover.d.ts +9 -5
  46. package/types/radix-ng-primitives-popper.d.ts +1 -0
  47. package/types/radix-ng-primitives-radio.d.ts +11 -9
  48. package/types/radix-ng-primitives-scroll-area.d.ts +4 -1
  49. package/types/radix-ng-primitives-select.d.ts +46 -32
  50. package/types/radix-ng-primitives-slider.d.ts +19 -4
  51. package/types/radix-ng-primitives-tabs.d.ts +69 -14
  52. package/types/radix-ng-primitives-toggle-group.d.ts +27 -16
  53. package/types/radix-ng-primitives-toggle.d.ts +5 -5
  54. package/types/radix-ng-primitives-toolbar.d.ts +84 -69
  55. package/collection/README.md +0 -1
  56. package/fesm2022/radix-ng-primitives-collection.mjs +0 -72
  57. package/fesm2022/radix-ng-primitives-collection.mjs.map +0 -1
  58. package/fesm2022/radix-ng-primitives-roving-focus.mjs +0 -388
  59. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +0 -1
  60. package/roving-focus/README.md +0 -3
  61. package/types/radix-ng-primitives-collection.d.ts +0 -44
  62. package/types/radix-ng-primitives-roving-focus.d.ts +0 -187
@@ -1,388 +0,0 @@
1
- import { isPlatformBrowser } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { inject, PLATFORM_ID, ElementRef, DestroyRef, input, booleanAttribute, model, output, linkedSignal, signal, effect, Directive, computed, untracked } from '@angular/core';
4
- import { createContext } from '@radix-ng/primitives/core';
5
- import { injectDirection } from '@radix-ng/primitives/direction-provider';
6
-
7
- const ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';
8
- const EVENT_OPTIONS = { bubbles: false, cancelable: true };
9
- const MAP_KEY_TO_FOCUS_INTENT = {
10
- ArrowLeft: 'prev',
11
- ArrowUp: 'prev',
12
- ArrowRight: 'next',
13
- ArrowDown: 'next',
14
- PageUp: 'first',
15
- Home: 'first',
16
- PageDown: 'last',
17
- End: 'last'
18
- };
19
- function getDirectionAwareKey(key, dir) {
20
- if (dir !== 'rtl')
21
- return key;
22
- return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
23
- }
24
- function getFocusIntent(event, orientation, dir) {
25
- const key = getDirectionAwareKey(event.key, dir);
26
- if (orientation === 'vertical' && ['ArrowLeft', 'ArrowRight'].includes(key))
27
- return undefined;
28
- if (orientation === 'horizontal' && ['ArrowUp', 'ArrowDown'].includes(key))
29
- return undefined;
30
- return MAP_KEY_TO_FOCUS_INTENT[key];
31
- }
32
- function focusFirst(candidates, preventScroll = false, rootNode) {
33
- const PREVIOUSLY_FOCUSED_ELEMENT = rootNode?.activeElement ?? document.activeElement;
34
- for (const candidate of candidates) {
35
- // if focus is already where we want to go, we don't want to keep going through the candidates
36
- if (candidate === PREVIOUSLY_FOCUSED_ELEMENT)
37
- return;
38
- candidate.focus({ preventScroll });
39
- if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT)
40
- return;
41
- }
42
- }
43
- /**
44
- * Wraps an array around itself at a given start index
45
- * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
46
- */
47
- function wrapArray(array, startIndex) {
48
- return array.map((_, index) => array[(startIndex + index) % array.length]);
49
- }
50
- /**
51
- * Sorts elements by their position in the document, so the order matches what the user sees.
52
- */
53
- function sortByDocumentPosition(elements) {
54
- return [...elements].sort((a, b) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));
55
- }
56
- let idCounter = 0;
57
- function generateId() {
58
- return `rf-item-${++idCounter}`;
59
- }
60
-
61
- const rootContext = () => {
62
- const rovingFocusGroup = inject(RdxRovingFocusGroupDirective);
63
- return {
64
- loop: rovingFocusGroup.loop,
65
- dir: rovingFocusGroup.dir,
66
- orientation: rovingFocusGroup.orientation,
67
- currentTabStopId: rovingFocusGroup.currentTabStopId,
68
- focusableItems: rovingFocusGroup.focusableItems,
69
- onItemFocus: (tabStopId) => {
70
- rovingFocusGroup.currentTabStopId.set(tabStopId);
71
- },
72
- onItemShiftTab: () => {
73
- rovingFocusGroup.isTabbingBackOut.set(true);
74
- },
75
- registerItem: (item, tabStopId) => rovingFocusGroup.registerItem(item, tabStopId),
76
- unregisterItem: (item, tabStopId) => rovingFocusGroup.unregisterItem(item, tabStopId)
77
- };
78
- };
79
- const [injectRovingFocusGroupContext, provideRovingFocusGroupContext] = createContext('RovingFocusGroupContext', 'utils/roving-focus');
80
- /**
81
- * @group Components
82
- */
83
- class RdxRovingFocusGroupDirective {
84
- constructor() {
85
- this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
86
- this.elementRef = inject(ElementRef);
87
- this.destroyRef = inject(DestroyRef);
88
- /**
89
- * The orientation of the group. Mainly so arrow navigation is done accordingly (left & right vs. up & down)
90
- */
91
- this.orientationInput = input('horizontal', { ...(ngDevMode ? { debugName: "orientationInput" } : /* istanbul ignore next */ {}), alias: 'orientation' });
92
- /**
93
- * The direction of navigation between items.
94
- */
95
- this.dirInput = input(undefined, { ...(ngDevMode ? { debugName: "dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
96
- this.effectiveDir = injectDirection(this.dirInput);
97
- /**
98
- * Whether keyboard navigation should loop around
99
- */
100
- this.loopInput = input(true, { ...(ngDevMode ? { debugName: "loopInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'loop' });
101
- /**
102
- * When `true`, will prevent scrolling to the focus item when focused.
103
- * @group Props
104
- */
105
- this.preventScrollOnEntryFocus = input(false, { ...(ngDevMode ? { debugName: "preventScrollOnEntryFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
106
- /**
107
- * The value of the current stop item.
108
- *
109
- * Use when you do not need to control the state of the stop item.
110
- * @group Props
111
- */
112
- this.defaultCurrentTabStopId = input(undefined, ...(ngDevMode ? [{ debugName: "defaultCurrentTabStopId" }] : /* istanbul ignore next */ []));
113
- /**
114
- * The controlled value of the current stop item. Can be binded as `model`.
115
- * @group Props
116
- */
117
- this.currentTabStopId = model(undefined, ...(ngDevMode ? [{ debugName: "currentTabStopId" }] : /* istanbul ignore next */ []));
118
- /**
119
- * Event handler called when container is being focused. Can be prevented.
120
- * @group Emits
121
- */
122
- this.entryFocus = output();
123
- this._orientation = linkedSignal(() => this.orientationInput(), ...(ngDevMode ? [{ debugName: "_orientation" }] : /* istanbul ignore next */ []));
124
- this.orientation = this._orientation.asReadonly();
125
- this._dir = linkedSignal(() => this.effectiveDir(), ...(ngDevMode ? [{ debugName: "_dir" }] : /* istanbul ignore next */ []));
126
- this.dir = this._dir.asReadonly();
127
- this._loop = linkedSignal(() => this.loopInput(), ...(ngDevMode ? [{ debugName: "_loop" }] : /* istanbul ignore next */ []));
128
- this.loop = this._loop.asReadonly();
129
- this.focusableItems = signal([], ...(ngDevMode ? [{ debugName: "focusableItems" }] : /* istanbul ignore next */ []));
130
- this.isClickFocus = signal(false, ...(ngDevMode ? [{ debugName: "isClickFocus" }] : /* istanbul ignore next */ []));
131
- this.isTabbingBackOut = signal(false, ...(ngDevMode ? [{ debugName: "isTabbingBackOut" }] : /* istanbul ignore next */ []));
132
- this.itemIds = new WeakMap();
133
- this.isDestroyed = false;
134
- this.destroyRef.onDestroy(() => {
135
- this.isDestroyed = true;
136
- });
137
- effect(() => {
138
- if (this.currentTabStopId() === undefined) {
139
- const def = this.defaultCurrentTabStopId();
140
- if (def !== undefined) {
141
- this.currentTabStopId.set(def);
142
- }
143
- }
144
- });
145
- }
146
- setOrientation(value) {
147
- this._orientation.set(value);
148
- }
149
- setDir(value) {
150
- this._dir.set(value);
151
- }
152
- setLoop(value) {
153
- this._loop.set(value);
154
- }
155
- /** @ignore */
156
- registerItem(item, tabStopId) {
157
- this.itemIds.set(item, tabStopId);
158
- // Keep the registry in DOM order, so arrow navigation matches the visual order
159
- // regardless of the order in which items are created/registered.
160
- this.focusableItems.update((items) => sortByDocumentPosition([...items, item]));
161
- }
162
- /** @ignore */
163
- unregisterItem(item, tabStopId) {
164
- const remainingItems = this.focusableItems().filter((el) => el !== item);
165
- this.focusableItems.set(remainingItems);
166
- this.itemIds.delete(item);
167
- if (!this.isDestroyed && this.currentTabStopId() === tabStopId) {
168
- this.currentTabStopId.set(this.itemIds.get(remainingItems[0]));
169
- }
170
- }
171
- /** @ignore */
172
- handleMouseUp() {
173
- if (!this.isBrowser)
174
- return;
175
- // reset `isClickFocus` after 1 tick because handleFocus might not triggered due to focused element
176
- requestAnimationFrame(() => {
177
- this.isClickFocus.set(false);
178
- });
179
- }
180
- /** @ignore */
181
- handleFocus(event) {
182
- // We normally wouldn't need this check, because we already check
183
- // that the focus is on the current target and not bubbling to it.
184
- // We do this because Safari doesn't focus buttons when clicked, and
185
- // instead, the wrapper will get focused and not through a bubbling event.
186
- const isKeyboardFocus = !this.isClickFocus();
187
- if (event.currentTarget === this.elementRef.nativeElement &&
188
- event.target === event.currentTarget &&
189
- isKeyboardFocus &&
190
- !this.isTabbingBackOut()) {
191
- const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
192
- this.elementRef.nativeElement.dispatchEvent(entryFocusEvent);
193
- this.entryFocus.emit(entryFocusEvent);
194
- if (!entryFocusEvent.defaultPrevented) {
195
- const items = this.focusableItems().filter((item) => item.dataset['disabled'] !== '');
196
- const activeItem = items.find((item) => item.getAttribute('data-active') === 'true');
197
- // The current tab stop is the only item with `tabindex="0"` (driven by
198
- // `currentTabStopId`). We match on it instead of the DOM `id`, because consumers
199
- // (tabs, navigation-menu) own the element `id` and it may not equal the internal id.
200
- const currentItem = items.find((item) => item.getAttribute('tabindex') === '0');
201
- const candidateItems = [activeItem, currentItem, ...items].filter(Boolean);
202
- focusFirst(candidateItems, this.preventScrollOnEntryFocus());
203
- }
204
- }
205
- this.isClickFocus.set(false);
206
- }
207
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
208
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxRovingFocusGroupDirective, isStandalone: true, selector: "[rdxRovingFocusGroup]", inputs: { orientationInput: { classPropertyName: "orientationInput", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, dirInput: { classPropertyName: "dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, loopInput: { classPropertyName: "loopInput", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, preventScrollOnEntryFocus: { classPropertyName: "preventScrollOnEntryFocus", publicName: "preventScrollOnEntryFocus", isSignal: true, isRequired: false, transformFunction: null }, defaultCurrentTabStopId: { classPropertyName: "defaultCurrentTabStopId", publicName: "defaultCurrentTabStopId", isSignal: true, isRequired: false, transformFunction: null }, currentTabStopId: { classPropertyName: "currentTabStopId", publicName: "currentTabStopId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentTabStopId: "currentTabStopIdChange", entryFocus: "entryFocus" }, host: { listeners: { "focus": "handleFocus($event)", "focusout": "isTabbingBackOut.set(false)", "mouseup": "handleMouseUp()", "mousedown": "isClickFocus.set(true)" }, properties: { "attr.data-orientation": "orientation()", "attr.tabindex": "isTabbingBackOut() || focusableItems().length === 0 ? -1 : 0", "attr.dir": "dir()" } }, providers: [provideRovingFocusGroupContext(rootContext)], ngImport: i0 }); }
209
- }
210
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusGroupDirective, decorators: [{
211
- type: Directive,
212
- args: [{
213
- selector: '[rdxRovingFocusGroup]',
214
- providers: [provideRovingFocusGroupContext(rootContext)],
215
- host: {
216
- '[attr.data-orientation]': 'orientation()',
217
- '[attr.tabindex]': 'isTabbingBackOut() || focusableItems().length === 0 ? -1 : 0',
218
- '[attr.dir]': 'dir()',
219
- '(focus)': 'handleFocus($event)',
220
- '(focusout)': 'isTabbingBackOut.set(false)',
221
- '(mouseup)': 'handleMouseUp()',
222
- '(mousedown)': 'isClickFocus.set(true)'
223
- }
224
- }]
225
- }], ctorParameters: () => [], propDecorators: { orientationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], loopInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }], preventScrollOnEntryFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "preventScrollOnEntryFocus", required: false }] }], defaultCurrentTabStopId: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultCurrentTabStopId", required: false }] }], currentTabStopId: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentTabStopId", required: false }] }, { type: i0.Output, args: ["currentTabStopIdChange"] }], entryFocus: [{ type: i0.Output, args: ["entryFocus"] }] } });
226
-
227
- /**
228
- * @group Components
229
- */
230
- class RdxRovingFocusItemDirective {
231
- constructor() {
232
- this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
233
- this.elementRef = inject(ElementRef);
234
- /**
235
- * The enclosing roving-focus group. Optional: when the item is used outside a group
236
- * (e.g. a standalone Toggle), it degrades to a plain element and does not manage focus.
237
- */
238
- this.rootContext = injectRovingFocusGroupContext(true);
239
- /**
240
- * When false, item will not be focusable.
241
- * @group Props
242
- */
243
- this.focusableInput = input(true, { ...(ngDevMode ? { debugName: "focusableInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'focusable' });
244
- /**
245
- * When `true`, marks the item as the active one, so it is preferred when focus enters the group.
246
- * @group Props
247
- */
248
- this.activeInput = input(false, { ...(ngDevMode ? { debugName: "activeInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'active' });
249
- /**
250
- * @group Props
251
- */
252
- this.tabStopIdInput = input(undefined, { ...(ngDevMode ? { debugName: "tabStopIdInput" } : /* istanbul ignore next */ {}), alias: 'tabStopId' });
253
- /**
254
- * When true, shift + arrow key will allow focusing on next/previous item.
255
- * @group Props
256
- */
257
- this.allowShiftKey = input(false, { ...(ngDevMode ? { debugName: "allowShiftKey" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
258
- // Stable fallback id, generated once so it never changes across recomputations of `id`.
259
- this.generatedId = generateId();
260
- this.id = computed(() => this.tabStopId() || this.generatedId, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
261
- this.isCurrentTabStop = computed(() => this.rootContext?.currentTabStopId() === this.id(), ...(ngDevMode ? [{ debugName: "isCurrentTabStop" }] : /* istanbul ignore next */ []));
262
- this.focusable = linkedSignal(() => this.focusableInput(), ...(ngDevMode ? [{ debugName: "focusable" }] : /* istanbul ignore next */ []));
263
- this.active = linkedSignal(() => this.activeInput(), ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
264
- this.tabStopId = linkedSignal(() => this.tabStopIdInput(), ...(ngDevMode ? [{ debugName: "tabStopId" }] : /* istanbul ignore next */ []));
265
- /**
266
- * The roving tabindex. Without a group the item keeps its natural tab order (`null`); inside a
267
- * group exactly one focusable item is a tab stop (`0`), the rest are reachable only via arrows (`-1`).
268
- */
269
- this.tabindex = computed(() => {
270
- if (!this.rootContext) {
271
- return null;
272
- }
273
- return this.focusable() && this.isCurrentTabStop() ? 0 : -1;
274
- }, ...(ngDevMode ? [{ debugName: "tabindex" }] : /* istanbul ignore next */ []));
275
- // Keep the group's registry in sync with `focusable`, which can change after creation
276
- // (e.g. toolbar/navigation-menu toggle it via `setFocusable`). The cleanup also runs on
277
- // destroy, so a single effect covers register/unregister for the whole lifecycle.
278
- effect((onCleanup) => {
279
- const rootContext = this.rootContext;
280
- if (!rootContext || !this.focusable())
281
- return;
282
- const element = this.elementRef.nativeElement;
283
- // `registerItem` reads and writes the group's `focusableItems` signal; calling it
284
- // untracked prevents the effect from depending on its own write and looping.
285
- const tabStopId = this.id();
286
- untracked(() => rootContext.registerItem(element, tabStopId));
287
- onCleanup(() => rootContext.unregisterItem(element, tabStopId));
288
- });
289
- }
290
- setFocusable(value) {
291
- this.focusable.set(value);
292
- }
293
- setActive(value) {
294
- this.active.set(value);
295
- }
296
- setTabStopId(value) {
297
- this.tabStopId.set(value);
298
- }
299
- /** @ignore */
300
- onFocus() {
301
- this.rootContext?.onItemFocus(this.id());
302
- }
303
- /** @ignore */
304
- handleMouseDown(event) {
305
- if (!this.focusable()) {
306
- // We prevent focusing non-focusable items on `mousedown`.
307
- // Even though the item has tabIndex={-1}, that only means take it out of the tab order.
308
- event.preventDefault();
309
- }
310
- else {
311
- // Safari doesn't focus a button when clicked so we run our logic on mousedown also
312
- this.rootContext?.onItemFocus(this.id());
313
- }
314
- }
315
- /**
316
- * Handles the `keydown` event for keyboard navigation within the roving focus group.
317
- * Supports navigation based on orientation and direction, and focuses appropriate elements.
318
- *
319
- * @param event The `KeyboardEvent` object.
320
- * @ignore
321
- */
322
- handleKeydown(event) {
323
- const rootContext = this.rootContext;
324
- if (!rootContext)
325
- return;
326
- const keyEvent = event;
327
- if (keyEvent.key === 'Tab' && keyEvent.shiftKey) {
328
- rootContext.onItemShiftTab();
329
- return;
330
- }
331
- if (event.target !== this.elementRef.nativeElement)
332
- return;
333
- const focusIntent = getFocusIntent(keyEvent, rootContext.orientation(), rootContext.dir());
334
- if (focusIntent !== undefined) {
335
- if (keyEvent.metaKey ||
336
- keyEvent.ctrlKey ||
337
- keyEvent.altKey ||
338
- (this.allowShiftKey() ? false : keyEvent.shiftKey)) {
339
- return;
340
- }
341
- event.preventDefault();
342
- let candidateNodes = rootContext.focusableItems().filter((item) => item.dataset['disabled'] !== '');
343
- if (focusIntent === 'last') {
344
- candidateNodes.reverse();
345
- }
346
- else if (focusIntent === 'prev' || focusIntent === 'next') {
347
- if (focusIntent === 'prev')
348
- candidateNodes.reverse();
349
- const currentIndex = candidateNodes.indexOf(this.elementRef.nativeElement);
350
- candidateNodes = rootContext.loop()
351
- ? wrapArray(candidateNodes, currentIndex + 1)
352
- : candidateNodes.slice(currentIndex + 1);
353
- }
354
- queueMicrotask(() => {
355
- if (this.isBrowser) {
356
- const rootNode = this.elementRef.nativeElement.getRootNode();
357
- focusFirst(candidateNodes, false, rootNode);
358
- }
359
- });
360
- }
361
- }
362
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
363
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxRovingFocusItemDirective, isStandalone: true, selector: "[rdxRovingFocusItem]", inputs: { focusableInput: { classPropertyName: "focusableInput", publicName: "focusable", isSignal: true, isRequired: false, transformFunction: null }, activeInput: { classPropertyName: "activeInput", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, tabStopIdInput: { classPropertyName: "tabStopIdInput", publicName: "tabStopId", isSignal: true, isRequired: false, transformFunction: null }, allowShiftKey: { classPropertyName: "allowShiftKey", publicName: "allowShiftKey", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mousedown": "handleMouseDown($event)", "keydown": "handleKeydown($event)", "focus": "onFocus()" }, properties: { "attr.tabindex": "tabindex()", "attr.data-orientation": "rootContext?.orientation()", "attr.data-active": "active() ? \"true\" : undefined", "attr.data-disabled": "!focusable() ? \"\" : undefined" } }, ngImport: i0 }); }
364
- }
365
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusItemDirective, decorators: [{
366
- type: Directive,
367
- args: [{
368
- selector: '[rdxRovingFocusItem]',
369
- host: {
370
- '[attr.tabindex]': 'tabindex()',
371
- '[attr.data-orientation]': 'rootContext?.orientation()',
372
- '[attr.data-active]': 'active() ? "true" : undefined',
373
- '[attr.data-disabled]': '!focusable() ? "" : undefined',
374
- '(mousedown)': 'handleMouseDown($event)',
375
- '(keydown)': 'handleKeydown($event)',
376
- '(focus)': 'onFocus()'
377
- }
378
- }]
379
- }], ctorParameters: () => [], propDecorators: { focusableInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusable", required: false }] }], activeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], tabStopIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabStopId", required: false }] }], allowShiftKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowShiftKey", required: false }] }] } });
380
-
381
- const rovingFocusImports = [RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective];
382
-
383
- /**
384
- * Generated bundle index. Do not edit.
385
- */
386
-
387
- export { RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective, focusFirst, injectRovingFocusGroupContext, provideRovingFocusGroupContext, rovingFocusImports };
388
- //# sourceMappingURL=radix-ng-primitives-roving-focus.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"radix-ng-primitives-roving-focus.mjs","sources":["../../../packages/primitives/roving-focus/src/utils.ts","../../../packages/primitives/roving-focus/src/roving-focus-group.directive.ts","../../../packages/primitives/roving-focus/src/roving-focus-item.directive.ts","../../../packages/primitives/roving-focus/index.ts","../../../packages/primitives/roving-focus/radix-ng-primitives-roving-focus.ts"],"sourcesContent":["export type Orientation = 'horizontal' | 'vertical';\nexport type Direction = 'ltr' | 'rtl';\n\nexport const ENTRY_FOCUS = 'rovingFocusGroup.onEntryFocus';\nexport const EVENT_OPTIONS = { bubbles: false, cancelable: true };\n\ntype FocusIntent = 'first' | 'last' | 'prev' | 'next';\n\nexport const MAP_KEY_TO_FOCUS_INTENT: Record<string, FocusIntent> = {\n ArrowLeft: 'prev',\n ArrowUp: 'prev',\n ArrowRight: 'next',\n ArrowDown: 'next',\n PageUp: 'first',\n Home: 'first',\n PageDown: 'last',\n End: 'last'\n};\n\nexport function getDirectionAwareKey(key: string, dir?: Direction) {\n if (dir !== 'rtl') return key;\n return key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;\n}\n\nexport function getFocusIntent(event: KeyboardEvent, orientation?: Orientation, dir?: Direction) {\n const key = getDirectionAwareKey(event.key, dir);\n if (orientation === 'vertical' && ['ArrowLeft', 'ArrowRight'].includes(key)) return undefined;\n if (orientation === 'horizontal' && ['ArrowUp', 'ArrowDown'].includes(key)) return undefined;\n return MAP_KEY_TO_FOCUS_INTENT[key];\n}\n\nexport function focusFirst(candidates: HTMLElement[], preventScroll = false, rootNode?: Document | ShadowRoot) {\n const PREVIOUSLY_FOCUSED_ELEMENT = rootNode?.activeElement ?? document.activeElement;\n for (const candidate of candidates) {\n // if focus is already where we want to go, we don't want to keep going through the candidates\n if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;\n candidate.focus({ preventScroll });\n if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;\n }\n}\n\n/**\n * Wraps an array around itself at a given start index\n * Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`\n */\nexport function wrapArray<T>(array: T[], startIndex: number) {\n return array.map((_, index) => array[(startIndex + index) % array.length]);\n}\n\n/**\n * Sorts elements by their position in the document, so the order matches what the user sees.\n */\nexport function sortByDocumentPosition(elements: HTMLElement[]): HTMLElement[] {\n return [...elements].sort((a, b) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));\n}\n\nlet idCounter = 0;\n\nexport function generateId(): string {\n return `rf-item-${++idCounter}`;\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n booleanAttribute,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n linkedSignal,\n model,\n output,\n PLATFORM_ID,\n signal\n} from '@angular/core';\nimport { BooleanInput, createContext } from '@radix-ng/primitives/core';\nimport { injectDirection } from '@radix-ng/primitives/direction-provider';\nimport { Direction, ENTRY_FOCUS, EVENT_OPTIONS, focusFirst, Orientation, sortByDocumentPosition } from './utils';\n\nconst rootContext = () => {\n const rovingFocusGroup = inject(RdxRovingFocusGroupDirective);\n return {\n loop: rovingFocusGroup.loop,\n dir: rovingFocusGroup.dir,\n orientation: rovingFocusGroup.orientation,\n currentTabStopId: rovingFocusGroup.currentTabStopId,\n focusableItems: rovingFocusGroup.focusableItems,\n onItemFocus: (tabStopId: string) => {\n rovingFocusGroup.currentTabStopId.set(tabStopId);\n },\n onItemShiftTab: () => {\n rovingFocusGroup.isTabbingBackOut.set(true);\n },\n registerItem: (item: HTMLElement, tabStopId: string) => rovingFocusGroup.registerItem(item, tabStopId),\n unregisterItem: (item: HTMLElement, tabStopId: string) => rovingFocusGroup.unregisterItem(item, tabStopId)\n };\n};\n\nexport type RovingFocusGroupContext = ReturnType<typeof rootContext>;\n\nexport const [injectRovingFocusGroupContext, provideRovingFocusGroupContext] = createContext<RovingFocusGroupContext>(\n 'RovingFocusGroupContext',\n 'utils/roving-focus'\n);\n\n/**\n * @group Components\n */\n@Directive({\n selector: '[rdxRovingFocusGroup]',\n providers: [provideRovingFocusGroupContext(rootContext)],\n host: {\n '[attr.data-orientation]': 'orientation()',\n '[attr.tabindex]': 'isTabbingBackOut() || focusableItems().length === 0 ? -1 : 0',\n '[attr.dir]': 'dir()',\n '(focus)': 'handleFocus($event)',\n '(focusout)': 'isTabbingBackOut.set(false)',\n '(mouseup)': 'handleMouseUp()',\n '(mousedown)': 'isClickFocus.set(true)'\n }\n})\nexport class RdxRovingFocusGroupDirective {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly elementRef = inject(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n /**\n * The orientation of the group. Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n */\n readonly orientationInput = input<Orientation>('horizontal', { alias: 'orientation' });\n\n /**\n * The direction of navigation between items.\n */\n readonly dirInput = input<Direction | undefined>(undefined, { alias: 'dir' });\n private readonly effectiveDir = injectDirection(this.dirInput);\n\n /**\n * Whether keyboard navigation should loop around\n */\n readonly loopInput = input<boolean, BooleanInput>(true, { transform: booleanAttribute, alias: 'loop' });\n\n /**\n * When `true`, will prevent scrolling to the focus item when focused.\n * @group Props\n */\n readonly preventScrollOnEntryFocus = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * The value of the current stop item.\n *\n * Use when you do not need to control the state of the stop item.\n * @group Props\n */\n readonly defaultCurrentTabStopId = input<string | undefined>(undefined);\n\n /**\n * The controlled value of the current stop item. Can be binded as `model`.\n * @group Props\n */\n readonly currentTabStopId = model<string | undefined>(undefined);\n\n /**\n * Event handler called when container is being focused. Can be prevented.\n * @group Emits\n */\n readonly entryFocus = output<Event>();\n\n private readonly _orientation = linkedSignal(() => this.orientationInput());\n readonly orientation = this._orientation.asReadonly();\n\n private readonly _dir = linkedSignal(() => this.effectiveDir());\n readonly dir = this._dir.asReadonly();\n\n private readonly _loop = linkedSignal(() => this.loopInput());\n readonly loop = this._loop.asReadonly();\n\n readonly focusableItems = signal<HTMLElement[]>([]);\n protected readonly isClickFocus = signal(false);\n readonly isTabbingBackOut = signal(false);\n private readonly itemIds = new WeakMap<HTMLElement, string>();\n private isDestroyed = false;\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n this.isDestroyed = true;\n });\n\n effect(() => {\n if (this.currentTabStopId() === undefined) {\n const def = this.defaultCurrentTabStopId();\n if (def !== undefined) {\n this.currentTabStopId.set(def);\n }\n }\n });\n }\n\n setOrientation(value: Orientation) {\n this._orientation.set(value);\n }\n\n setDir(value: Direction) {\n this._dir.set(value);\n }\n\n setLoop(value: boolean) {\n this._loop.set(value);\n }\n\n /** @ignore */\n registerItem(item: HTMLElement, tabStopId: string) {\n this.itemIds.set(item, tabStopId);\n // Keep the registry in DOM order, so arrow navigation matches the visual order\n // regardless of the order in which items are created/registered.\n this.focusableItems.update((items) => sortByDocumentPosition([...items, item]));\n }\n\n /** @ignore */\n unregisterItem(item: HTMLElement, tabStopId: string) {\n const remainingItems = this.focusableItems().filter((el) => el !== item);\n\n this.focusableItems.set(remainingItems);\n this.itemIds.delete(item);\n\n if (!this.isDestroyed && this.currentTabStopId() === tabStopId) {\n this.currentTabStopId.set(this.itemIds.get(remainingItems[0]));\n }\n }\n\n /** @ignore */\n handleMouseUp() {\n if (!this.isBrowser) return;\n\n // reset `isClickFocus` after 1 tick because handleFocus might not triggered due to focused element\n requestAnimationFrame(() => {\n this.isClickFocus.set(false);\n });\n }\n\n /** @ignore */\n handleFocus(event: Event) {\n // We normally wouldn't need this check, because we already check\n // that the focus is on the current target and not bubbling to it.\n // We do this because Safari doesn't focus buttons when clicked, and\n // instead, the wrapper will get focused and not through a bubbling event.\n const isKeyboardFocus = !this.isClickFocus();\n\n if (\n event.currentTarget === this.elementRef.nativeElement &&\n event.target === event.currentTarget &&\n isKeyboardFocus &&\n !this.isTabbingBackOut()\n ) {\n const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);\n this.elementRef.nativeElement.dispatchEvent(entryFocusEvent);\n this.entryFocus.emit(entryFocusEvent);\n\n if (!entryFocusEvent.defaultPrevented) {\n const items = this.focusableItems().filter((item) => item.dataset['disabled'] !== '');\n const activeItem = items.find((item) => item.getAttribute('data-active') === 'true');\n // The current tab stop is the only item with `tabindex=\"0\"` (driven by\n // `currentTabStopId`). We match on it instead of the DOM `id`, because consumers\n // (tabs, navigation-menu) own the element `id` and it may not equal the internal id.\n const currentItem = items.find((item) => item.getAttribute('tabindex') === '0');\n\n const candidateItems = [activeItem, currentItem, ...items].filter(Boolean) as typeof items;\n\n focusFirst(candidateItems, this.preventScrollOnEntryFocus());\n }\n }\n\n this.isClickFocus.set(false);\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n linkedSignal,\n PLATFORM_ID,\n untracked\n} from '@angular/core';\nimport { BooleanInput } from '@radix-ng/primitives/core';\nimport { injectRovingFocusGroupContext } from './roving-focus-group.directive';\nimport { focusFirst, generateId, getFocusIntent, wrapArray } from './utils';\n\n/**\n * @group Components\n */\n@Directive({\n selector: '[rdxRovingFocusItem]',\n host: {\n '[attr.tabindex]': 'tabindex()',\n '[attr.data-orientation]': 'rootContext?.orientation()',\n '[attr.data-active]': 'active() ? \"true\" : undefined',\n '[attr.data-disabled]': '!focusable() ? \"\" : undefined',\n '(mousedown)': 'handleMouseDown($event)',\n '(keydown)': 'handleKeydown($event)',\n '(focus)': 'onFocus()'\n }\n})\nexport class RdxRovingFocusItemDirective {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly elementRef = inject(ElementRef);\n\n /**\n * The enclosing roving-focus group. Optional: when the item is used outside a group\n * (e.g. a standalone Toggle), it degrades to a plain element and does not manage focus.\n */\n protected readonly rootContext = injectRovingFocusGroupContext(true);\n\n /**\n * When false, item will not be focusable.\n * @group Props\n */\n readonly focusableInput = input<boolean, BooleanInput>(true, { transform: booleanAttribute, alias: 'focusable' });\n\n /**\n * When `true`, marks the item as the active one, so it is preferred when focus enters the group.\n * @group Props\n */\n readonly activeInput = input<boolean, BooleanInput>(false, { transform: booleanAttribute, alias: 'active' });\n\n /**\n * @group Props\n */\n readonly tabStopIdInput = input<string>(undefined, { alias: 'tabStopId' });\n\n /**\n * When true, shift + arrow key will allow focusing on next/previous item.\n * @group Props\n */\n readonly allowShiftKey = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n // Stable fallback id, generated once so it never changes across recomputations of `id`.\n private readonly generatedId = generateId();\n protected readonly id = computed(() => this.tabStopId() || this.generatedId);\n protected readonly isCurrentTabStop = computed(() => this.rootContext?.currentTabStopId() === this.id());\n\n protected readonly focusable = linkedSignal(() => this.focusableInput());\n protected readonly active = linkedSignal(() => this.activeInput());\n private readonly tabStopId = linkedSignal(() => this.tabStopIdInput());\n\n /**\n * The roving tabindex. Without a group the item keeps its natural tab order (`null`); inside a\n * group exactly one focusable item is a tab stop (`0`), the rest are reachable only via arrows (`-1`).\n */\n protected readonly tabindex = computed(() => {\n if (!this.rootContext) {\n return null;\n }\n return this.focusable() && this.isCurrentTabStop() ? 0 : -1;\n });\n\n constructor() {\n // Keep the group's registry in sync with `focusable`, which can change after creation\n // (e.g. toolbar/navigation-menu toggle it via `setFocusable`). The cleanup also runs on\n // destroy, so a single effect covers register/unregister for the whole lifecycle.\n effect((onCleanup) => {\n const rootContext = this.rootContext;\n if (!rootContext || !this.focusable()) return;\n\n const element = this.elementRef.nativeElement;\n // `registerItem` reads and writes the group's `focusableItems` signal; calling it\n // untracked prevents the effect from depending on its own write and looping.\n const tabStopId = this.id();\n untracked(() => rootContext.registerItem(element, tabStopId));\n\n onCleanup(() => rootContext.unregisterItem(element, tabStopId));\n });\n }\n\n setFocusable(value: boolean) {\n this.focusable.set(value);\n }\n\n setActive(value: boolean) {\n this.active.set(value);\n }\n\n setTabStopId(value: string) {\n this.tabStopId.set(value);\n }\n\n /** @ignore */\n onFocus() {\n this.rootContext?.onItemFocus(this.id());\n }\n\n /** @ignore */\n handleMouseDown(event: Event) {\n if (!this.focusable()) {\n // We prevent focusing non-focusable items on `mousedown`.\n // Even though the item has tabIndex={-1}, that only means take it out of the tab order.\n event.preventDefault();\n } else {\n // Safari doesn't focus a button when clicked so we run our logic on mousedown also\n this.rootContext?.onItemFocus(this.id());\n }\n }\n\n /**\n * Handles the `keydown` event for keyboard navigation within the roving focus group.\n * Supports navigation based on orientation and direction, and focuses appropriate elements.\n *\n * @param event The `KeyboardEvent` object.\n * @ignore\n */\n handleKeydown(event: Event) {\n const rootContext = this.rootContext;\n if (!rootContext) return;\n\n const keyEvent = event as KeyboardEvent;\n if (keyEvent.key === 'Tab' && keyEvent.shiftKey) {\n rootContext.onItemShiftTab();\n return;\n }\n\n if (event.target !== this.elementRef.nativeElement) return;\n\n const focusIntent = getFocusIntent(keyEvent, rootContext.orientation(), rootContext.dir());\n\n if (focusIntent !== undefined) {\n if (\n keyEvent.metaKey ||\n keyEvent.ctrlKey ||\n keyEvent.altKey ||\n (this.allowShiftKey() ? false : keyEvent.shiftKey)\n ) {\n return;\n }\n\n event.preventDefault();\n\n let candidateNodes = rootContext.focusableItems().filter((item) => item.dataset['disabled'] !== '');\n\n if (focusIntent === 'last') {\n candidateNodes.reverse();\n } else if (focusIntent === 'prev' || focusIntent === 'next') {\n if (focusIntent === 'prev') candidateNodes.reverse();\n const currentIndex = candidateNodes.indexOf(this.elementRef.nativeElement);\n\n candidateNodes = rootContext.loop()\n ? wrapArray(candidateNodes, currentIndex + 1)\n : candidateNodes.slice(currentIndex + 1);\n }\n\n queueMicrotask(() => {\n if (this.isBrowser) {\n const rootNode = this.elementRef.nativeElement.getRootNode() as Document | ShadowRoot;\n focusFirst(candidateNodes, false, rootNode);\n }\n });\n }\n }\n}\n","import { RdxRovingFocusGroupDirective } from './src/roving-focus-group.directive';\nimport { RdxRovingFocusItemDirective } from './src/roving-focus-item.directive';\n\nexport * from './src/roving-focus-group.directive';\nexport * from './src/roving-focus-item.directive';\n\nexport { focusFirst } from './src/utils';\nexport type { Direction, Orientation } from './src/utils';\n\nexport const rovingFocusImports = [RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective];\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- # @radix-ng/primitives/roving-focus
2
-
3
- Secondary entry point of `@radix-ng/primitives`.
@@ -1,44 +0,0 @@
1
- import * as _angular_core from '@angular/core';
2
-
3
- /**
4
- * Marks an element as a member of a collection. Items are discovered by the
5
- * {@link RdxCollectionProvider} via `contentChildren`, so registration is automatic — no manual
6
- * book-keeping or marker attributes are needed.
7
- *
8
- * @group Components
9
- */
10
- declare class RdxCollectionItem<T = unknown> {
11
- /** The host element of the item, read straight off the instance. */
12
- readonly element: HTMLElement;
13
- /** Arbitrary data associated with the item. */
14
- readonly value: _angular_core.InputSignal<T | undefined>;
15
- /** Whether the item is disabled. Disabled items are excluded from {@link RdxCollectionProvider.enabledItems}. */
16
- readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
17
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCollectionItem<any>, never>;
18
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCollectionItem<any>, "[rdxCollectionItem]", ["rdxCollectionItem"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
19
- }
20
-
21
- /**
22
- * Collects {@link RdxCollectionItem} descendants in DOM order, reactively, using Angular's
23
- * `contentChildren`. Matches host directives too, so items composed via `hostDirectives` are found.
24
- *
25
- * @group Components
26
- */
27
- declare class RdxCollectionProvider {
28
- /** All items, in DOM order. */
29
- readonly items: _angular_core.Signal<readonly RdxCollectionItem<any>[]>;
30
- /** Items that are not disabled. Recomputes when an item's `disabled` flag changes. */
31
- readonly enabledItems: _angular_core.Signal<RdxCollectionItem<any>[]>;
32
- /** Returns the collection items, excluding disabled ones unless `includeDisabled` is `true`. */
33
- getItems(includeDisabled?: boolean): readonly RdxCollectionItem[];
34
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCollectionProvider, never>;
35
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCollectionProvider, "[rdxCollectionProvider]", ["rdxCollectionProvider"], {}, {}, ["items"], never, true, never>;
36
- }
37
-
38
- /**
39
- * Convenience accessor for the nearest {@link RdxCollectionProvider}. Equivalent to
40
- * `inject(RdxCollectionProvider)`; returns the provider with its reactive `items`/`enabledItems`.
41
- */
42
- declare function useCollection(): RdxCollectionProvider;
43
-
44
- export { RdxCollectionItem, RdxCollectionProvider, useCollection };