-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Expand file tree
/
Copy pathuseFlatTree.ts
More file actions
104 lines (94 loc) · 3.57 KB
/
useFlatTree.ts
File metadata and controls
104 lines (94 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
'use client';
import * as React from 'react';
import { useRootTree } from '../../hooks/useRootTree';
import { FlatTreeBaseProps, FlatTreeBaseState, FlatTreeProps, FlatTreeState } from './FlatTree.types';
import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';
import { useFlatTreeNavigation } from '../../hooks/useFlatTreeNavigation';
import { useSubtree } from '../../hooks/useSubtree';
import { ImmutableSet } from '../../utils/ImmutableSet';
import { ImmutableMap } from '../../utils/ImmutableMap';
import { SubtreeContext } from '../../contexts/subtreeContext';
/**
* Create the base state required to render FlatTree, without design-only props.
*
* @param props - props from this instance of FlatTree (without appearance and size)
* @param ref - reference to root HTMLElement of FlatTree
*/
export const useFlatTreeBase_unstable: (props: FlatTreeBaseProps, ref: React.Ref<HTMLElement>) => FlatTreeBaseState = (
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 ? useRootFlatTreeBase(props, ref) : (useSubFlatTree(props as FlatTreeProps, ref) as FlatTreeBaseState);
};
/**
* Create the state required to render FlatTree.
*
* The returned state can be modified with hooks such as useFlatTreeStyles_unstable,
* before being passed to renderFlatTree_unstable.
*
* @param props - props from this instance of FlatTree
* @param ref - reference to root HTMLElement of FlatTree
*/
export const useFlatTree_unstable: (props: FlatTreeProps, ref: React.Ref<HTMLElement>) => FlatTreeState = (
props,
ref,
) => {
'use no memo';
const { appearance = 'subtle', size = 'medium' } = props;
const baseState = useFlatTreeBase_unstable(props, ref);
return { ...baseState, appearance, size } as unknown as FlatTreeState;
};
function useRootFlatTreeBase(props: FlatTreeBaseProps, ref: React.Ref<HTMLElement>): FlatTreeBaseState {
const navigation = useFlatTreeNavigation(props.navigationMode);
const fullState = useRootTree(
{
...props,
onNavigation: useEventCallback((event, data) => {
props.onNavigation?.(event, data);
if (!event.isDefaultPrevented()) {
navigation.navigate(data);
}
}),
},
useMergedRefs(ref, navigation.rootRef),
);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { appearance: _appearance, size: _size, ...baseState } = fullState;
return Object.assign(baseState, {
treeType: 'flat',
forceUpdateRovingTabIndex: navigation.forceUpdateRovingTabIndex,
} as const) as unknown as FlatTreeBaseState;
}
function useSubFlatTree(props: FlatTreeProps, ref: React.Ref<HTMLElement>): FlatTreeState {
if (process.env.NODE_ENV === 'development') {
throw new Error(/* #__DE-INDENT__ */ `
@fluentui/react-tree [useFlatTree]:
Subtrees are not allowed in a FlatTree!
You cannot use a <FlatTree> component inside of another <FlatTree> nor a <Tree> component!
`);
}
return {
...useSubtree(props, ref),
// ------ defaultTreeContextValue
level: 0,
contextType: 'root',
treeType: 'nested',
selectionMode: 'none',
openItems: ImmutableSet.empty,
checkedItems: ImmutableMap.empty,
requestTreeResponse: noop,
forceUpdateRovingTabIndex: noop,
appearance: 'subtle',
size: 'medium',
// ------ defaultTreeContextValue
open: false,
};
}
function noop() {
/* do nothing */
}