@radix-ng/primitives 1.0.1 → 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 (37) hide show
  1. package/composite/README.md +1 -1
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +10 -10
  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 +127 -43
  7. package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-menu.mjs +288 -63
  9. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-menubar.mjs +24 -1
  11. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-select.mjs +56 -29
  13. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  14. package/fesm2022/radix-ng-primitives-slider.mjs +57 -13
  15. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-tabs.mjs +292 -59
  17. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-toolbar.mjs +19 -13
  19. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  20. package/package.json +2 -10
  21. package/types/radix-ng-primitives-accordion.d.ts +4 -4
  22. package/types/radix-ng-primitives-checkbox.d.ts +98 -70
  23. package/types/radix-ng-primitives-composite.d.ts +58 -15
  24. package/types/radix-ng-primitives-menu.d.ts +44 -16
  25. package/types/radix-ng-primitives-menubar.d.ts +2 -0
  26. package/types/radix-ng-primitives-select.d.ts +46 -32
  27. package/types/radix-ng-primitives-slider.d.ts +19 -4
  28. package/types/radix-ng-primitives-tabs.d.ts +63 -11
  29. package/types/radix-ng-primitives-toolbar.d.ts +80 -73
  30. package/collection/README.md +0 -1
  31. package/fesm2022/radix-ng-primitives-collection.mjs +0 -72
  32. package/fesm2022/radix-ng-primitives-collection.mjs.map +0 -1
  33. package/fesm2022/radix-ng-primitives-roving-focus.mjs +0 -420
  34. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +0 -1
  35. package/roving-focus/README.md +0 -3
  36. package/types/radix-ng-primitives-collection.d.ts +0 -44
  37. package/types/radix-ng-primitives-roving-focus.d.ts +0 -201
