@lumx/core 4.9.0-next.1 → 4.9.0-next.10
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.
- package/components-and-utils.css +36 -4
- package/js/components/Combobox/ComboboxButton.d.ts +54 -0
- package/js/components/Combobox/ComboboxInput.d.ts +49 -0
- package/js/components/Combobox/ComboboxList.d.ts +47 -0
- package/js/components/Combobox/ComboboxOption.d.ts +74 -0
- package/js/components/Combobox/ComboboxOptionAction.d.ts +35 -0
- package/js/components/Combobox/ComboboxOptionMoreInfo.d.ts +54 -0
- package/js/components/Combobox/ComboboxOptionSkeleton.d.ts +41 -0
- package/js/components/Combobox/ComboboxPopover.d.ts +50 -0
- package/js/components/Combobox/ComboboxSection.d.ts +58 -0
- package/js/components/Combobox/ComboboxState.d.ts +90 -0
- package/js/components/Combobox/index.d.ts +25 -0
- package/js/components/Combobox/setupCombobox.d.ts +24 -0
- package/js/components/Combobox/setupComboboxButton.d.ts +16 -0
- package/js/components/Combobox/setupComboboxInput.d.ts +28 -0
- package/js/components/Combobox/setupListbox.d.ts +21 -0
- package/js/components/Combobox/subscribeComboboxState.d.ts +23 -0
- package/js/components/Combobox/types.d.ts +124 -0
- package/js/components/Combobox/utils.d.ts +27 -0
- package/js/components/List/ListItem.d.ts +58 -0
- package/js/components/List/ListItemAction.d.ts +24 -0
- package/js/components/List/index.d.ts +39 -0
- package/js/components/Mosaic/Tests.d.ts +13 -0
- package/js/components/Tabs/TabList.d.ts +39 -0
- package/js/components/Tabs/TabListTests.d.ts +12 -0
- package/js/components/Tabs/TabPanelTests.d.ts +11 -0
- package/js/components/Tabs/TabProviderTestUtils.d.ts +17 -0
- package/js/components/Tabs/Tests.d.ts +11 -0
- package/js/components/Tabs/constants.d.ts +4 -0
- package/js/components/Tabs/state.d.ts +34 -0
- package/js/components/Text/index.d.ts +1 -1
- package/js/components/UserBlock/Tests.d.ts +13 -0
- package/js/types/jsx/PropsToOverride.d.ts +1 -1
- package/js/utils/browser/createSelectorTreeWalker.d.ts +13 -0
- package/js/utils/focusNavigation/createGridFocusNavigation.d.ts +13 -0
- package/js/utils/focusNavigation/index.d.ts +2 -1
- package/js/utils/focusNavigation/types.d.ts +28 -7
- package/js/utils/typeahead/index.d.ts +29 -0
- package/lumx.css +36 -4
- package/package.json +2 -2
- package/scss/_components_classes.scss +2 -1
- package/scss/components/combobox/_index.scss +44 -0
- package/scss/components/list/_mixins.scss +47 -33
- package/stories/types.d.ts +2 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ComboboxCallbacks, ComboboxHandle, OnTriggerAttach } from './types';
|
|
2
|
+
/** Options for configuring the shared combobox behavior. */
|
|
3
|
+
interface ComboboxOptions {
|
|
4
|
+
/** When true, ArrowDown/ArrowUp wrap around in listbox mode (input pattern). Default: false. */
|
|
5
|
+
wrapNavigation?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Set up combobox behavior (WAI-ARIA combobox pattern) on a trigger + listbox pair.
|
|
9
|
+
*
|
|
10
|
+
* The trigger and listbox are registered separately via the returned handle,
|
|
11
|
+
* allowing framework components to register them on mount. The behavior is
|
|
12
|
+
* fully attached once both are registered.
|
|
13
|
+
*
|
|
14
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
15
|
+
*
|
|
16
|
+
* @param callbacks Callbacks invoked on combobox events (e.g. option selection).
|
|
17
|
+
* @param options Options for configuring the shared combobox behavior.
|
|
18
|
+
* @param onTriggerAttach Optional callback invoked when the trigger is registered and the signal is ready.
|
|
19
|
+
* Used by mode-specific wrappers (setupComboboxInput/Button) to automatically
|
|
20
|
+
* attach the appropriate controller.
|
|
21
|
+
* @returns A ComboboxHandle for interacting with the combobox.
|
|
22
|
+
*/
|
|
23
|
+
export declare function setupCombobox(callbacks: ComboboxCallbacks, options?: ComboboxOptions, onTriggerAttach?: OnTriggerAttach): ComboboxHandle;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ComboboxCallbacks, ComboboxHandle } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Set up a combobox with a button trigger (select-only pattern).
|
|
4
|
+
*
|
|
5
|
+
* Creates a full combobox handle with the button-mode controller automatically
|
|
6
|
+
* wired in and the trigger registered. The consumer only needs to call
|
|
7
|
+
* `handle.registerListbox(listbox)`.
|
|
8
|
+
*
|
|
9
|
+
* Handles: Space (select/open), Home/End (listbox navigation),
|
|
10
|
+
* printable characters (typeahead), and click (toggle).
|
|
11
|
+
*
|
|
12
|
+
* @param button The button element to use as the combobox trigger.
|
|
13
|
+
* @param callbacks Callbacks for select and open/close events.
|
|
14
|
+
* @returns A ComboboxHandle for interacting with the combobox.
|
|
15
|
+
*/
|
|
16
|
+
export declare function setupComboboxButton(button: HTMLButtonElement, callbacks: ComboboxCallbacks): ComboboxHandle;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ComboboxCallbacks, ComboboxHandle } from './types';
|
|
2
|
+
/** Options for configuring the input-mode combobox controller. */
|
|
3
|
+
export interface SetupComboboxInputOptions extends ComboboxCallbacks {
|
|
4
|
+
/**
|
|
5
|
+
* When true (default), the combobox automatically filters options as the user types.
|
|
6
|
+
* Each registered `Combobox.Option` receives filter state updates and hides itself
|
|
7
|
+
* when it does not match the current input value.
|
|
8
|
+
*
|
|
9
|
+
* Set to false when you want to handle filtering yourself (e.g. async search,
|
|
10
|
+
* consumer-side pre-filtering). Options will not be registered for auto-filtering.
|
|
11
|
+
*/
|
|
12
|
+
autoFilter?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Set up a combobox with an input trigger (autocomplete/filter pattern).
|
|
16
|
+
*
|
|
17
|
+
* Creates a full combobox handle with the input-mode controller automatically
|
|
18
|
+
* wired in and the trigger registered. The consumer only needs to call
|
|
19
|
+
* `handle.registerListbox(listbox)`.
|
|
20
|
+
*
|
|
21
|
+
* Handles: Home/End (text cursor), ArrowLeft/Right (clear active descendant),
|
|
22
|
+
* filtering (on input and on open), and focus behavior.
|
|
23
|
+
*
|
|
24
|
+
* @param input The input element to use as the combobox trigger.
|
|
25
|
+
* @param options Options and callbacks for configuring the input-mode controller.
|
|
26
|
+
* @returns A ComboboxHandle for interacting with the combobox.
|
|
27
|
+
*/
|
|
28
|
+
export declare function setupComboboxInput(input: HTMLInputElement, options: SetupComboboxInputOptions): ComboboxHandle;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type FocusNavigationController } from '../../utils/focusNavigation';
|
|
2
|
+
import type { ComboboxEventMap, ComboboxHandle } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Set up focus navigation and delegated event listeners on a listbox element.
|
|
5
|
+
*
|
|
6
|
+
* This merges two concerns:
|
|
7
|
+
* 1. Creating the appropriate {@link FocusNavigationController} (grid or list mode)
|
|
8
|
+
* with callbacks that manage `aria-activedescendant` and visual focus indicators.
|
|
9
|
+
* 2. Attaching delegated `click` and `mousedown` listeners to the listbox for
|
|
10
|
+
* option selection and blur prevention.
|
|
11
|
+
*
|
|
12
|
+
* The caller is responsible for guarding against duplicate calls (i.e., checking
|
|
13
|
+
* that a focus navigation controller does not already exist before calling)
|
|
14
|
+
* and ensuring `handle.trigger` and `handle.listbox` are non-null.
|
|
15
|
+
*
|
|
16
|
+
* @param handle The combobox handle (provides trigger, listbox, select, etc.).
|
|
17
|
+
* @param signal Abort signal used to clean up all attached listeners.
|
|
18
|
+
* @param notify Notify subscribers of combobox events.
|
|
19
|
+
* @returns The created focus navigation controller.
|
|
20
|
+
*/
|
|
21
|
+
export declare function setupListbox(handle: ComboboxHandle, signal: AbortSignal, notify: <K extends keyof ComboboxEventMap>(event: K, value: ComboboxEventMap[K]) => void): FocusNavigationController;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ComboboxHandle } from './types';
|
|
2
|
+
/** Setters invoked by `subscribeComboboxState` when handle events fire. */
|
|
3
|
+
export interface ComboboxStateSetters {
|
|
4
|
+
/** Called immediately with the current loading state, then on every `loadingChange` event. */
|
|
5
|
+
setIsLoading: (value: boolean) => void;
|
|
6
|
+
/** Called on every `loadingAnnouncement` event (debounced 500ms after skeletons mount). */
|
|
7
|
+
setShouldAnnounce: (value: boolean) => void;
|
|
8
|
+
/** Called with `true` after a short delay when the combobox opens, and `false` immediately on close. */
|
|
9
|
+
setIsOpen: (value: boolean) => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Subscribe to the combobox handle events needed by `ComboboxState`.
|
|
13
|
+
*
|
|
14
|
+
* Manages three subscriptions:
|
|
15
|
+
* - `loadingChange` → `setIsLoading` (+ synchronous initial read of `handle.isLoading`)
|
|
16
|
+
* - `loadingAnnouncement` → `setShouldAnnounce`
|
|
17
|
+
* - `open` → `setIsOpen` (deferred by {@link OPEN_ANNOUNCEMENT_DELAY}ms on open, immediate on close)
|
|
18
|
+
*
|
|
19
|
+
* @param handle The combobox handle to subscribe to.
|
|
20
|
+
* @param setters Framework-specific state setters.
|
|
21
|
+
* @returns A cleanup function that unsubscribes all events and clears timers.
|
|
22
|
+
*/
|
|
23
|
+
export declare function subscribeComboboxState(handle: ComboboxHandle, setters: ComboboxStateSetters): () => void;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { FocusNavigationController } from '../../utils/focusNavigation';
|
|
2
|
+
/** Section visibility state tracked per registration. */
|
|
3
|
+
export interface SectionState {
|
|
4
|
+
hidden: boolean;
|
|
5
|
+
'aria-hidden': boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Registration entry for a section element. */
|
|
8
|
+
export interface SectionRegistration {
|
|
9
|
+
callback: (state: SectionState) => void;
|
|
10
|
+
last: SectionState;
|
|
11
|
+
}
|
|
12
|
+
/** Registration entry for an option element. */
|
|
13
|
+
export interface OptionRegistration {
|
|
14
|
+
callback: (isFiltered: boolean) => void;
|
|
15
|
+
lastFiltered: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** Map of combobox event names to their payload types. */
|
|
18
|
+
export interface ComboboxEventMap {
|
|
19
|
+
/** Fired when the combobox open state changes. Payload: whether the combobox is open. */
|
|
20
|
+
open: boolean;
|
|
21
|
+
/** Fired when the active descendant changes (visual focus). Payload: the option id or null. */
|
|
22
|
+
activeDescendantChange: string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Fired when the visible option count transitions between empty and non-empty.
|
|
25
|
+
* Payload: whether the list is empty plus the current input value.
|
|
26
|
+
*/
|
|
27
|
+
emptyChange: {
|
|
28
|
+
isEmpty?: boolean;
|
|
29
|
+
inputValue?: string;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Fired immediately when the aggregate loading state changes (skeleton count transitions
|
|
33
|
+
* between 0 and >0). Used for empty suppression in ComboboxState and for aria-busy on the listbox.
|
|
34
|
+
*/
|
|
35
|
+
loadingChange: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Fired after a 500ms debounce when loading persists, or immediately when loading ends.
|
|
38
|
+
* Used to control the loading message text in the live region (ComboboxState).
|
|
39
|
+
*/
|
|
40
|
+
loadingAnnouncement: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** Callbacks provided by the consumer (React/Vue) to react to combobox state changes. */
|
|
43
|
+
export interface ComboboxCallbacks {
|
|
44
|
+
/** Called when an option is selected (click or keyboard). Receives the combobox handle for post-selection side effects. */
|
|
45
|
+
onSelect(option: {
|
|
46
|
+
value: string;
|
|
47
|
+
}, handle: ComboboxHandle): void;
|
|
48
|
+
}
|
|
49
|
+
/** Handle returned by `setupCombobox`. Used by framework wrappers and mode controllers. */
|
|
50
|
+
export interface ComboboxHandle {
|
|
51
|
+
/** Register the trigger element. Returns a cleanup function. */
|
|
52
|
+
registerTrigger(trigger: HTMLInputElement | HTMLButtonElement): () => void;
|
|
53
|
+
/** Register the listbox/grid element. Returns a cleanup function. */
|
|
54
|
+
registerListbox(listbox: HTMLElement): () => void;
|
|
55
|
+
/** Tear down all listeners and state. */
|
|
56
|
+
destroy(): void;
|
|
57
|
+
/** Subscribe to a combobox event. Returns an unsubscribe function. */
|
|
58
|
+
subscribe<K extends keyof ComboboxEventMap>(event: K, callback: (value: ComboboxEventMap[K]) => void): () => void;
|
|
59
|
+
/** The current trigger element (may be null before registration). */
|
|
60
|
+
readonly trigger: HTMLInputElement | HTMLButtonElement | null;
|
|
61
|
+
/** The current listbox/grid element (may be null before registration). */
|
|
62
|
+
readonly listbox: HTMLElement | null;
|
|
63
|
+
/** The focus navigation controller. */
|
|
64
|
+
readonly focusNav: FocusNavigationController | null;
|
|
65
|
+
/** Whether the popup is open. */
|
|
66
|
+
readonly isOpen: boolean;
|
|
67
|
+
/** Whether multi-select mode. */
|
|
68
|
+
readonly isMultiSelect: boolean;
|
|
69
|
+
/** Whether any skeleton placeholders are currently registered (loading). */
|
|
70
|
+
readonly isLoading: boolean;
|
|
71
|
+
/** Set the open state, update ARIA, fire callback. */
|
|
72
|
+
setIsOpen(isOpen: boolean): void;
|
|
73
|
+
/** Select an option (or null to clear), fire callback. */
|
|
74
|
+
select(option: HTMLElement | null): void;
|
|
75
|
+
/**
|
|
76
|
+
* Register an option DOM element for filter notifications.
|
|
77
|
+
* The element's textContent is used as the searchable text.
|
|
78
|
+
* The callback is invoked immediately with the current filter state,
|
|
79
|
+
* and again whenever the filter changes.
|
|
80
|
+
* Returns a cleanup function that unregisters the option.
|
|
81
|
+
*/
|
|
82
|
+
registerOption(element: HTMLElement, onFilterChange: (isFiltered: boolean) => void): () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Set the current filter value and notify all registered options of their match state.
|
|
85
|
+
* Options whose text does not start with the filter value are notified with isFiltered=true.
|
|
86
|
+
* An empty filter value clears filtering (all options become visible).
|
|
87
|
+
*/
|
|
88
|
+
setFilter(filterValue: string): void;
|
|
89
|
+
/**
|
|
90
|
+
* Register a section DOM element for state notifications.
|
|
91
|
+
* The callback is invoked immediately with the current state, and again whenever
|
|
92
|
+
* the state changes after a filter update or option un/registration.
|
|
93
|
+
*
|
|
94
|
+
* - `hidden`: true when all registered options are filtered out (keeps children mounted
|
|
95
|
+
* but invisible to the user and screen readers).
|
|
96
|
+
* - `aria-hidden`: true when the section has no registered options at all (skeleton-only).
|
|
97
|
+
* The section stays visually rendered but is hidden from assistive technology —
|
|
98
|
+
* the live region (`ComboboxState`) handles the loading announcement instead.
|
|
99
|
+
*
|
|
100
|
+
* At most one of `hidden` / `aria-hidden` is true at a time.
|
|
101
|
+
*
|
|
102
|
+
* Returns a cleanup function that unregisters the section.
|
|
103
|
+
*/
|
|
104
|
+
registerSection(element: HTMLElement, onChange: (state: {
|
|
105
|
+
hidden: boolean;
|
|
106
|
+
'aria-hidden': boolean;
|
|
107
|
+
}) => void): () => void;
|
|
108
|
+
/**
|
|
109
|
+
* Register a skeleton placeholder. Increments the internal skeleton counter.
|
|
110
|
+
* When the counter transitions from 0 to >0, fires `loadingChange` immediately
|
|
111
|
+
* and schedules `loadingAnnouncement` after 500ms. Returns a cleanup function
|
|
112
|
+
* that decrements the counter (and fires the reverse transitions when reaching 0).
|
|
113
|
+
*/
|
|
114
|
+
registerSkeleton(): () => void;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Callback invoked when the trigger is attached and the abort controller is ready.
|
|
118
|
+
*
|
|
119
|
+
* The callback can optionally return a mode-specific keydown hook. When returned,
|
|
120
|
+
* it is called before the shared keydown handler; return `true` to indicate the
|
|
121
|
+
* event was handled (the caller will call `stopPropagation`/`preventDefault`)
|
|
122
|
+
* and skip the shared logic.
|
|
123
|
+
*/
|
|
124
|
+
export type OnTriggerAttach = (handle: ComboboxHandle, signal: AbortSignal) => ((event: KeyboardEvent) => boolean) | void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FocusNavigationController } from '../../utils/focusNavigation';
|
|
2
|
+
import type { OptionRegistration, SectionRegistration } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Get the value for a combobox option element.
|
|
5
|
+
* Uses `data-value` when set; falls back to the element's trimmed `textContent`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getOptionValue(option: HTMLElement): string;
|
|
8
|
+
/** Returns true when an option carries aria-disabled="true". */
|
|
9
|
+
export declare function isOptionDisabled(option: HTMLElement): boolean;
|
|
10
|
+
/** Returns true when the cell is NOT the first gridcell in its row (i.e., it's an action cell). */
|
|
11
|
+
export declare function isActionCell(cell: HTMLElement): boolean;
|
|
12
|
+
/** Predicate matching an option element that carries `aria-selected="true"`. */
|
|
13
|
+
export declare const isSelected: (el: Element) => boolean;
|
|
14
|
+
/** Navigate to the selected option, or to the first option if none is selected. */
|
|
15
|
+
export declare function goToSelectedOrFirst(nav: FocusNavigationController): void;
|
|
16
|
+
/** Navigate to the selected option, or to the last option if none is selected. */
|
|
17
|
+
export declare function goToSelectedOrLast(nav: FocusNavigationController): void;
|
|
18
|
+
/**
|
|
19
|
+
* Compute the current state of a section and notify when it changed.
|
|
20
|
+
*
|
|
21
|
+
* Section state:
|
|
22
|
+
* - `hidden`: true when the section has registered options but all are filtered out.
|
|
23
|
+
* - `aria-hidden`: true when the section has no registered options at all (skeleton-only).
|
|
24
|
+
*
|
|
25
|
+
* At most one of `hidden` / `aria-hidden` is true at a time.
|
|
26
|
+
*/
|
|
27
|
+
export declare function notifySection(sectionElement: HTMLElement, sectionRegistrations: Map<HTMLElement, SectionRegistration>, optionRegistrations: Map<HTMLElement, OptionRegistration>, force?: boolean): void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Size } from '../../constants';
|
|
2
|
+
import type { CommonRef, GenericProps, HasAriaDisabled, HasClassName, JSXElement, LumxClassName } from '../../types';
|
|
3
|
+
/** ListItem size variants. */
|
|
4
|
+
export type ListItemSize = Extract<Size, 'tiny' | 'regular' | 'big' | 'huge'>;
|
|
5
|
+
/**
|
|
6
|
+
* Defines the props of the component.
|
|
7
|
+
*/
|
|
8
|
+
export interface ListItemProps extends HasClassName, HasAriaDisabled {
|
|
9
|
+
/** A component to be rendered after the content. */
|
|
10
|
+
after?: JSXElement;
|
|
11
|
+
/** A component to be rendered before the content. */
|
|
12
|
+
before?: JSXElement;
|
|
13
|
+
/** Content. */
|
|
14
|
+
children?: JSXElement;
|
|
15
|
+
/** Whether the list item should be highlighted or not. */
|
|
16
|
+
isHighlighted?: boolean;
|
|
17
|
+
/** Whether the component is selected or not. */
|
|
18
|
+
isSelected?: boolean;
|
|
19
|
+
/** Whether link/button is disabled or not. */
|
|
20
|
+
isDisabled?: boolean;
|
|
21
|
+
/** Custom component for the link (can be used to inject router Link). */
|
|
22
|
+
linkAs?: 'a' | any;
|
|
23
|
+
/** Props that will be passed on to the Link. */
|
|
24
|
+
linkProps?: GenericProps;
|
|
25
|
+
/** Reference to the link element. */
|
|
26
|
+
linkRef?: CommonRef;
|
|
27
|
+
/** Size variant. */
|
|
28
|
+
size?: ListItemSize;
|
|
29
|
+
/** ref to the root <li> element */
|
|
30
|
+
ref?: CommonRef;
|
|
31
|
+
/** On click callback. */
|
|
32
|
+
handleClick?: (event: any) => void;
|
|
33
|
+
}
|
|
34
|
+
export type ListItemPropsToOverride = 'after' | 'before' | 'children' | 'handleClick';
|
|
35
|
+
/**
|
|
36
|
+
* Component display name.
|
|
37
|
+
*/
|
|
38
|
+
export declare const COMPONENT_NAME = "ListItem";
|
|
39
|
+
/**
|
|
40
|
+
* Component default class name and class prefix.
|
|
41
|
+
*/
|
|
42
|
+
export declare const CLASSNAME: LumxClassName<typeof COMPONENT_NAME>;
|
|
43
|
+
/**
|
|
44
|
+
* Component default props.
|
|
45
|
+
*/
|
|
46
|
+
export declare const DEFAULT_PROPS: Partial<ListItemProps>;
|
|
47
|
+
/**
|
|
48
|
+
* ListItem component.
|
|
49
|
+
*
|
|
50
|
+
* @param props Component props.
|
|
51
|
+
* @return JSX element.
|
|
52
|
+
*/
|
|
53
|
+
export declare const ListItem: {
|
|
54
|
+
(props: ListItemProps): import("react").JSX.Element;
|
|
55
|
+
displayName: string;
|
|
56
|
+
className: "lumx-list-item";
|
|
57
|
+
defaultProps: Partial<ListItemProps>;
|
|
58
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HasClassName } from '../../types';
|
|
2
|
+
import { ClickableElement, RawClickableProps } from '../RawClickable';
|
|
3
|
+
/**
|
|
4
|
+
* ListItemAction props.
|
|
5
|
+
*/
|
|
6
|
+
export type ListItemActionProps<E extends ClickableElement = 'button'> = RawClickableProps<E> & HasClassName;
|
|
7
|
+
/**
|
|
8
|
+
* Component display name.
|
|
9
|
+
*/
|
|
10
|
+
export declare const COMPONENT_NAME = "ListItemAction";
|
|
11
|
+
/**
|
|
12
|
+
* Component classname (used by action area CSS pattern).
|
|
13
|
+
*/
|
|
14
|
+
export declare const CLASSNAME = "lumx-action-area__action";
|
|
15
|
+
export declare const DEFAULT_PROPS: Partial<ListItemActionProps>;
|
|
16
|
+
/**
|
|
17
|
+
* ListItemAction component.
|
|
18
|
+
*
|
|
19
|
+
* Renders a button or link with action area classes.
|
|
20
|
+
* When placed as a child of ListItem, it activates the action area pattern:
|
|
21
|
+
* the entire list item becomes visually clickable, while other interactive
|
|
22
|
+
* elements (in `before`/`after` slots) remain independently clickable.
|
|
23
|
+
*/
|
|
24
|
+
export declare const ListItemAction: <E extends ClickableElement = "button">(props: ListItemActionProps<E>) => import("react").JSX.Element;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Size } from '../../constants';
|
|
2
|
+
import type { CommonRef, HasClassName, JSXElement, LumxClassName } from '../../types';
|
|
3
|
+
/** List item padding size. */
|
|
4
|
+
export type ListItemPadding = Extract<Size, 'big' | 'huge'>;
|
|
5
|
+
/**
|
|
6
|
+
* Defines the props of the component.
|
|
7
|
+
*/
|
|
8
|
+
export interface ListProps extends HasClassName {
|
|
9
|
+
/** List content (should be ListItem, ListDivider, etc.). */
|
|
10
|
+
children?: JSXElement;
|
|
11
|
+
/** Item padding size. */
|
|
12
|
+
itemPadding?: ListItemPadding;
|
|
13
|
+
/** ref to the root element */
|
|
14
|
+
ref?: CommonRef;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Component display name.
|
|
18
|
+
*/
|
|
19
|
+
export declare const COMPONENT_NAME = "List";
|
|
20
|
+
/**
|
|
21
|
+
* Component default class name and class prefix.
|
|
22
|
+
*/
|
|
23
|
+
export declare const CLASSNAME: LumxClassName<typeof COMPONENT_NAME>;
|
|
24
|
+
/**
|
|
25
|
+
* Component default props.
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_PROPS: Partial<ListProps>;
|
|
28
|
+
/**
|
|
29
|
+
* List component.
|
|
30
|
+
*
|
|
31
|
+
* @param props Component props.
|
|
32
|
+
* @return JSX element.
|
|
33
|
+
*/
|
|
34
|
+
export declare const List: {
|
|
35
|
+
(props: ListProps): import("react").JSX.Element;
|
|
36
|
+
displayName: string;
|
|
37
|
+
className: "lumx-list";
|
|
38
|
+
defaultProps: Partial<ListProps>;
|
|
39
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SetupOptions } from '../../../testing';
|
|
2
|
+
/**
|
|
3
|
+
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
4
|
+
*/
|
|
5
|
+
export declare const setup: (propsOverride: any | undefined, { render, ...options }: SetupOptions<any>) => {
|
|
6
|
+
props: any;
|
|
7
|
+
mosaic: HTMLElement;
|
|
8
|
+
thumbnails: HTMLElement[];
|
|
9
|
+
overlay: HTMLElement | null;
|
|
10
|
+
wrapper: Partial<import("../../../testing").SetupResult>;
|
|
11
|
+
};
|
|
12
|
+
declare const _default: (renderOptions: SetupOptions<any>) => void;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Alignment } from '../../constants';
|
|
2
|
+
import { CommonRef, HasClassName, HasTheme, JSXElement } from '../../types';
|
|
3
|
+
export declare enum TabListLayout {
|
|
4
|
+
clustered = "clustered",
|
|
5
|
+
fixed = "fixed"
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Defines the props of the component.
|
|
9
|
+
*/
|
|
10
|
+
export interface TabListProps extends HasClassName, HasTheme {
|
|
11
|
+
/** ARIA label (purpose of the set of tabs). */
|
|
12
|
+
['aria-label']: string;
|
|
13
|
+
/** Tab list. */
|
|
14
|
+
children: JSXElement;
|
|
15
|
+
/** Layout of the tabs in the list. */
|
|
16
|
+
layout?: TabListLayout;
|
|
17
|
+
/** Position of the tabs in the list (requires 'clustered' layout). */
|
|
18
|
+
position?: Alignment;
|
|
19
|
+
/** ref to the wrapper element */
|
|
20
|
+
ref?: CommonRef;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Component display name.
|
|
24
|
+
*/
|
|
25
|
+
export declare const COMPONENT_NAME = "TabList";
|
|
26
|
+
/**
|
|
27
|
+
* Component default props.
|
|
28
|
+
*/
|
|
29
|
+
export declare const DEFAULT_PROPS: Partial<TabListProps>;
|
|
30
|
+
/**
|
|
31
|
+
* TabList component.
|
|
32
|
+
*
|
|
33
|
+
* Implements WAI-ARIA `tablist` role {@see https://www.w3.org/TR/wai-aria-practices-1.1/examples/tabs/tabs-1/tabs.html#rps_label}
|
|
34
|
+
*
|
|
35
|
+
* @param props Component props.
|
|
36
|
+
* @param ref Component ref.
|
|
37
|
+
* @return React element.
|
|
38
|
+
*/
|
|
39
|
+
export declare const TabList: (props: TabListProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SetupOptions } from '../../../testing';
|
|
2
|
+
/**
|
|
3
|
+
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
4
|
+
*/
|
|
5
|
+
export declare const setup: (propsOverride: any | undefined, { render, ...options }: SetupOptions<any>) => {
|
|
6
|
+
props: any;
|
|
7
|
+
tabList: HTMLElement;
|
|
8
|
+
links: HTMLElement | null;
|
|
9
|
+
wrapper: Partial<import("../../../testing").SetupResult>;
|
|
10
|
+
};
|
|
11
|
+
declare const _default: (renderOptions: SetupOptions<any>) => void;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SetupOptions } from '../../../testing';
|
|
2
|
+
/**
|
|
3
|
+
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
4
|
+
*/
|
|
5
|
+
export declare const setup: (propsOverride: any | undefined, { render, ...options }: SetupOptions<any>) => {
|
|
6
|
+
props: any;
|
|
7
|
+
tabPanel: HTMLElement;
|
|
8
|
+
wrapper: Partial<import("../../../testing").SetupResult>;
|
|
9
|
+
};
|
|
10
|
+
declare const _default: (renderOptions: SetupOptions<any>) => void;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test util module. Do not import in production code!
|
|
3
|
+
*/
|
|
4
|
+
export declare const createTabTestUtils: ({ screen, within }: {
|
|
5
|
+
screen: any;
|
|
6
|
+
within: any;
|
|
7
|
+
}) => {
|
|
8
|
+
query: {
|
|
9
|
+
tabList: (name: string) => any;
|
|
10
|
+
tabs: (tabList?: any) => any;
|
|
11
|
+
tab: (name: string, tabList?: any) => any;
|
|
12
|
+
tabPanel: (name: string) => any;
|
|
13
|
+
};
|
|
14
|
+
checkTabActive: (activeTabName: string, { isLazy }?: {
|
|
15
|
+
isLazy?: boolean | undefined;
|
|
16
|
+
}) => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SetupOptions } from '../../../testing';
|
|
2
|
+
/**
|
|
3
|
+
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
4
|
+
*/
|
|
5
|
+
export declare const setup: (propsOverride: any | undefined, { render, ...options }: SetupOptions<any>) => {
|
|
6
|
+
props: any;
|
|
7
|
+
tab: HTMLElement;
|
|
8
|
+
wrapper: Partial<import("../../../testing").SetupResult>;
|
|
9
|
+
};
|
|
10
|
+
declare const _default: (renderOptions: SetupOptions<any>) => void;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type TabType = 'tab' | 'tabPanel';
|
|
2
|
+
export interface State {
|
|
3
|
+
isLazy: boolean;
|
|
4
|
+
shouldActivateOnFocus: boolean;
|
|
5
|
+
activeTabIndex: number;
|
|
6
|
+
ids: Record<TabType, string[]>;
|
|
7
|
+
}
|
|
8
|
+
export declare const INIT_STATE: State;
|
|
9
|
+
export type Action = {
|
|
10
|
+
type: 'update';
|
|
11
|
+
payload: Partial<State>;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'setActiveTabIndex';
|
|
14
|
+
payload: number;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'register';
|
|
17
|
+
payload: {
|
|
18
|
+
type: TabType;
|
|
19
|
+
id: string;
|
|
20
|
+
};
|
|
21
|
+
} | {
|
|
22
|
+
type: 'unregister';
|
|
23
|
+
payload: {
|
|
24
|
+
type: TabType;
|
|
25
|
+
id: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export declare const reducer: (state: State, action: Action) => State;
|
|
29
|
+
export type TabState = Pick<Required<State>, 'isLazy' | 'shouldActivateOnFocus'> & {
|
|
30
|
+
isActive: boolean;
|
|
31
|
+
tabId: string;
|
|
32
|
+
tabPanelId: string;
|
|
33
|
+
changeToTab(): void;
|
|
34
|
+
};
|
|
@@ -69,7 +69,7 @@ export declare const DEFAULT_PROPS: {};
|
|
|
69
69
|
* @param props Component props.
|
|
70
70
|
* @return Common Props
|
|
71
71
|
*/
|
|
72
|
-
export declare const getTextProps: (props: TextProps) => {
|
|
72
|
+
export declare const getTextProps: (props: Omit<TextProps, "as">) => {
|
|
73
73
|
className: string;
|
|
74
74
|
style: {
|
|
75
75
|
accentColor?: import("csstype").Property.AccentColor | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SetupOptions } from '../../../testing';
|
|
2
|
+
/**
|
|
3
|
+
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
4
|
+
*/
|
|
5
|
+
export declare const setup: (propsOverride: any | undefined, { render, ...options }: SetupOptions<any>) => {
|
|
6
|
+
props: any;
|
|
7
|
+
userBlock: HTMLElement;
|
|
8
|
+
fields: HTMLElement | null;
|
|
9
|
+
div: HTMLElement;
|
|
10
|
+
wrapper: Partial<import("../../../testing").SetupResult>;
|
|
11
|
+
};
|
|
12
|
+
declare const _default: (renderOptions: SetupOptions<any>) => void;
|
|
13
|
+
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** list of generic props defined on JSX that need to be redefined for each framework */
|
|
2
|
-
export type PropsToOverride = 'ref' | 'handleClick' | 'handleChange' | 'handleKeyPress' | 'handleClose' | 'handleBeforeClick' | 'handleAfterClick' | 'handleKeyDown';
|
|
2
|
+
export type PropsToOverride = 'ref' | 'handleClick' | 'handleChange' | 'handleKeyPress' | 'handleClose' | 'handleFocus' | 'handleBeforeClick' | 'handleAfterClick' | 'handleMouseEnter' | 'handleMouseLeave' | 'handleKeyDown';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a TreeWalker that iterates over elements matching a CSS selector
|
|
3
|
+
* within a container.
|
|
4
|
+
*
|
|
5
|
+
* Uses `NodeFilter.SHOW_ELEMENT` and accepts nodes that match the given
|
|
6
|
+
* selector, skipping everything else. The returned walker can be used with
|
|
7
|
+
* `nextNode()` / `previousNode()` for lazy, sequential DOM traversal.
|
|
8
|
+
*
|
|
9
|
+
* @param container The root element to walk within.
|
|
10
|
+
* @param selector CSS selector that items must match.
|
|
11
|
+
* @returns A TreeWalker scoped to the container and filtered by the selector.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createSelectorTreeWalker(container: HTMLElement, selector: string): TreeWalker;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FocusNavigationCallbacks, FocusNavigationController, GridNavigationOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Create a focus navigation controller for a 2D grid.
|
|
4
|
+
*
|
|
5
|
+
* Supports Up/Down between rows (with column memory) and Left/Right between cells
|
|
6
|
+
* (with wrapping across rows).
|
|
7
|
+
*
|
|
8
|
+
* @param options Grid navigation options (container, rowSelector, cellSelector, isRowVisible, wrap).
|
|
9
|
+
* @param callbacks Callbacks for focus state changes.
|
|
10
|
+
* @param signal AbortSignal for cleanup.
|
|
11
|
+
* @returns FocusNavigationController instance.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createGridFocusNavigation(options: GridNavigationOptions, callbacks: FocusNavigationCallbacks, signal: AbortSignal): FocusNavigationController;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export type { FocusNavigationCallbacks, FocusNavigationController, ListNavigationOptions } from './types';
|
|
1
|
+
export type { FocusNavigationCallbacks, FocusNavigationController, GridNavigationOptions, ListNavigationOptions, NavigationOptions, } from './types';
|
|
2
2
|
export type { RovingTabIndexOptions } from './setupRovingTabIndex';
|
|
3
3
|
export { createListFocusNavigation } from './createListFocusNavigation';
|
|
4
|
+
export { createGridFocusNavigation } from './createGridFocusNavigation';
|
|
4
5
|
export { setupRovingTabIndex } from './setupRovingTabIndex';
|