@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
1 lines • 9.58 kB
Source Map (JSON)
{"version":3,"file":"use-cascader.cjs","names":["getCascaderPathOptions","cascaderOptionHasChildren","getCascaderColumns"],"sources":["../../../src/components/Cascader/use-cascader.ts"],"sourcesContent":["import { useCallback, useMemo, useRef, useState } from 'react';\nimport { useUncontrolled } from '@mantine/hooks';\nimport type { CascaderOption } from './Cascader';\nimport { cascaderOptionHasChildren, getCascaderColumns } from './get-cascader-columns';\nimport { getCascaderPathOptions } from './get-cascader-path-options';\n\nexport interface UseCascaderInput {\n data: CascaderOption[];\n value: string[] | null | undefined;\n defaultValue: string[] | null | undefined;\n onChange: ((value: string[] | null, options: CascaderOption[]) => void) | undefined;\n changeOnSelect: boolean | undefined;\n allowDeselect: boolean | undefined;\n expandTrigger: 'click' | 'hover' | undefined;\n onLeafSelect?: () => void;\n}\n\nfunction pathsEqual(a: string[] | null, b: string[]): boolean {\n return !!a && a.length === b.length && a.every((item, index) => item === b[index]);\n}\n\nfunction findEnabledIndex(options: CascaderOption[], from: number, direction: 1 | -1): number {\n let index = from + direction;\n\n while (index >= 0 && index < options.length) {\n if (!options[index].disabled) {\n return index;\n }\n index += direction;\n }\n\n return -1;\n}\n\nexport function useCascader({\n data,\n value,\n defaultValue,\n onChange,\n changeOnSelect,\n allowDeselect,\n expandTrigger,\n onLeafSelect,\n}: UseCascaderInput) {\n const [keyboardNav, setKeyboardNav] = useState(false);\n\n const [_value, setValue] = useUncontrolled<string[] | null>({\n value: value as any,\n defaultValue: defaultValue as any,\n finalValue: null,\n onChange: (val) => onChange?.(val, getCascaderPathOptions(data, val)),\n });\n\n const [activePath, setActivePath] = useState<string[]>(() => _value ?? []);\n const activePathRef = useRef(activePath);\n activePathRef.current = activePath;\n\n const resetActivePath = useCallback(() => {\n setActivePath(_value ?? []);\n }, [_value]);\n\n const selectPath = useCallback(\n (path: string[]) => {\n setValue(allowDeselect && pathsEqual(_value, path) ? null : path);\n },\n [allowDeselect, _value, setValue]\n );\n\n const expandOption = useCallback((level: number, option: CascaderOption) => {\n const optionPath = [...activePathRef.current.slice(0, level), option.value];\n const children = option.children;\n\n if (Array.isArray(children) && children.length > 0) {\n const first = findEnabledIndex(children, -1, 1);\n setActivePath(first >= 0 ? [...optionPath, children[first].value] : optionPath);\n } else {\n setActivePath(optionPath);\n }\n }, []);\n\n const handleOptionClick = useCallback(\n (level: number, option: CascaderOption) => {\n setKeyboardNav(false);\n const path = [...activePath.slice(0, level), option.value];\n\n if (cascaderOptionHasChildren(option)) {\n if (changeOnSelect) {\n selectPath(path);\n }\n expandOption(level, option);\n if (changeOnSelect) {\n onLeafSelect?.();\n }\n } else {\n selectPath(path);\n onLeafSelect?.();\n }\n },\n [activePath, changeOnSelect, selectPath, expandOption, onLeafSelect]\n );\n\n const handleOptionMouseEnter = useCallback(\n (level: number, option: CascaderOption) => {\n setKeyboardNav(false);\n\n if (expandTrigger !== 'hover') {\n return;\n }\n\n if (cascaderOptionHasChildren(option)) {\n expandOption(level, option);\n } else {\n setActivePath([...activePath.slice(0, level), option.value]);\n }\n },\n [expandTrigger, activePath, expandOption]\n );\n\n const handleColumnsKeyDown = useCallback(\n (event: React.KeyboardEvent): boolean => {\n setKeyboardNav(true);\n const columns = getCascaderColumns(data, activePath);\n const focusedLevel = Math.max(0, activePath.length - 1);\n const currentColumn = columns[focusedLevel] ?? columns[0] ?? [];\n const focusedIndex = currentColumn.findIndex(\n (item) => item.value === activePath[focusedLevel]\n );\n const focusedOption = focusedIndex >= 0 ? currentColumn[focusedIndex] : undefined;\n\n switch (event.key) {\n case 'ArrowDown': {\n const next = findEnabledIndex(currentColumn, focusedIndex, 1);\n if (next >= 0) {\n setActivePath([...activePath.slice(0, focusedLevel), currentColumn[next].value]);\n }\n return true;\n }\n case 'ArrowUp': {\n const from = focusedIndex < 0 ? currentColumn.length : focusedIndex;\n const prev = findEnabledIndex(currentColumn, from, -1);\n if (prev >= 0) {\n setActivePath([...activePath.slice(0, focusedLevel), currentColumn[prev].value]);\n }\n return true;\n }\n case 'ArrowRight': {\n if (focusedOption && cascaderOptionHasChildren(focusedOption)) {\n expandOption(focusedLevel, focusedOption);\n }\n return true;\n }\n case 'ArrowLeft': {\n if (activePath.length > 1) {\n setActivePath(activePath.slice(0, -1));\n }\n return true;\n }\n case 'Enter': {\n if (!focusedOption) {\n return false;\n }\n\n if (cascaderOptionHasChildren(focusedOption)) {\n if (changeOnSelect) {\n selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);\n }\n expandOption(focusedLevel, focusedOption);\n if (changeOnSelect) {\n onLeafSelect?.();\n }\n } else {\n selectPath([...activePath.slice(0, focusedLevel), focusedOption.value]);\n onLeafSelect?.();\n }\n return true;\n }\n default:\n return false;\n }\n },\n [data, activePath, changeOnSelect, selectPath, expandOption, onLeafSelect]\n );\n\n const pathOptions = useMemo(() => getCascaderPathOptions(data, _value), [data, _value]);\n\n return {\n value: _value,\n setValue,\n selectPath,\n activePath,\n setActivePath,\n resetActivePath,\n keyboardNav,\n setKeyboardNav,\n handleOptionClick,\n handleOptionMouseEnter,\n handleColumnsKeyDown,\n pathOptions,\n };\n}\n"],"mappings":"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"}