@@ -1,420 +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
- enabled: rovingFocusGroup.enabled,
65
- loop: rovingFocusGroup.loop,
66
- dir: rovingFocusGroup.dir,
67
- orientation: rovingFocusGroup.orientation,
68
- currentTabStopId: rovingFocusGroup.currentTabStopId,
69
- focusableItems: rovingFocusGroup.focusableItems,
70
- onItemFocus: (tabStopId) => {
71
- rovingFocusGroup.currentTabStopId.set(tabStopId);
72
- },
73
- onItemShiftTab: () => {
74
- rovingFocusGroup.isTabbingBackOut.set(true);
75
- },
76
- registerItem: (item, tabStopId) => rovingFocusGroup.registerItem(item, tabStopId),
77
- unregisterItem: (item, tabStopId) => rovingFocusGroup.unregisterItem(item, tabStopId)
78
- };
79
- };
80
- const [injectRovingFocusGroupContext, provideRovingFocusGroupContext] = createContext('RovingFocusGroupContext', 'utils/roving-focus');
81
- /**
82
- * @group Components
83
- */
84
- class RdxRovingFocusGroupDirective {
85
- constructor() {
86
- this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
87
- this.elementRef = inject(ElementRef);
88
- this.destroyRef = inject(DestroyRef);
89
- /**
90
- * The orientation of the group. Mainly so arrow navigation is done accordingly (left & right vs. up & down)
91
- */
92
- this.orientationInput = input('horizontal', { ...(ngDevMode ? { debugName: "orientationInput" } : /* istanbul ignore next */ {}), alias: 'orientation' });
93
- /**
94
- * The direction of navigation between items.
95
- */
96
- this.dirInput = input(undefined, { ...(ngDevMode ? { debugName: "dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
97
- this.effectiveDir = injectDirection(this.dirInput);
98
- /**
99
- * Whether keyboard navigation should loop around
100
- */
101
- this.loopInput = input(true, { ...(ngDevMode ? { debugName: "loopInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'loop' });
102
- /**
103
- * Whether roving focus behavior is active for the group.
104
- * @group Props
105
- */
106
- this.enabledInput = input(true, { ...(ngDevMode ? { debugName: "enabledInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'enabled' });
107
- /**
108
- * When `true`, will prevent scrolling to the focus item when focused.
109
- * @group Props
110
- */
111
- this.preventScrollOnEntryFocus = input(false, { ...(ngDevMode ? { debugName: "preventScrollOnEntryFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
112
- /**
113
- * The value of the current stop item.
114
- *
115
- * Use when you do not need to control the state of the stop item.
116
- * @group Props
117
- */
118
- this.defaultCurrentTabStopId = input(undefined, ...(ngDevMode ? [{ debugName: "defaultCurrentTabStopId" }] : /* istanbul ignore next */ []));
119
- /**
120
- * The controlled value of the current stop item. Can be binded as `model`.
121
- * @group Props
122
- */
123
- this.currentTabStopId = model(undefined, ...(ngDevMode ? [{ debugName: "currentTabStopId" }] : /* istanbul ignore next */ []));
124
- /**
125
- * Event handler called when container is being focused. Can be prevented.
126
- * @group Emits
127
- */
128
- this.entryFocus = output();
129
- this._orientation = linkedSignal(() => this.orientationInput(), ...(ngDevMode ? [{ debugName: "_orientation" }] : /* istanbul ignore next */ []));
130
- this.orientation = this._orientation.asReadonly();
131
- this._dir = linkedSignal(() => this.effectiveDir(), ...(ngDevMode ? [{ debugName: "_dir" }] : /* istanbul ignore next */ []));
132
- this.dir = this._dir.asReadonly();
133
- this._loop = linkedSignal(() => this.loopInput(), ...(ngDevMode ? [{ debugName: "_loop" }] : /* istanbul ignore next */ []));
134
- this.loop = this._loop.asReadonly();
135
- this._enabled = linkedSignal(() => this.enabledInput(), ...(ngDevMode ? [{ debugName: "_enabled" }] : /* istanbul ignore next */ []));
136
- this.enabled = this._enabled.asReadonly();
137
- this.focusableItems = signal([], ...(ngDevMode ? [{ debugName: "focusableItems" }] : /* istanbul ignore next */ []));
138
- this.isClickFocus = signal(false, ...(ngDevMode ? [{ debugName: "isClickFocus" }] : /* istanbul ignore next */ []));
139
- this.isTabbingBackOut = signal(false, ...(ngDevMode ? [{ debugName: "isTabbingBackOut" }] : /* istanbul ignore next */ []));
140
- this.itemIds = new WeakMap();
141
- this.isDestroyed = false;
142
- this.destroyRef.onDestroy(() => {
143
- this.isDestroyed = true;
144
- });
145
- effect(() => {
146
- if (this.currentTabStopId() === undefined) {
147
- const def = this.defaultCurrentTabStopId();
148
- if (def !== undefined) {
149
- this.currentTabStopId.set(def);
150
- }
151
- }
152
- });
153
- }
154
- setOrientation(value) {
155
- this._orientation.set(value);
156
- }
157
- setDir(value) {
158
- this._dir.set(value);
159
- }
160
- setLoop(value) {
161
- this._loop.set(value);
162
- }
163
- setEnabled(value) {
164
- this._enabled.set(value);
165
- }
166
- /** @ignore */
167
- registerItem(item, tabStopId) {
168
- this.itemIds.set(item, tabStopId);
169
- // Keep the registry in DOM order, so arrow navigation matches the visual order
170
- // regardless of the order in which items are created/registered.
171
- this.focusableItems.update((items) => sortByDocumentPosition([...items, item]));
172
- }
173
- /** @ignore */
174
- unregisterItem(item, tabStopId) {
175
- const remainingItems = this.focusableItems().filter((el) => el !== item);
176
- this.focusableItems.set(remainingItems);
177
- this.itemIds.delete(item);
178
- if (!this.isDestroyed && this.currentTabStopId() === tabStopId) {
179
- this.currentTabStopId.set(this.itemIds.get(remainingItems[0]));
180
- }
181
- }
182
- /** @ignore */
183
- handleMouseUp() {
184
- if (!this.isBrowser)
185
- return;
186
- // reset `isClickFocus` after 1 tick because handleFocus might not triggered due to focused element
187
- requestAnimationFrame(() => {
188
- this.isClickFocus.set(false);
189
- });
190
- }
191
- /** @ignore */
192
- handleFocus(event) {
193
- // We normally wouldn't need this check, because we already check
194
- // that the focus is on the current target and not bubbling to it.
195
- // We do this because Safari doesn't focus buttons when clicked, and
196
- // instead, the wrapper will get focused and not through a bubbling event.
197
- const isKeyboardFocus = !this.isClickFocus();
198
- if (this.enabled() &&
199
- event.currentTarget === this.elementRef.nativeElement &&
200
- event.target === event.currentTarget &&
201
- isKeyboardFocus &&
202
- !this.isTabbingBackOut()) {
203
- const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
204
- this.elementRef.nativeElement.dispatchEvent(entryFocusEvent);
205
- this.entryFocus.emit(entryFocusEvent);
206
- if (!entryFocusEvent.defaultPrevented) {
207
- const items = this.focusableItems().filter((item) => item.dataset['disabled'] !== '');
208
- const activeItem = items.find((item) => item.getAttribute('data-active') === 'true');
209
- // The current tab stop is the only item with `tabindex="0"` (driven by
210
- // `currentTabStopId`). We match on it instead of the DOM `id`, because consumers
211
- // (tabs, navigation-menu) own the element `id` and it may not equal the internal id.
212
- const currentItem = items.find((item) => item.getAttribute('tabindex') === '0');
213
- const candidateItems = [activeItem, currentItem, ...items].filter(Boolean);
214
- focusFirst(candidateItems, this.preventScrollOnEntryFocus());
215
- }
216
- }
217
- this.isClickFocus.set(false);
218
- }
219
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
220
- 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 }, enabledInput: { classPropertyName: "enabledInput", publicName: "enabled", 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": "enabled() ? (isTabbingBackOut() || focusableItems().length === 0 ? -1 : 0) : null", "attr.dir": "dir()" } }, providers: [provideRovingFocusGroupContext(rootContext)], ngImport: i0 }); }
221
- }
222
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusGroupDirective, decorators: [{
223
- type: Directive,
224
- args: [{
225
- selector: '[rdxRovingFocusGroup]',
226
- providers: [provideRovingFocusGroupContext(rootContext)],
227
- host: {
228
- '[attr.data-orientation]': 'orientation()',
229
- '[attr.tabindex]': 'enabled() ? (isTabbingBackOut() || focusableItems().length === 0 ? -1 : 0) : null',
230
- '[attr.dir]': 'dir()',
231
- '(focus)': 'handleFocus($event)',
232
- '(focusout)': 'isTabbingBackOut.set(false)',
233
- '(mouseup)': 'handleMouseUp()',
234
- '(mousedown)': 'isClickFocus.set(true)'
235
- }
236
- }]
237
- }], 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 }] }], enabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "enabled", 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"] }] } });
238
-
239
- /**
240
- * @group Components
241
- */
242
- class RdxRovingFocusItemDirective {
243
- constructor() {
244
- this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
245
- this.elementRef = inject(ElementRef);
246
- /**
247
- * The enclosing roving-focus group. Optional: when the item is used outside a group
248
- * (e.g. a standalone Toggle), it degrades to a plain element and does not manage focus.
249
- */
250
- this.rootContext = injectRovingFocusGroupContext(true);
251
- /**
252
- * When false, item will not be focusable.
253
- * @group Props
254
- */
255
- this.focusableInput = input(true, { ...(ngDevMode ? { debugName: "focusableInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'focusable' });
256
- /**
257
- * When `true`, marks the item as the active one, so it is preferred when focus enters the group.
258
- * @group Props
259
- */
260
- this.activeInput = input(false, { ...(ngDevMode ? { debugName: "activeInput" } : /* istanbul ignore next */ {}), transform: booleanAttribute, alias: 'active' });
261
- /**
262
- * @group Props
263
- */
264
- this.tabStopIdInput = input(undefined, { ...(ngDevMode ? { debugName: "tabStopIdInput" } : /* istanbul ignore next */ {}), alias: 'tabStopId' });
265
- /**
266
- * When true, shift + arrow key will allow focusing on next/previous item.
267
- * @group Props
268
- */
269
- this.allowShiftKey = input(false, { ...(ngDevMode ? { debugName: "allowShiftKey" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
270
- // Stable fallback id, generated once so it never changes across recomputations of `id`.
271
- this.generatedId = generateId();
272
- this.id = computed(() => this.tabStopId() || this.generatedId, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
273
- this.isCurrentTabStop = computed(() => this.rootContext?.currentTabStopId() === this.id(), ...(ngDevMode ? [{ debugName: "isCurrentTabStop" }] : /* istanbul ignore next */ []));
274
- this.focusable = linkedSignal(() => this.focusableInput(), ...(ngDevMode ? [{ debugName: "focusable" }] : /* istanbul ignore next */ []));
275
- this.active = linkedSignal(() => this.activeInput(), ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
276
- this.enabled = signal(true, ...(ngDevMode ? [{ debugName: "enabled" }] : /* istanbul ignore next */ []));
277
- this.tabStopId = linkedSignal(() => this.tabStopIdInput(), ...(ngDevMode ? [{ debugName: "tabStopId" }] : /* istanbul ignore next */ []));
278
- /**
279
- * The roving tabindex. Without a group the item keeps its natural tab order (`null`); inside a
280
- * group exactly one focusable item is a tab stop (`0`), the rest are reachable only via arrows (`-1`).
281
- */
282
- this.tabindex = computed(() => {
283
- if (!this.rootContext) {
284
- return null;
285
- }
286
- if (!this.enabled()) {
287
- return null;
288
- }
289
- if (!this.rootContext.enabled()) {
290
- return null;
291
- }
292
- return this.focusable() && this.isCurrentTabStop() ? 0 : -1;
293
- }, ...(ngDevMode ? [{ debugName: "tabindex" }] : /* istanbul ignore next */ []));
294
- // Keep the group's registry in sync with `focusable`, which can change after creation
295
- // (e.g. toolbar/navigation-menu toggle it via `setFocusable`). The cleanup also runs on
296
- // destroy, so a single effect covers register/unregister for the whole lifecycle.
297
- effect((onCleanup) => {
298
- const rootContext = this.rootContext;
299
- if (!rootContext || !this.enabled() || !this.focusable())
300
- return;
301
- const element = this.elementRef.nativeElement;
302
- // `registerItem` reads and writes the group's `focusableItems` signal; calling it
303
- // untracked prevents the effect from depending on its own write and looping.
304
- const tabStopId = this.id();
305
- untracked(() => rootContext.registerItem(element, tabStopId));
306
- onCleanup(() => rootContext.unregisterItem(element, tabStopId));
307
- });
308
- }
309
- setFocusable(value) {
310
- this.focusable.set(value);
311
- }
312
- setEnabled(value) {
313
- this.enabled.set(value);
314
- }
315
- setActive(value) {
316
- this.active.set(value);
317
- }
318
- setTabStopId(value) {
319
- this.tabStopId.set(value);
320
- }
321
- /** @ignore */
322
- onFocus() {
323
- if (!this.enabled()) {
324
- return;
325
- }
326
- this.rootContext?.onItemFocus(this.id());
327
- }
328
- /** @ignore */
329
- handleMouseDown(event) {
330
- if (!this.enabled()) {
331
- return;
332
- }
333
- if (!this.focusable()) {
334
- // We prevent focusing non-focusable items on `mousedown`.
335
- // Even though the item has tabIndex={-1}, that only means take it out of the tab order.
336
- event.preventDefault();
337
- }
338
- else {
339
- // Safari doesn't focus a button when clicked so we run our logic on mousedown also
340
- this.rootContext?.onItemFocus(this.id());
341
- }
342
- }
343
- /**
344
- * Handles the `keydown` event for keyboard navigation within the roving focus group.
345
- * Supports navigation based on orientation and direction, and focuses appropriate elements.
346
- *
347
- * @param event The `KeyboardEvent` object.
348
- * @ignore
349
- */
350
- handleKeydown(event) {
351
- const rootContext = this.rootContext;
352
- if (!rootContext)
353
- return;
354
- if (!this.enabled())
355
- return;
356
- if (!rootContext.enabled())
357
- return;
358
- const keyEvent = event;
359
- if (keyEvent.key === 'Tab' && keyEvent.shiftKey) {
360
- rootContext.onItemShiftTab();
361
- return;
362
- }
363
- if (event.target !== this.elementRef.nativeElement)
364
- return;
365
- const focusIntent = getFocusIntent(keyEvent, rootContext.orientation(), rootContext.dir());
366
- if (focusIntent !== undefined) {
367
- if (keyEvent.metaKey ||
368
- keyEvent.ctrlKey ||
369
- keyEvent.altKey ||
370
- (this.allowShiftKey() ? false : keyEvent.shiftKey)) {
371
- return;
372
- }
373
- event.preventDefault();
374
- let candidateNodes = rootContext.focusableItems().filter((item) => item.dataset['disabled'] !== '');
375
- if (focusIntent === 'last') {
376
- candidateNodes.reverse();
377
- }
378
- else if (focusIntent === 'prev' || focusIntent === 'next') {
379
- if (focusIntent === 'prev')
380
- candidateNodes.reverse();
381
- const currentIndex = candidateNodes.indexOf(this.elementRef.nativeElement);
382
- candidateNodes = rootContext.loop()
383
- ? wrapArray(candidateNodes, currentIndex + 1)
384
- : candidateNodes.slice(currentIndex + 1);
385
- }
386
- queueMicrotask(() => {
387
- if (this.isBrowser) {
388
- const rootNode = this.elementRef.nativeElement.getRootNode();
389
- focusFirst(candidateNodes, false, rootNode);
390
- }
391
- });
392
- }
393
- }
394
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
395
- 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": "enabled() ? rootContext?.orientation() : undefined", "attr.data-active": "active() ? \"true\" : undefined", "attr.data-disabled": "enabled() && !focusable() ? \"\" : undefined" } }, ngImport: i0 }); }
396
- }
397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxRovingFocusItemDirective, decorators: [{
398
- type: Directive,
399
- args: [{
400
- selector: '[rdxRovingFocusItem]',
401
- host: {
402
- '[attr.tabindex]': 'tabindex()',
403
- '[attr.data-orientation]': 'enabled() ? rootContext?.orientation() : undefined',
404
- '[attr.data-active]': 'active() ? "true" : undefined',
405
- '[attr.data-disabled]': 'enabled() && !focusable() ? "" : undefined',
406
- '(mousedown)': 'handleMouseDown($event)',
407
- '(keydown)': 'handleKeydown($event)',
408
- '(focus)': 'onFocus()'
409
- }
410
- }]
411
- }], 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 }] }] } });
412
-
413
- const rovingFocusImports = [RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective];
414
-
415
- /**
416
- * Generated bundle index. Do not edit.
417
- */
418
-
419
- export { RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective, focusFirst, injectRovingFocusGroupContext, provideRovingFocusGroupContext, rovingFocusImports };
420
- //# 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 enabled: rovingFocusGroup.enabled,\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]': 'enabled() ? (isTabbingBackOut() || focusableItems().length === 0 ? -1 : 0) : null',\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 * Whether roving focus behavior is active for the group.\n * @group Props\n */\n readonly enabledInput = input<boolean, BooleanInput>(true, { transform: booleanAttribute, alias: 'enabled' });\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 private readonly _enabled = linkedSignal(() => this.enabledInput());\n readonly enabled = this._enabled.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 setEnabled(value: boolean) {\n this._enabled.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 this.enabled() &&\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 signal,\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]': 'enabled() ? rootContext?.orientation() : undefined',\n '[attr.data-active]': 'active() ? \"true\" : undefined',\n '[attr.data-disabled]': 'enabled() && !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 protected readonly enabled = signal(true);\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 if (!this.enabled()) {\n return null;\n }\n if (!this.rootContext.enabled()) {\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.enabled() || !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 setEnabled(value: boolean) {\n this.enabled.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 if (!this.enabled()) {\n return;\n }\n\n this.rootContext?.onItemFocus(this.id());\n }\n\n /** @ignore */\n handleMouseDown(event: Event) {\n if (!this.enabled()) {\n return;\n }\n\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 if (!this.enabled()) return;\n if (!rootContext.enabled()) 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 };