'use client'; import * as React from 'react'; import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities'; import { createNextOpenItems, useControllableOpenItems } from '../../hooks/useControllableOpenItems'; import { createNextNestedCheckedItems, useNestedCheckedItems } from './useNestedControllableCheckedItems'; import { SubtreeContext } from '../../contexts/subtreeContext'; import { useRootTree } from '../../hooks/useRootTree'; import { useSubtree } from '../../hooks/useSubtree'; import { useTreeNavigation } from '../../hooks/useTreeNavigation'; import { useTreeContext_unstable } from '../../contexts/treeContext'; import { ImmutableSet } from '../../utils/ImmutableSet'; import { ImmutableMap } from '../../utils/ImmutableMap'; export const useTree_unstable = (props, ref)=>{ 'use no memo'; const isRoot = React.useContext(SubtreeContext) === undefined; // as level is static, this doesn't break rule of hooks // and if this becomes an issue later on, this can be easily converted // eslint-disable-next-line react-hooks/rules-of-hooks return isRoot ? useNestedRootTree(props, ref) : useNestedSubtree(props, ref); }; function useNestedRootTree(props, ref) { 'use no memo'; const [openItems, setOpenItems] = useControllableOpenItems(props); const checkedItems = useNestedCheckedItems(props); const navigation = useTreeNavigation(props.navigationMode); return Object.assign(useRootTree({ ...props, openItems, checkedItems, onOpenChange: useEventCallback((event, data)=>{ var _props_onOpenChange; const nextOpenItems = createNextOpenItems(data, openItems); (_props_onOpenChange = props.onOpenChange) === null || _props_onOpenChange === void 0 ? void 0 : _props_onOpenChange.call(props, event, { ...data, openItems: ImmutableSet.dangerouslyGetInternalSet(nextOpenItems) }); setOpenItems(nextOpenItems); }), onNavigation: useEventCallback((event, data)=>{ var _props_onNavigation; (_props_onNavigation = props.onNavigation) === null || _props_onNavigation === void 0 ? void 0 : _props_onNavigation.call(props, event, data); if (!event.isDefaultPrevented()) { navigation.navigate(data, { preventScroll: data.isScrollPrevented() }); } }), onCheckedChange: useEventCallback((event, data)=>{ var _props_onCheckedChange; const nextCheckedItems = createNextNestedCheckedItems(data, checkedItems); (_props_onCheckedChange = props.onCheckedChange) === null || _props_onCheckedChange === void 0 ? void 0 : _props_onCheckedChange.call(props, event, { ...data, checkedItems: ImmutableMap.dangerouslyGetInternalMap(nextCheckedItems) }); }) }, useMergedRefs(ref, navigation.treeRef)), { treeType: 'nested', forceUpdateRovingTabIndex: navigation.forceUpdateRovingTabIndex }); } function useNestedSubtree(props, ref) { 'use no memo'; if (process.env.NODE_ENV === 'development') { // this doesn't break rule of hooks, as environment is a static value // eslint-disable-next-line react-hooks/rules-of-hooks const treeType = useTreeContext_unstable((ctx)=>ctx.treeType); if (treeType === 'flat') { throw new Error(`@fluentui/react-tree [useTree]: Subtrees are not allowed in a FlatTree! You cannot use a component inside of a component!`); } } return useSubtree(props, ref); }