@payfit/unity-components
Version:
193 lines (192 loc) • 6.54 kB
TypeScript
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;