/
bearury
/
ui-kit-ce
Обзор
Документация
Войти
/
bearury
/
ui-kit-ce
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
packages/tree/src/hooks/useCheck/useCheck.ts
187 строк
6 KB
Denis Svyatovets
chore: правки prettier
27 июн 2025, 14:46
27 июн 2025, 14:46
e9e0fb5
Код
Авторство
О чём код?
'use client' import * as React from 'react' import { useValue } from '@v-uik/hooks' import { TreeGetters, TreeItem, TreeNodeItem, TreeNodePlain } from '../types' import { getKeys } from './utils' export const TreeCheckMode = { strict: 'strict', affect: 'affect', } as const export type TreeCheckModeType = (typeof TreeCheckMode)[keyof typeof TreeCheckMode] export type UseCheckProps<TItem = TreeItem> = { /** * Функция обратного вызова, которая срабатывает при изменении состояния чекбокса у узла дерева. * * @param {React.Key[]} checkedKeys Массив ключей узлов, для которых будут отмечены чекбоксы. * @param {TreeNodeItem<TItem>} node Целевой узел дерева. * * @returns */ onNodeCheck?: (checkedKeys: React.Key[], node: TreeNodeItem<TItem>) => void /** * Массив ключей узлов, для которых будут отмечены чекбоксы по умолчанию. * * @inner */ defaultCheckedKeys?: React.Key[] /** * Массив ключей узлов, для которых будут отмечены чекбоксы. * * @inner */ checkedKeys?: React.Key[] /** * * @inner */ treePlain: TreeNodePlain<TItem> /** * * @inner */ disabledKeysForCheck: Record<React.Key, boolean> /** * * @returns */ getTreeItemCheckDisabled?: TreeGetters<TItem>['getTreeItemCheckDisabled'] /** * Режим работы отметки чекбокса у узлов дерева, где `strict` - это строгая отметка чекбоксов, а `affect` - режим работы, в котором * при отметке чекбокса, чекбоксы у родительских и дочерних узлов также меняют свое состояние. * * @inner */ checkMode?: TreeCheckModeType } export type UseCheckReturnProps = { /** * Функция для смены состояния чекбокса у узла дерева. * * @param {React.Key} key Ключ узла дерева. * * @returns */ toggleCheck: (key: React.Key) => void /** * Функция для проверки выбора чекбокса у узла дерева. * * @param {React.Key} key Ключ узла дерева. * * @returns Флаг выбранного чекбокса у узла дерева. */ getIsChecked: (key: React.Key) => boolean /** * Функция для проверки неопределенного состояния чекбокса у узла дерева. * * @param {React.Key} key Ключ узла дерева. * * @returns Флаг частично выбранного чекбокса у узла дерева. */ getIsIndeterminate: (key: React.Key) => boolean } const makeFormatValueFromProp = <TItem = TreeItem>( treePlain: TreeNodePlain<TItem>, disabledKeysForCheck: Record<React.Key, boolean>, checkMode: TreeCheckModeType, getTreeItemCheckDisabled?: TreeGetters<TItem>['getTreeItemCheckDisabled'] ) => (keys: React.Key[] = []) => { const checkedKeys: Record<React.Key, boolean> = {} const indeterminateKeys: Record<React.Key, boolean> = {} keys.forEach((key) => { const { keysToCheck, keysToIndeterminate } = getKeys(treePlain, key, { currentCheckedKeys: checkedKeys, currentIndeterminateKeys: indeterminateKeys, disabledKeys: disabledKeysForCheck, targetValue: true, getTreeItemCheckDisabled, checkMode, }) Object.assign(checkedKeys, keysToCheck) Object.assign(indeterminateKeys, keysToIndeterminate) }) Object.keys(indeterminateKeys).forEach((key) => { if (!indeterminateKeys[key] || disabledKeysForCheck[key]) { delete indeterminateKeys[key] } }) return { checkedKeys, indeterminateKeys } } export const useCheck = <TItem = TreeNodeItem>({ checkedKeys: checkedKeysProp, defaultCheckedKeys, onNodeCheck, treePlain, disabledKeysForCheck, getTreeItemCheckDisabled, checkMode = TreeCheckMode.affect, }: UseCheckProps<TItem>): UseCheckReturnProps => { const isControlled = checkedKeysProp !== undefined const [{ checkedKeys, indeterminateKeys }, setKeysState] = useValue( checkedKeysProp || defaultCheckedKeys, { formatValueFromProp: makeFormatValueFromProp<TItem>( treePlain, disabledKeysForCheck, checkMode, getTreeItemCheckDisabled ), useInnerState: !isControlled, } ) const toggleCheck = (key: React.Key) => { let keysToCheck: Record<React.Key, boolean> = {} const keys = getKeys(treePlain, key, { currentCheckedKeys: checkedKeys, currentIndeterminateKeys: indeterminateKeys, disabledKeys: disabledKeysForCheck, getTreeItemCheckDisabled, checkMode, }) keysToCheck = keys.keysToCheck onNodeCheck?.(Object.keys(keysToCheck), treePlain[key]) if (!isControlled) { const keysToIndeterminate = { ...indeterminateKeys } Object.keys(keys.keysToIndeterminate).forEach((key) => { if (keys.keysToIndeterminate[key] && !disabledKeysForCheck[key]) { keysToIndeterminate[key] = keys.keysToIndeterminate[key] } else { delete keysToIndeterminate[key] } }) setKeysState({ checkedKeys: keysToCheck, indeterminateKeys: keysToIndeterminate, }) } } const getIsChecked = (key: React.Key) => !!checkedKeys[key] const getIsIndeterminate = (key: React.Key) => !!indeterminateKeys[key] return { getIsChecked, getIsIndeterminate, toggleCheck, } }