@lumx/core 4.8.1 → 4.9.0-alpha.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.
@@ -0,0 +1,26 @@
1
+ import type { FocusNavigationCallbacks } from './types';
2
+ /**
3
+ * Internal state for tracking the active (focused) item.
4
+ * Shared by both list and grid navigation implementations.
5
+ */
6
+ export interface ActiveItemState {
7
+ /** Get the currently active item. */
8
+ readonly active: HTMLElement | null;
9
+ /** Set the active item (handles deactivate/activate callbacks). */
10
+ setActive(item: HTMLElement | null): void;
11
+ /** Clear the active item (deactivate + clear callbacks). */
12
+ clear(): void;
13
+ }
14
+ /**
15
+ * Create shared active item state with cleanup on abort.
16
+ *
17
+ * Callback invocation:
18
+ * - `setActive(item)`: calls `onDeactivate(previous)` then `onActivate(item)`.
19
+ * - `clear()`: calls `onDeactivate(current)` then `onClear()`.
20
+ * - On `signal.abort()`: same as `clear()`.
21
+ *
22
+ * @param callbacks Focus state change callbacks.
23
+ * @param signal AbortSignal for cleanup.
24
+ * @param initialItem Optional item to silently pre-select on creation (no callbacks fired).
25
+ */
26
+ export declare function createActiveItemState(callbacks: FocusNavigationCallbacks, signal: AbortSignal, initialItem?: HTMLElement | null): ActiveItemState;
@@ -0,0 +1,10 @@
1
+ import type { FocusNavigationCallbacks, FocusNavigationController, ListNavigationOptions } from './types';
2
+ /**
3
+ * Create a focus navigation controller for a 1D list.
4
+ *
5
+ * @param options List navigation options (container, itemSelector, direction, wrap).
6
+ * @param callbacks Callbacks for focus state changes.
7
+ * @param signal AbortSignal for cleanup.
8
+ * @returns FocusNavigationController instance.
9
+ */
10
+ export declare function createListFocusNavigation(options: ListNavigationOptions, callbacks: FocusNavigationCallbacks, signal: AbortSignal): FocusNavigationController;
@@ -0,0 +1,4 @@
1
+ export type { FocusNavigationCallbacks, FocusNavigationController, ListNavigationOptions } from './types';
2
+ export type { RovingTabIndexOptions } from './setupRovingTabIndex';
3
+ export { createListFocusNavigation } from './createListFocusNavigation';
4
+ export { setupRovingTabIndex } from './setupRovingTabIndex';
@@ -0,0 +1,42 @@
1
+ import type { FocusNavigationController } from './types';
2
+ /**
3
+ * Options for the roving tabindex setup.
4
+ */
5
+ export interface RovingTabIndexOptions {
6
+ /** The container element holding the focusable items. */
7
+ container: HTMLElement;
8
+ /** CSS selector to identify focusable items within the container. */
9
+ itemSelector: string;
10
+ /**
11
+ * Primary navigation axis — determines which arrow keys navigate.
12
+ * - `'horizontal'` (default): Left/Right navigate, Up/Down are no-ops.
13
+ * - `'vertical'`: Up/Down navigate, Left/Right are no-ops.
14
+ */
15
+ direction?: 'horizontal' | 'vertical';
16
+ /**
17
+ * CSS selector matching disabled items within the container.
18
+ * Disabled items are skipped during keyboard navigation.
19
+ */
20
+ itemDisabledSelector?: string;
21
+ /** Callback invoked when an item receives focus via keyboard navigation. */
22
+ onItemFocused?: (item: HTMLElement) => void;
23
+ }
24
+ /**
25
+ * Set up the roving tabindex pattern on a container element.
26
+ *
27
+ * Handles:
28
+ * - Keyboard navigation (Arrow keys, Home, End) via a keydown listener on the container
29
+ * - tabindex management on focus changes (`0` on active, `-1` on inactive)
30
+ * - Calling `.focus()` on the newly active item
31
+ *
32
+ * The consumer is responsible for setting the initial tabindex values on items
33
+ * (`tabindex="0"` on the active item, `tabindex="-1"` on the rest). On setup, the item
34
+ * with `tabindex="0"` is silently adopted as the initial active item.
35
+ *
36
+ * The setup is torn down when the provided `signal` is aborted.
37
+ *
38
+ * @param options Roving tabindex configuration.
39
+ * @param signal AbortSignal for teardown.
40
+ * @returns The underlying {@link FocusNavigationController} for programmatic access.
41
+ */
42
+ export declare function setupRovingTabIndex(options: RovingTabIndexOptions, signal: AbortSignal): FocusNavigationController;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Callbacks for focus state changes.
3
+ * The consumer decides how to manifest focus (roving tabindex, aria-activedescendant, etc.).
4
+ */
5
+ export interface FocusNavigationCallbacks {
6
+ /** Called when an item becomes the active (focused) item. */
7
+ onActivate(item: HTMLElement): void;
8
+ /** Called when an item is no longer the active item (being replaced or cleared). */
9
+ onDeactivate(item: HTMLElement): void;
10
+ /** Called when focus is completely cleared (no active item). */
11
+ onClear?(): void;
12
+ }
13
+ /** Options for 1D list navigation. */
14
+ export interface ListNavigationOptions {
15
+ type: 'list';
16
+ /** The container element to scan for items. */
17
+ container: HTMLElement;
18
+ /** CSS selector to identify navigable items within the container. */
19
+ itemSelector: string;
20
+ /**
21
+ * Primary navigation axis — determines which arrow keys navigate the list.
22
+ * - `'vertical'` (default): Up/Down navigate, Left/Right are no-ops.
23
+ * - `'horizontal'`: Left/Right navigate, Up/Down are no-ops.
24
+ */
25
+ direction?: 'vertical' | 'horizontal';
26
+ /** Whether navigation wraps at boundaries (last→first, first→last). Default: false. */
27
+ wrap?: boolean;
28
+ /**
29
+ * CSS selector matching disabled items within the container.
30
+ * Disabled items are skipped during navigation (goUp/goDown/goLeft/goRight/goToFirst/goToLast)
31
+ * but can still be navigated to directly via `goToItem`.
32
+ * Default: no items are disabled.
33
+ */
34
+ itemDisabledSelector?: string;
35
+ /**
36
+ * CSS selector identifying the initially active item within the container.
37
+ * If an item matching this selector is found on setup, it becomes the active item
38
+ * without triggering focus or activation callbacks (silent init from DOM state).
39
+ */
40
+ itemActiveSelector?: string;
41
+ }
42
+ /** Focus navigation controller interface for 1D lists. */
43
+ export interface FocusNavigationController {
44
+ /** The navigation structure type. */
45
+ readonly type: 'list';
46
+ /** The currently active item, or null if no item is active. */
47
+ readonly activeItem: HTMLElement | null;
48
+ /** Whether an item is currently active. */
49
+ readonly hasActiveItem: boolean;
50
+ /** Whether there are any navigable items in the container. */
51
+ readonly hasNavigableItems: boolean;
52
+ /** Navigate to the first navigable item. */
53
+ goToFirst(): boolean;
54
+ /** Navigate to the last navigable item. */
55
+ goToLast(): boolean;
56
+ /**
57
+ * Navigate to a specific item element.
58
+ * @returns true if navigation occurred (item is navigable).
59
+ */
60
+ goToItem(item: HTMLElement): boolean;
61
+ /**
62
+ * Navigate by offset from the current item.
63
+ * Positive offsets move forward, negative move backward.
64
+ */
65
+ goToOffset(offset: number): boolean;
66
+ /**
67
+ * Navigate to the first item matching a predicate.
68
+ * @returns true if a matching item was found and focused.
69
+ */
70
+ goToItemMatching(predicate: (item: HTMLElement) => boolean): boolean;
71
+ /** Clear the active item — no item is active after this call. */
72
+ clear(): void;
73
+ /** Navigate up (previous item in vertical list). */
74
+ goUp(): boolean;
75
+ /** Navigate down (next item in vertical list). */
76
+ goDown(): boolean;
77
+ /** Navigate left (previous item in horizontal list). */
78
+ goLeft(): boolean;
79
+ /** Navigate right (next item in horizontal list). */
80
+ goRight(): boolean;
81
+ }
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "dependencies": {
9
9
  "@floating-ui/dom": "^1.7.5",
10
- "@lumx/icons": "^4.8.1",
10
+ "@lumx/icons": "^4.9.0-alpha.0",
11
11
  "classnames": "^2.3.2",
12
12
  "focus-visible": "^5.0.2",
13
13
  "lodash": "4.17.23",
@@ -69,7 +69,7 @@
69
69
  "update-version-changelog": "yarn version-changelog ../../CHANGELOG.md"
70
70
  },
71
71
  "sideEffects": false,
72
- "version": "4.8.1",
72
+ "version": "4.9.0-alpha.0",
73
73
  "devDependencies": {
74
74
  "@rollup/plugin-typescript": "^12.3.0",
75
75
  "@testing-library/dom": "^10.4.1",
@@ -92,5 +92,6 @@
92
92
  "vite": "^7.3.1",
93
93
  "vite-tsconfig-paths": "^5.1.4",
94
94
  "vitest": "^4.0.18"
95
- }
95
+ },
96
+ "stableVersion": "4.8.1"
96
97
  }