UNPKG

2.65 kBPlain TextView Raw
1import * as React from "react";
2import {
3 SealedInitialState,
4 useSealedState,
5} from "reakit-utils/useSealedState";
6import { SetState } from "reakit-utils/types";
7import {
8 unstable_useGridState as useGridState,
9 unstable_GridState as GridState,
10 unstable_GridActions as GridActions,
11 unstable_GridInitialState as GridInitialState,
12} from "../Grid/GridState";
13import {
14 useComboboxBaseState,
15 ComboboxBaseState,
16 ComboboxBaseActions,
17 ComboboxBaseInitialState,
18} from "./__utils/ComboboxBaseState";
19
20function chunk<T>(array: T[], size: number) {
21 const chunks: T[][] = [];
22 for (let i = 0, j = array.length; i < j; i += size) {
23 chunks.push(array.slice(i, i + size));
24 }
25 return chunks;
26}
27
28export function unstable_useComboboxListGridState(
29 initialState: SealedInitialState<unstable_ComboboxListGridInitialState> = {}
30): unstable_ComboboxListGridStateReturn {
31 const {
32 columns: initialColumns = 1,
33 currentId = null,
34 loop = true,
35 ...sealed
36 } = useSealedState(initialState);
37
38 const [columns, setColumns] = React.useState(initialColumns);
39
40 const grid = useGridState({
41 currentId,
42 loop,
43 ...sealed,
44 unstable_virtual: true,
45 unstable_includesBaseElement: true,
46 });
47 const combobox = useComboboxBaseState(grid, sealed);
48
49 const matches = React.useMemo(() => chunk(combobox.matches, columns), [
50 combobox.matches,
51 columns,
52 ]);
53
54 return {
55 ...combobox,
56 menuRole: "grid",
57 columns,
58 matches,
59 setColumns,
60 };
61}
62
63export type unstable_ComboboxListGridState = Omit<
64 ComboboxBaseState<GridState>,
65 "matches"
66> & {
67 /**
68 * Number of columns by which `values` will be splitted to generate the
69 * `matches` 2D array.
70 */
71 columns: number;
72 /**
73 * Result of filtering `values` based on `inputValue`.
74 * @default []
75 * @example
76 * const combobox = useComboboxState({
77 * values: ["Red", "Green", "Blue"],
78 * columns: 2,
79 * });
80 * combobox.matches; // [["Red", "Green"], ["Blue"]]
81 * combobox.setInputValue("g");
82 * // On next render
83 * combobox.matches; // [["Green"]]
84 */
85 matches: string[][];
86};
87
88export type unstable_ComboboxListGridActions = ComboboxBaseActions<GridActions> & {
89 /**
90 * Sets `columns`.
91 */
92 setColumns: SetState<unstable_ComboboxListGridState["columns"]>;
93};
94
95export type unstable_ComboboxListGridInitialState = Omit<
96 GridInitialState,
97 "unstable_virtual" | "unstable_includesBaseElement"
98> &
99 ComboboxBaseInitialState &
100 Pick<Partial<unstable_ComboboxListGridState>, "columns">;
101
102export type unstable_ComboboxListGridStateReturn = unstable_ComboboxListGridState &
103 unstable_ComboboxListGridActions;