UNPKG

@payfit/unity-components

Version:

193 lines (192 loc) 6.54 kB
import { Selection } from 'react-aria-components/GridList'; import { SelectListProps } from '../select-list/SelectList.js'; import { FilterProps } from './Filter.types.js'; /** * Represents a single selectable item in a filter. * * Use this type to define the data structure for individual options in your filter. * Each item must have a unique `id` and a human-readable `label`. * @example * ```tsx * const statusItems: FilterItem[] = [ * { id: 'active', label: 'Active' }, * { id: 'inactive', label: 'Inactive' }, * { id: 'pending', label: 'Pending' }, * ] * ``` */ export interface FilterItem { /** * Unique identifier for the item. Used as the value in selections. */ id: string; /** * Human-readable label displayed to users. */ label: string; } /** * Represents a group of related filter items. * * Use this type to organize filter options into logical categories, improving UX when * dealing with many options. Groups are rendered with a header label and contain multiple * child items. * @example * ```tsx * const departmentGroups: FilterItemGroup[] = [ * { * id: 'business', * label: 'Business', * children: [ * { id: 'sales', label: 'Sales' }, * { id: 'marketing', label: 'Marketing' }, * ], * }, * { * id: 'tech', * label: 'Tech', * children: [ * { id: 'engineering', label: 'Engineering' }, * { id: 'product', label: 'Product' }, * ], * }, * ] * ``` */ export interface FilterItemGroup { /** * Unique identifier for the group. */ id: string; /** * Label for the group header. */ label: string; /** * Array of items belonging to this group. */ children: FilterItem[]; } /** * Creates a pre-configured SelectList control for use with the Filter component. * * This helper function simplifies the most common filter use case: selecting items from a list. * It handles the rendering of SelectList with proper multi-select behavior, keyboard navigation, * and support for both flat lists and grouped items. Use this function to quickly create filter * controls without manually managing SelectList configuration. * * The function returns a render function compatible with the Filter component's `renderControl` prop. * It automatically configures the SelectList with sensible defaults: multiple selection, selected items * sorted first, and proper accessibility attributes. * @template TFilterType - The type of the filter value (defaults to Selection from React Aria) * @template TItemType - The type of items in the list (FilterItem or FilterItemGroup) * @param items - An iterable collection of items or item groups to display in the list * @param props - Additional props to pass to the SelectList component (excluding items, value, * onChange, and children which are managed internally) * @returns A render function that creates a SelectList with the provided items and configuration * @example * ```tsx * import { Filter, selectListFilter } from '@payfit/unity-components' * import { useState } from 'react' * * // Simple flat list * const statusItems = [ * { id: 'active', label: 'Active' }, * { id: 'inactive', label: 'Inactive' }, * { id: 'pending', label: 'Pending' }, * ] * * function StatusFilter() { * const [value, setValue] = useState<Set<string>>(new Set()) * * return ( * <Filter * label="Status" * value={value} * onChange={setValue} * renderControl={selectListFilter(statusItems, {})} * /> * ) * } * ``` * @example * ```tsx * // Grouped list with custom aria-label * const departmentGroups = [ * { * id: 'business', * label: 'Business', * children: [ * { id: 'sales', label: 'Sales' }, * { id: 'marketing', label: 'Marketing' }, * ], * }, * { * id: 'tech', * label: 'Tech', * children: [ * { id: 'engineering', label: 'Engineering' }, * { id: 'product', label: 'Product' }, * ], * }, * ] * * function DepartmentFilter() { * const [value, setValue] = useState<Set<string>>(new Set()) * * return ( * <Filter * label="Departments" * value={value} * onChange={setValue} * renderControl={selectListFilter(departmentGroups, { * 'aria-label': 'Select departments', * })} * /> * ) * } * ``` * @remarks * - The returned SelectList is configured with `selectionMode="multiple"` by default * - Selected items are automatically sorted to the top of the list using `sortSelectedFirst` * - The escape key behavior is set to `"none"` to prevent closing the filter popover accidentally * - A maximum height of 300px is applied with scrolling enabled for long lists * - Both flat lists (FilterItem[]) and grouped lists (FilterItemGroup[]) are supported */ export declare function selectListFilter<TFilterType extends Selection = Selection, TItemType extends FilterItem | FilterItemGroup = FilterItem | FilterItemGroup>(items: Iterable<TItemType>, props: Omit<SelectListProps<TItemType>, 'items' | 'value' | 'onChange' | 'children'>): (value: TFilterType, onChange: FilterProps<TFilterType>["onChange"]) => import("react/jsx-runtime").JSX.Element; /** * Render the label of a filter that uses the default SelectList component. * This function will extract all the labels of all the selected items, and * create a comma-separated string from them. * @param items the array of items used in the select list * @return A curried function that flattens items into a comma-separated string * @example * ```tsx * import { Filter, selectListFilter, selectListLabel } from '@payfit/unity-components' * import { useState } from 'react' * * // Simple flat list * const statusItems = [ * { id: 'active', label: 'Active' }, * { id: 'inactive', label: 'Inactive' }, * { id: 'pending', label: 'Pending' }, * ] * * function StatusFilter() { * const [value, setValue] = useState<Set<string>>(new Set()) * * return ( * <Filter * label="Status" * value={value} * onChange={setValue} * renderControl={selectListFilter(statusItems, {})} * renderLabel={selectListLabel(items)} * /> * ) * } * ``` * @remarks * - Both flat lists (FilterItem[]) and grouped lists (FilterItemGroup[]) are supported */ export declare function selectListLabel(items: Array<FilterItem | FilterItemGroup>): (value: Selection) => string;