@ssa-ui-kit/core 3.27.0 → 3.27.1

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.
@@ -259,6 +259,9 @@ Select-like dropdown component for single selection
259
259
  - `success?: boolean` `= false` — Whether to display success state styling When true, status is set to 'success'
260
260
  - `icon?: 'reset' | 'archive' | 'arrow-down' | 'arrow-up' | …(237 more — full list under "Icon.name")` — Leading icon shown in the toggle button when no selected item avatar is present. Ignored once an item with an…
261
261
  - `width?: string | number` — Width of the dropdown. Can be a number (pixels) or a string (any CSS value, e.g. `'100%'`).
262
+ - `searchable?: boolean` `= false` — Adds a search box above the open list. Typing filters the options by their text (case-insensitive, anywhere…
263
+ - `searchPlaceholder?: string` `= 'Search'` — Placeholder and accessible name of the search box.
264
+ - `searchEmptyState?: React.ReactNode` `= 'No results found'` — Shown in the list when nothing matches the search.
262
265
  - `dropdownProps?: { base, toggleButton, toggleButtonArrow, dropdownPosition }` — Props object for sub-components Allows fine-grained control over component parts
263
266
 
264
267
  #### DropdownArrow
@@ -283,6 +286,7 @@ A single selectable row inside `Dropdown` or `MultipleDropdown`.
283
286
  - `label?: string | number`
284
287
  - `children?: React.ReactNode`
285
288
  - `avatar?: React.ReactNode` — Avatar or icon to display before the option content (e.g. <Avatar size={20} image={url} />)
289
+ - `textValue?: string` — Plain text of the option, for search and type-to-find. Needed when `children` is markup rather than text;…
286
290
  - _plus native element attributes_
287
291
 
288
292
  #### DropdownOptionGroup
@@ -427,6 +431,9 @@ Dropdown component for multi-select and single-select
427
431
  - `onChange?: (selectedItem: string | number, isSelected: boolean) => void` — Callback fired when an option is toggled
428
432
  - `maxHeight?: number` `= 200` — Max height (px) of the options list; overflow scrolls.
429
433
  - `width?: string | number` — Width of the dropdown. Can be a number (pixels) or a string (any CSS value, e.g. `'100%'`).
434
+ - `searchable?: boolean` `= false` — Adds a search box above the open list. Typing filters the options by their text (case-insensitive, anywhere…
435
+ - `searchPlaceholder?: string` `= 'Search'` — Placeholder and accessible name of the search box.
436
+ - `searchEmptyState?: ReactNode` `= 'No results found'` — Shown in the list when nothing matches the search.
430
437
 
431
438
  #### MultipleDropdownNotification
432
439
 
@@ -94,5 +94,5 @@ import { DropdownProps } from './types';
94
94
  *
95
95
  * @see https://www.w3.org/WAI/ARIA/apg/example-index/combobox/combobox-select-only.html
96
96
  */
97
- declare const Dropdown: <T extends DropdownOptionProps>({ selectedItem, disabled, isDisabled, isOpen: isInitOpen, children, onChange: handleChange, className, placeholder, maxHeight, avatarBorder, label, labelBadge, helperText, errors, success, icon, width, dropdownProps: componentProps, }: DropdownProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
97
+ declare const Dropdown: <T extends DropdownOptionProps>({ selectedItem, disabled, isDisabled, isOpen: isInitOpen, children, onChange: handleChange, className, placeholder, maxHeight, avatarBorder, label, labelBadge, helperText, errors, success, icon, width, searchable, searchPlaceholder, searchEmptyState, dropdownProps: componentProps, }: DropdownProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
98
98
  export default Dropdown;
@@ -161,6 +161,36 @@ export interface DropdownProps<P extends DropdownOptionProps> extends CommonProp
161
161
  * ```
162
162
  */
163
163
  width?: string | number;
164
+ /**
165
+ * Adds a search box above the open list. Typing filters the options by
166
+ * their text (case-insensitive, anywhere in the text); a group stays while
167
+ * any of its options match. Options whose `children` is markup are matched
168
+ * by their `textValue`.
169
+ *
170
+ * Focus moves to the search box on open and keeps driving the list: arrows
171
+ * move the highlight, Enter picks, Escape clears the search, then closes.
172
+ * @default false
173
+ *
174
+ * @example
175
+ * ```tsx
176
+ * <Dropdown searchable searchPlaceholder="Search country" onChange={setCountry}>
177
+ * {countries.map((c) => (
178
+ * <DropdownOption key={c.code} value={c.code} label={c.name} />
179
+ * ))}
180
+ * </Dropdown>
181
+ * ```
182
+ */
183
+ searchable?: boolean;
184
+ /**
185
+ * Placeholder and accessible name of the search box.
186
+ * @default 'Search'
187
+ */
188
+ searchPlaceholder?: string;
189
+ /**
190
+ * Shown in the list when nothing matches the search.
191
+ * @default 'No results found'
192
+ */
193
+ searchEmptyState?: React.ReactNode;
164
194
  /**
165
195
  * Props object for sub-components
166
196
  * Allows fine-grained control over component parts
@@ -246,4 +276,8 @@ export interface DropdownContextType {
246
276
  activeValue?: string | number | null;
247
277
  /** Moves the highlight; called by the list on pointer moves. */
248
278
  setActiveValue?: (value: string | number | null) => void;
279
+ /** The list sits in the search card, which does the positioning. */
280
+ searchable?: boolean;
281
+ /** Shown when the list has no options. */
282
+ emptyState?: React.ReactNode;
249
283
  }
@@ -18,6 +18,11 @@ export interface DropdownItemProps extends CommonProps, Omit<React.LiHTMLAttribu
18
18
  children?: React.ReactNode;
19
19
  /** Avatar or icon to display before the option content (e.g. <Avatar size={20} image={url} />) */
20
20
  avatar?: React.ReactNode;
21
+ /**
22
+ * Plain text of the option, for search and type-to-find. Needed when
23
+ * `children` is markup rather than text; defaults to the text label.
24
+ */
25
+ textValue?: string;
21
26
  }
22
27
  /**
23
28
  * DropdownOption - A single selectable row inside `Dropdown` or
@@ -0,0 +1,25 @@
1
+ import { KeyboardEvent, ReactNode } from 'react';
2
+ /** Props of {@link DropdownSearch}. */
3
+ export interface DropdownSearchProps {
4
+ /** Typed text. */
5
+ query: string;
6
+ onQueryChange: (query: string) => void;
7
+ placeholder: string;
8
+ /** Id of the list the input drives. */
9
+ listId: string;
10
+ /** Opens upward or downward from the toggle. */
11
+ placement?: 'top' | 'bottom';
12
+ zIndex?: number;
13
+ /** The highlighted option's id. */
14
+ 'aria-activedescendant'?: string;
15
+ onKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
16
+ onKeyUp?: (event: KeyboardEvent<HTMLInputElement>) => void;
17
+ /** The options list. */
18
+ children: ReactNode;
19
+ }
20
+ /**
21
+ * The open list of a searchable `Dropdown` / `MultipleDropdown`: a search box,
22
+ * focused on open, above the options. The box is the combobox while the list
23
+ * is open — it keeps focus and points at the highlighted option.
24
+ */
25
+ export declare const DropdownSearch: ({ query, onQueryChange, placeholder, listId, placement, zIndex, children, ...inputProps }: DropdownSearchProps) => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -2,7 +2,7 @@ import { KeyboardEvent } from 'react';
2
2
  import { ContextMenuEntry } from '../ContextMenu';
3
3
  import { OptionValue } from './utils';
4
4
  /** Options of {@link useToggleListKeys}. */
5
- export interface UseToggleListKeysOptions {
5
+ export interface UseToggleListKeysOptions<E extends HTMLElement = HTMLButtonElement> {
6
6
  /** Id of the ContextMenu the toggle controls. */
7
7
  listId: string;
8
8
  isOpen: boolean;
@@ -16,18 +16,24 @@ export interface UseToggleListKeysOptions {
16
16
  close: () => void;
17
17
  /** Enter or Space on the highlighted option. */
18
18
  onPick: (value: OptionValue) => void;
19
+ /**
20
+ * Keys go to a text input (the search box): Space types a space and
21
+ * Home / End move the caret instead of the highlight.
22
+ */
23
+ typing?: boolean;
19
24
  /** Consumer handlers, run first; `preventDefault()` skips the built-in keys. */
20
- onKeyDown?: (event: KeyboardEvent<HTMLButtonElement>) => void;
21
- onKeyUp?: (event: KeyboardEvent<HTMLButtonElement>) => void;
25
+ onKeyDown?: (event: KeyboardEvent<E>) => void;
26
+ onKeyUp?: (event: KeyboardEvent<E>) => void;
22
27
  }
23
28
  /**
24
29
  * Keyboard for a dropdown toggle that keeps focus while it drives its list:
25
30
  * arrows open it, then Arrow/Home/End move the highlight, Enter/Space pick,
26
31
  * Escape/Tab close. Returns the toggle's handlers and its
27
- * `aria-activedescendant`.
32
+ * `aria-activedescendant`. With `typing`, drives the list from a search input
33
+ * instead.
28
34
  */
29
- export declare const useToggleListKeys: ({ listId, isOpen, disabled, menuItems, activeValue, setActiveValue, open, close, onPick, onKeyDown, onKeyUp, }: UseToggleListKeysOptions) => {
30
- onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;
31
- onKeyUp: (event: KeyboardEvent<HTMLButtonElement>) => void;
35
+ export declare const useToggleListKeys: <E extends HTMLElement = HTMLButtonElement>({ listId, isOpen, disabled, menuItems, activeValue, setActiveValue, open, close, onPick, typing, onKeyDown, onKeyUp, }: UseToggleListKeysOptions<E>) => {
36
+ onKeyDown: (event: KeyboardEvent<E>) => void;
37
+ onKeyUp: (event: KeyboardEvent<E>) => void;
32
38
  'aria-activedescendant': string | undefined;
33
39
  };
@@ -14,3 +14,10 @@ export declare const flattenDropdownOptions: (children: React.ReactNode) => Reac
14
14
  * `children` → `label` → `value`, as it always has.
15
15
  */
16
16
  export declare const toDropdownMenuItems: (children: React.ReactNode) => ContextMenuEntry<OptionValue>[];
17
+ /**
18
+ * The `DropdownOption` children whose text contains `query` (case-insensitive),
19
+ * in display order. A `DropdownOptionGroup` is kept, holding only its matching
20
+ * options, while any of them match. An empty query returns the children as is.
21
+ * Options with no text (custom markup and no `textValue`) never match.
22
+ */
23
+ export declare const filterDropdownOptions: (children: React.ReactNode, query: string) => React.ReactElement[];
@@ -5,6 +5,8 @@ import { ControlledButtonProps } from '../Dropdown/types';
5
5
  export interface DropdownToggleProps extends CommonProps, Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, ControlledButtonProps> {
6
6
  /** Emotion css prop forwarded to the underlying styled button */
7
7
  css?: Interpolation<Theme>;
8
+ /** Ref to the button, e.g. to return focus to it. */
9
+ ref?: React.Ref<HTMLButtonElement>;
8
10
  onClick: (e: React.MouseEvent<HTMLElement>) => void;
9
11
  onFocus?: (e: React.FocusEvent<HTMLButtonElement, Element>) => void;
10
12
  isOpen: boolean;
@@ -98,6 +98,27 @@ export type DropdownProps<P extends DropdownOptionProps> = {
98
98
  * matching the behaviour of previous versions.
99
99
  */
100
100
  width?: string | number;
101
+ /**
102
+ * Adds a search box above the open list. Typing filters the options by
103
+ * their text (case-insensitive, anywhere in the text); a group stays while
104
+ * any of its options match. Options whose `children` is markup are matched
105
+ * by their `textValue`. Selections outside the current search are kept.
106
+ *
107
+ * Focus moves to the search box on open and keeps driving the list: arrows
108
+ * move the highlight, Enter toggles, Escape clears the search, then closes.
109
+ * @default false
110
+ */
111
+ searchable?: boolean;
112
+ /**
113
+ * Placeholder and accessible name of the search box.
114
+ * @default 'Search'
115
+ */
116
+ searchPlaceholder?: string;
117
+ /**
118
+ * Shown in the list when nothing matches the search.
119
+ * @default 'No results found'
120
+ */
121
+ searchEmptyState?: React.ReactNode;
101
122
  };
102
123
  /**
103
124
  * Context value shared with child DropdownOption components via MultipleDropdownContext
@@ -127,4 +148,8 @@ export interface DropdownContextType<T extends DropdownOptionProps> {
127
148
  * Updates the highlighted option
128
149
  */
129
150
  setActiveValue?: (value: string | number | null) => void;
151
+ /** The list sits in the search card, which does the positioning. */
152
+ searchable?: boolean;
153
+ /** Shown when the list has no options. */
154
+ emptyState?: React.ReactNode;
130
155
  }