@mui/x-tree-view 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/RichTreeView/RichTreeView.js +4 -4
- package/SimpleTreeView/SimpleTreeView.plugins.d.ts +1 -1
- package/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/TreeItem/TreeItem.js +4 -4
- package/TreeItem/treeItemClasses.d.ts +1 -1
- package/TreeItem/useTreeItemState.js +9 -9
- package/TreeItem2Icon/TreeItem2Icon.types.d.ts +4 -4
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +8 -8
- package/hooks/useTreeViewApiRef.d.ts +1 -1
- package/index.js +1 -1
- package/internals/TreeViewProvider/DescendantProvider.d.ts +1 -1
- package/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/internals/index.d.ts +2 -2
- package/internals/plugins/defaultPlugins.d.ts +3 -3
- package/internals/plugins/defaultPlugins.js +2 -2
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +9 -9
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.types.d.ts +5 -5
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +35 -33
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.types.d.ts +6 -6
- package/internals/plugins/useTreeViewIcons/useTreeViewIcons.types.d.ts +6 -6
- package/internals/plugins/useTreeViewId/useTreeViewId.types.d.ts +1 -1
- package/internals/plugins/useTreeViewItems/index.d.ts +2 -0
- package/internals/plugins/useTreeViewItems/index.js +1 -0
- package/internals/plugins/useTreeViewItems/useTreeViewItems.d.ts +3 -0
- package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +42 -32
- package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.d.ts → useTreeViewItems/useTreeViewItems.types.d.ts} +32 -21
- package/internals/plugins/useTreeViewJSXItems/index.d.ts +2 -0
- package/internals/plugins/useTreeViewJSXItems/index.js +1 -0
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.d.ts +3 -0
- package/{modern/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +26 -25
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.types.d.ts +18 -0
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +40 -44
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.types.d.ts +2 -2
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +34 -34
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +6 -6
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.d.ts +7 -7
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/internals/useTreeView/useTreeView.utils.d.ts +5 -5
- package/internals/useTreeView/useTreeView.utils.js +15 -15
- package/modern/RichTreeView/RichTreeView.js +4 -4
- package/modern/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/modern/TreeItem/TreeItem.js +4 -4
- package/modern/TreeItem/useTreeItemState.js +9 -9
- package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +8 -8
- package/modern/index.js +1 -1
- package/modern/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/modern/internals/plugins/defaultPlugins.js +2 -2
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +9 -9
- package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +35 -33
- package/modern/internals/plugins/useTreeViewItems/index.js +1 -0
- package/modern/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +42 -32
- package/modern/internals/plugins/useTreeViewJSXItems/index.js +1 -0
- package/{internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.js → modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js} +26 -25
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +40 -44
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +34 -34
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/modern/internals/useTreeView/useTreeView.utils.js +15 -15
- package/node/RichTreeView/RichTreeView.js +4 -4
- package/node/SimpleTreeView/SimpleTreeView.plugins.js +2 -2
- package/node/TreeItem/TreeItem.js +4 -4
- package/node/TreeItem/useTreeItemState.js +9 -9
- package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +8 -8
- package/node/index.js +1 -1
- package/node/internals/TreeViewProvider/DescendantProvider.js +1 -1
- package/node/internals/plugins/defaultPlugins.js +2 -2
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +9 -9
- package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +35 -33
- package/node/internals/plugins/useTreeViewItems/index.js +12 -0
- package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.js → useTreeViewItems/useTreeViewItems.js} +44 -34
- package/node/internals/plugins/useTreeViewJSXItems/index.js +12 -0
- package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.js → useTreeViewJSXItems/useTreeViewJSXItems.js} +28 -27
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +39 -43
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +33 -33
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.utils.js +5 -5
- package/node/internals/useTreeView/useTreeView.utils.js +20 -20
- package/package.json +1 -1
- package/useTreeItem2/useTreeItem2.d.ts +1 -1
- package/internals/plugins/useTreeViewJSXNodes/index.d.ts +0 -2
- package/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
- package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.d.ts +0 -3
- package/internals/plugins/useTreeViewJSXNodes/useTreeViewJSXNodes.types.d.ts +0 -18
- package/internals/plugins/useTreeViewNodes/index.d.ts +0 -2
- package/internals/plugins/useTreeViewNodes/index.js +0 -1
- package/internals/plugins/useTreeViewNodes/useTreeViewNodes.d.ts +0 -3
- package/modern/internals/plugins/useTreeViewJSXNodes/index.js +0 -1
- package/modern/internals/plugins/useTreeViewNodes/index.js +0 -1
- package/node/internals/plugins/useTreeViewJSXNodes/index.js +0 -12
- package/node/internals/plugins/useTreeViewNodes/index.js +0 -12
- /package/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
- /package/modern/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/modern/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
- /package/node/internals/plugins/{useTreeViewJSXNodes/useTreeViewJSXNodes.types.js → useTreeViewItems/useTreeViewItems.types.js} +0 -0
- /package/node/internals/plugins/{useTreeViewNodes/useTreeViewNodes.types.js → useTreeViewJSXItems/useTreeViewJSXItems.types.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,77 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 7.1.0
|
|
7
|
+
|
|
8
|
+
_Mar 28, 2024_
|
|
9
|
+
|
|
10
|
+
We'd like to offer a big thanks to the 10 contributors who made this release possible. Here are some highlights ✨:
|
|
11
|
+
|
|
12
|
+
- 🚀 Add `resizeThrottleMs` prop (#12556) @romgrk
|
|
13
|
+
- 🌍 Improve Chinese (Hong Kong) (zh-HK) and Italian (it-IT) locale on the Pickers
|
|
14
|
+
- 🐞 Bugfixes
|
|
15
|
+
- 📚 Documentation improvements
|
|
16
|
+
|
|
17
|
+
### Data Grid
|
|
18
|
+
|
|
19
|
+
#### `@mui/x-data-grid@7.1.0`
|
|
20
|
+
|
|
21
|
+
- [DataGrid] Add `resizeThrottleMs` prop (#12556) @romgrk
|
|
22
|
+
- [DataGrid] Do not publish `rowEditStop` event if row has fields with errors (#11383) @cherniavskii
|
|
23
|
+
- [DataGrid] Fix bug in suspense (#12553) @romgrk
|
|
24
|
+
- [DataGrid] Fix missing class name in the `GridToolbarQuickFilter` component (#12484) @jhawkins11
|
|
25
|
+
|
|
26
|
+
#### `@mui/x-data-grid-pro@7.1.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
27
|
+
|
|
28
|
+
Same changes as in `@mui/x-data-grid@7.1.0`.
|
|
29
|
+
|
|
30
|
+
#### `@mui/x-data-grid-premium@7.1.0` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
31
|
+
|
|
32
|
+
Same changes as in `@mui/x-data-grid-pro@7.1.0`.
|
|
33
|
+
|
|
34
|
+
### Date and Time Pickers
|
|
35
|
+
|
|
36
|
+
#### `@mui/x-date-pickers@7.1.0`
|
|
37
|
+
|
|
38
|
+
- [fields] Fix placeholder override (#12589) @flaviendelangle
|
|
39
|
+
- [l10n] Improve Chinese (Hong Kong) (zh-HK) locale (#12547) @samchiu90
|
|
40
|
+
- [l10n] Improve Italian (it-IT) locale (#12549) @antomanc
|
|
41
|
+
- [pickers] Prepare compatibility with `@mui/zero-runtime` (stop using `ownerState` in `styled`) (#12003) @flaviendelangle
|
|
42
|
+
|
|
43
|
+
#### `@mui/x-date-pickers-pro@7.1.0` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
44
|
+
|
|
45
|
+
Same changes as in `@mui/x-date-pickers@7.1.0`, plus:
|
|
46
|
+
|
|
47
|
+
- [DateRangePicker] Fix selection behavior with single input field when `readOnly` (#12593) @LukasTy
|
|
48
|
+
|
|
49
|
+
### Charts
|
|
50
|
+
|
|
51
|
+
#### `@mui/x-charts@7.1.0`
|
|
52
|
+
|
|
53
|
+
- [charts] Fix tooltip causing crash on data change (#12571) @Rishi556
|
|
54
|
+
|
|
55
|
+
### Tree View
|
|
56
|
+
|
|
57
|
+
#### `@mui/x-tree-view@7.1.0`
|
|
58
|
+
|
|
59
|
+
- [TreeView] Do not use outdated version of the state to compute new label first char in `RichTreeView` (#12512) @flaviendelangle
|
|
60
|
+
|
|
61
|
+
### Docs
|
|
62
|
+
|
|
63
|
+
- [docs] Add example to add a second icon next to the field's opening button (#12524) @flaviendelangle
|
|
64
|
+
- [docs] Add missing note to Data Grid migration guide (#12557) @romgrk
|
|
65
|
+
- [docs] Fix Charts title for SEO (#12545) @oliviertassinari
|
|
66
|
+
- [docs] Fix small typo (#12558) @diogoparente
|
|
67
|
+
- [docs] Improve codemod related documentation (#12582) @MBilalShafi
|
|
68
|
+
- [docs] Reduce noise in migration docs side navigation (#12552) @cherniavskii
|
|
69
|
+
- [docs] Sync static images from core repository (#12525) @LukasTy
|
|
70
|
+
|
|
71
|
+
### Core
|
|
72
|
+
|
|
73
|
+
- [core] Fix `l10n` script on Windows (#12550) @LukasTy
|
|
74
|
+
- [core] Include `DateTimeRangePicker` tag in `releaseChangelog` (#12526) @LukasTy
|
|
75
|
+
- [core] Upgrade monorepo (#12536) @cherniavskii
|
|
76
|
+
|
|
6
77
|
## v7.0.0
|
|
7
78
|
|
|
8
79
|
_Mar 22, 2024_
|
|
@@ -104,8 +104,8 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
|
|
|
104
104
|
getSlotProps: getRootProps,
|
|
105
105
|
ownerState: props
|
|
106
106
|
});
|
|
107
|
-
const
|
|
108
|
-
const
|
|
107
|
+
const itemsToRender = instance.getItemsToRender();
|
|
108
|
+
const renderItem = ({
|
|
109
109
|
label,
|
|
110
110
|
itemId,
|
|
111
111
|
id,
|
|
@@ -117,13 +117,13 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
|
|
|
117
117
|
label: label,
|
|
118
118
|
id: id,
|
|
119
119
|
itemId: itemId,
|
|
120
|
-
children: children?.map(
|
|
120
|
+
children: children?.map(renderItem)
|
|
121
121
|
}, itemId);
|
|
122
122
|
};
|
|
123
123
|
return /*#__PURE__*/_jsx(TreeViewProvider, {
|
|
124
124
|
value: contextValue,
|
|
125
125
|
children: /*#__PURE__*/_jsx(Root, _extends({}, rootProps, {
|
|
126
|
-
children:
|
|
126
|
+
children: itemsToRender.map(renderItem)
|
|
127
127
|
}))
|
|
128
128
|
});
|
|
129
129
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DefaultTreeViewPluginParameters, DefaultTreeViewPluginSlotProps, DefaultTreeViewPluginSlots } from '../internals/plugins/defaultPlugins';
|
|
2
2
|
import { ConvertPluginsIntoSignatures } from '../internals/models';
|
|
3
|
-
export declare const SIMPLE_TREE_VIEW_PLUGINS: readonly [import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewIdSignature>, import("../internals/models").TreeViewPlugin<import("../internals").
|
|
3
|
+
export declare const SIMPLE_TREE_VIEW_PLUGINS: readonly [import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewIdSignature>, import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewItemsSignature>, import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewExpansionSignature>, import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewSelectionSignature>, import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewFocusSignature>, import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewKeyboardNavigationSignature>, import("../internals/models").TreeViewPlugin<import("../internals").UseTreeViewIconsSignature>, import("../internals/models").TreeViewPlugin<import("../internals/plugins/useTreeViewJSXItems").UseTreeViewJSXItemsSignature>];
|
|
4
4
|
export type SimpleTreeViewPlugins = ConvertPluginsIntoSignatures<typeof SIMPLE_TREE_VIEW_PLUGINS>;
|
|
5
5
|
export type SimpleTreeViewPluginSlots = DefaultTreeViewPluginSlots;
|
|
6
6
|
export type SimpleTreeViewPluginSlotProps = DefaultTreeViewPluginSlotProps;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_TREE_VIEW_PLUGINS } from '../internals/plugins/defaultPlugins';
|
|
2
|
-
import {
|
|
3
|
-
export const SIMPLE_TREE_VIEW_PLUGINS = [...DEFAULT_TREE_VIEW_PLUGINS,
|
|
2
|
+
import { useTreeViewJSXItems } from '../internals/plugins/useTreeViewJSXItems';
|
|
3
|
+
export const SIMPLE_TREE_VIEW_PLUGINS = [...DEFAULT_TREE_VIEW_PLUGINS, useTreeViewJSXItems];
|
|
4
4
|
|
|
5
5
|
// We can't infer this type from the plugin, otherwise we would lose the generics.
|
package/TreeItem/TreeItem.js
CHANGED
|
@@ -186,10 +186,10 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
|
|
|
186
186
|
return Boolean(reactChildren);
|
|
187
187
|
};
|
|
188
188
|
const expandable = isExpandable(children);
|
|
189
|
-
const expanded = instance.
|
|
190
|
-
const focused = instance.
|
|
191
|
-
const selected = instance.
|
|
192
|
-
const disabled = instance.
|
|
189
|
+
const expanded = instance.isItemExpanded(itemId);
|
|
190
|
+
const focused = instance.isItemFocused(itemId);
|
|
191
|
+
const selected = instance.isItemSelected(itemId);
|
|
192
|
+
const disabled = instance.isItemDisabled(itemId);
|
|
193
193
|
const ownerState = _extends({}, props, {
|
|
194
194
|
expanded,
|
|
195
195
|
focused,
|
|
@@ -13,7 +13,7 @@ export interface TreeItemClasses {
|
|
|
13
13
|
focused: string;
|
|
14
14
|
/** State class applied to the element when disabled. */
|
|
15
15
|
disabled: string;
|
|
16
|
-
/** Styles applied to the tree
|
|
16
|
+
/** Styles applied to the tree item icon. */
|
|
17
17
|
iconContainer: string;
|
|
18
18
|
/** Styles applied to the label element. */
|
|
19
19
|
label: string;
|
|
@@ -6,11 +6,11 @@ export function useTreeItemState(itemId) {
|
|
|
6
6
|
multiSelect
|
|
7
7
|
}
|
|
8
8
|
} = useTreeViewContext();
|
|
9
|
-
const expandable = instance.
|
|
10
|
-
const expanded = instance.
|
|
11
|
-
const focused = instance.
|
|
12
|
-
const selected = instance.
|
|
13
|
-
const disabled = instance.
|
|
9
|
+
const expandable = instance.isItemExpandable(itemId);
|
|
10
|
+
const expanded = instance.isItemExpanded(itemId);
|
|
11
|
+
const focused = instance.isItemFocused(itemId);
|
|
12
|
+
const selected = instance.isItemSelected(itemId);
|
|
13
|
+
const disabled = instance.isItemDisabled(itemId);
|
|
14
14
|
const handleExpansion = event => {
|
|
15
15
|
if (!disabled) {
|
|
16
16
|
if (!focused) {
|
|
@@ -19,8 +19,8 @@ export function useTreeItemState(itemId) {
|
|
|
19
19
|
const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
|
|
20
20
|
|
|
21
21
|
// If already expanded and trying to toggle selection don't close
|
|
22
|
-
if (expandable && !(multiple && instance.
|
|
23
|
-
instance.
|
|
22
|
+
if (expandable && !(multiple && instance.isItemExpanded(itemId))) {
|
|
23
|
+
instance.toggleItemExpansion(event, itemId);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
};
|
|
@@ -36,10 +36,10 @@ export function useTreeItemState(itemId) {
|
|
|
36
36
|
end: itemId
|
|
37
37
|
});
|
|
38
38
|
} else {
|
|
39
|
-
instance.
|
|
39
|
+
instance.selectItem(event, itemId, true);
|
|
40
40
|
}
|
|
41
41
|
} else {
|
|
42
|
-
instance.
|
|
42
|
+
instance.selectItem(event, itemId);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
};
|
|
@@ -3,19 +3,19 @@ import { SlotComponentProps } from '@mui/base/utils';
|
|
|
3
3
|
import { UseTreeItem2Status } from '../useTreeItem2';
|
|
4
4
|
export interface TreeItem2IconSlots {
|
|
5
5
|
/**
|
|
6
|
-
* The icon used to collapse the
|
|
6
|
+
* The icon used to collapse the item.
|
|
7
7
|
*/
|
|
8
8
|
collapseIcon?: React.ElementType;
|
|
9
9
|
/**
|
|
10
|
-
* The icon used to expand the
|
|
10
|
+
* The icon used to expand the item.
|
|
11
11
|
*/
|
|
12
12
|
expandIcon?: React.ElementType;
|
|
13
13
|
/**
|
|
14
|
-
* The icon displayed next to an end
|
|
14
|
+
* The icon displayed next to an end item.
|
|
15
15
|
*/
|
|
16
16
|
endIcon?: React.ElementType;
|
|
17
17
|
/**
|
|
18
|
-
* The icon to display next to the tree
|
|
18
|
+
* The icon to display next to the tree item's label.
|
|
19
19
|
*/
|
|
20
20
|
icon?: React.ElementType;
|
|
21
21
|
}
|
|
@@ -11,10 +11,10 @@ export const useTreeItem2Utils = ({
|
|
|
11
11
|
} = useTreeViewContext();
|
|
12
12
|
const status = {
|
|
13
13
|
expandable: Boolean(Array.isArray(children) ? children.length : children),
|
|
14
|
-
expanded: instance.
|
|
15
|
-
focused: instance.
|
|
16
|
-
selected: instance.
|
|
17
|
-
disabled: instance.
|
|
14
|
+
expanded: instance.isItemExpanded(itemId),
|
|
15
|
+
focused: instance.isItemFocused(itemId),
|
|
16
|
+
selected: instance.isItemSelected(itemId),
|
|
17
|
+
disabled: instance.isItemDisabled(itemId)
|
|
18
18
|
};
|
|
19
19
|
const handleExpansion = event => {
|
|
20
20
|
if (status.disabled) {
|
|
@@ -26,8 +26,8 @@ export const useTreeItem2Utils = ({
|
|
|
26
26
|
const multiple = multiSelect && (event.shiftKey || event.ctrlKey || event.metaKey);
|
|
27
27
|
|
|
28
28
|
// If already expanded and trying to toggle selection don't close
|
|
29
|
-
if (status.expandable && !(multiple && instance.
|
|
30
|
-
instance.
|
|
29
|
+
if (status.expandable && !(multiple && instance.isItemExpanded(itemId))) {
|
|
30
|
+
instance.toggleItemExpansion(event, itemId);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
const handleSelection = event => {
|
|
@@ -44,10 +44,10 @@ export const useTreeItem2Utils = ({
|
|
|
44
44
|
end: itemId
|
|
45
45
|
});
|
|
46
46
|
} else {
|
|
47
|
-
instance.
|
|
47
|
+
instance.selectItem(event, itemId, true);
|
|
48
48
|
}
|
|
49
49
|
} else {
|
|
50
|
-
instance.
|
|
50
|
+
instance.selectItem(event, itemId);
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
const interactions = {
|
|
@@ -3,4 +3,4 @@ import { TreeViewAnyPluginSignature, TreeViewPublicAPI } from '../internals/mode
|
|
|
3
3
|
/**
|
|
4
4
|
* Hook that instantiates a [[TreeViewApiRef]].
|
|
5
5
|
*/
|
|
6
|
-
export declare const useTreeViewApiRef: <TPlugins extends readonly TreeViewAnyPluginSignature[] = [import("../internals").UseTreeViewIdSignature, import("../internals").
|
|
6
|
+
export declare const useTreeViewApiRef: <TPlugins extends readonly TreeViewAnyPluginSignature[] = [import("../internals").UseTreeViewIdSignature, import("../internals").UseTreeViewItemsSignature, import("../internals").UseTreeViewExpansionSignature, import("../internals").UseTreeViewSelectionSignature, import("../internals").UseTreeViewFocusSignature, import("../internals").UseTreeViewKeyboardNavigationSignature, import("../internals").UseTreeViewIconsSignature]>() => React.MutableRefObject<TreeViewPublicAPI<TPlugins> | undefined>;
|
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as React from 'react';
|
|
|
5
5
|
* We use this for focus management, keyboard navigation, and typeahead
|
|
6
6
|
* functionality for some components.
|
|
7
7
|
*
|
|
8
|
-
* The hook accepts the element
|
|
8
|
+
* The hook accepts the element item
|
|
9
9
|
*
|
|
10
10
|
* Our main goals with this are:
|
|
11
11
|
* 1) maximum composability,
|
|
@@ -46,7 +46,7 @@ const noop = () => {};
|
|
|
46
46
|
* We use this for focus management, keyboard navigation, and typeahead
|
|
47
47
|
* functionality for some components.
|
|
48
48
|
*
|
|
49
|
-
* The hook accepts the element
|
|
49
|
+
* The hook accepts the element item
|
|
50
50
|
*
|
|
51
51
|
* Our main goals with this are:
|
|
52
52
|
* 1) maximum composability,
|
package/internals/index.d.ts
CHANGED
|
@@ -10,6 +10,6 @@ export type { UseTreeViewFocusSignature } from './plugins/useTreeViewFocus';
|
|
|
10
10
|
export type { UseTreeViewKeyboardNavigationSignature } from './plugins/useTreeViewKeyboardNavigation';
|
|
11
11
|
export type { UseTreeViewIdSignature } from './plugins/useTreeViewId';
|
|
12
12
|
export type { UseTreeViewIconsSignature } from './plugins/useTreeViewIcons';
|
|
13
|
-
export type {
|
|
14
|
-
export type {
|
|
13
|
+
export type { UseTreeViewItemsSignature } from './plugins/useTreeViewItems';
|
|
14
|
+
export type { UseTreeViewJSXItemsSignature } from './plugins/useTreeViewJSXItems';
|
|
15
15
|
export { extractPluginParamsFromProps } from './utils/extractPluginParamsFromProps';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { UseTreeViewIdParameters } from './useTreeViewId';
|
|
2
|
-
import {
|
|
2
|
+
import { UseTreeViewItemsParameters } from './useTreeViewItems';
|
|
3
3
|
import { UseTreeViewExpansionParameters } from './useTreeViewExpansion';
|
|
4
4
|
import { UseTreeViewSelectionParameters } from './useTreeViewSelection';
|
|
5
5
|
import { UseTreeViewFocusParameters } from './useTreeViewFocus';
|
|
6
6
|
import { UseTreeViewIconsParameters } from './useTreeViewIcons';
|
|
7
7
|
import { ConvertPluginsIntoSignatures, MergePluginsProperty } from '../models';
|
|
8
|
-
export declare const DEFAULT_TREE_VIEW_PLUGINS: readonly [import("../models").TreeViewPlugin<import("./useTreeViewId").UseTreeViewIdSignature>, import("../models").TreeViewPlugin<import("./
|
|
8
|
+
export declare const DEFAULT_TREE_VIEW_PLUGINS: readonly [import("../models").TreeViewPlugin<import("./useTreeViewId").UseTreeViewIdSignature>, import("../models").TreeViewPlugin<import("./useTreeViewItems").UseTreeViewItemsSignature>, import("../models").TreeViewPlugin<import("./useTreeViewExpansion").UseTreeViewExpansionSignature>, import("../models").TreeViewPlugin<import("./useTreeViewSelection").UseTreeViewSelectionSignature>, import("../models").TreeViewPlugin<import("./useTreeViewFocus").UseTreeViewFocusSignature>, import("../models").TreeViewPlugin<import("./useTreeViewKeyboardNavigation").UseTreeViewKeyboardNavigationSignature>, import("../models").TreeViewPlugin<import("./useTreeViewIcons").UseTreeViewIconsSignature>];
|
|
9
9
|
export type DefaultTreeViewPlugins = ConvertPluginsIntoSignatures<typeof DEFAULT_TREE_VIEW_PLUGINS>;
|
|
10
10
|
export type DefaultTreeViewPluginSlots = MergePluginsProperty<DefaultTreeViewPlugins, 'slots'>;
|
|
11
11
|
export type DefaultTreeViewPluginSlotProps = MergePluginsProperty<DefaultTreeViewPlugins, 'slotProps'>;
|
|
12
|
-
export interface DefaultTreeViewPluginParameters<R extends {}, Multiple extends boolean | undefined> extends UseTreeViewIdParameters,
|
|
12
|
+
export interface DefaultTreeViewPluginParameters<R extends {}, Multiple extends boolean | undefined> extends UseTreeViewIdParameters, UseTreeViewItemsParameters<R>, UseTreeViewExpansionParameters, UseTreeViewFocusParameters, UseTreeViewSelectionParameters<Multiple>, UseTreeViewIconsParameters {
|
|
13
13
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useTreeViewId } from './useTreeViewId';
|
|
2
|
-
import {
|
|
2
|
+
import { useTreeViewItems } from './useTreeViewItems';
|
|
3
3
|
import { useTreeViewExpansion } from './useTreeViewExpansion';
|
|
4
4
|
import { useTreeViewSelection } from './useTreeViewSelection';
|
|
5
5
|
import { useTreeViewFocus } from './useTreeViewFocus';
|
|
6
6
|
import { useTreeViewKeyboardNavigation } from './useTreeViewKeyboardNavigation';
|
|
7
7
|
import { useTreeViewIcons } from './useTreeViewIcons';
|
|
8
|
-
export const DEFAULT_TREE_VIEW_PLUGINS = [useTreeViewId,
|
|
8
|
+
export const DEFAULT_TREE_VIEW_PLUGINS = [useTreeViewId, useTreeViewItems, useTreeViewExpansion, useTreeViewSelection, useTreeViewFocus, useTreeViewKeyboardNavigation, useTreeViewIcons];
|
|
9
9
|
|
|
10
10
|
// We can't infer this type from the plugin, otherwise we would lose the generics.
|
|
@@ -11,11 +11,11 @@ export const useTreeViewExpansion = ({
|
|
|
11
11
|
params.onExpandedItemsChange?.(event, value);
|
|
12
12
|
models.expandedItems.setControlledValue(value);
|
|
13
13
|
};
|
|
14
|
-
const
|
|
14
|
+
const isItemExpanded = React.useCallback(itemId => {
|
|
15
15
|
return Array.isArray(models.expandedItems.value) ? models.expandedItems.value.indexOf(itemId) !== -1 : false;
|
|
16
16
|
}, [models.expandedItems.value]);
|
|
17
|
-
const
|
|
18
|
-
const
|
|
17
|
+
const isItemExpandable = React.useCallback(itemId => !!instance.getNode(itemId)?.expandable, [instance]);
|
|
18
|
+
const toggleItemExpansion = useEventCallback((event, itemId) => {
|
|
19
19
|
if (itemId == null) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
@@ -34,7 +34,7 @@ export const useTreeViewExpansion = ({
|
|
|
34
34
|
const expandAllSiblings = (event, itemId) => {
|
|
35
35
|
const node = instance.getNode(itemId);
|
|
36
36
|
const siblings = instance.getChildrenIds(node.parentId);
|
|
37
|
-
const diff = siblings.filter(child => instance.
|
|
37
|
+
const diff = siblings.filter(child => instance.isItemExpandable(child) && !instance.isItemExpanded(child));
|
|
38
38
|
const newExpanded = models.expandedItems.value.concat(diff);
|
|
39
39
|
if (diff.length > 0) {
|
|
40
40
|
if (params.onItemExpansionToggle) {
|
|
@@ -46,9 +46,9 @@ export const useTreeViewExpansion = ({
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
populateInstance(instance, {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
isItemExpanded,
|
|
50
|
+
isItemExpandable,
|
|
51
|
+
toggleItemExpansion,
|
|
52
52
|
expandAllSiblings
|
|
53
53
|
});
|
|
54
54
|
};
|
|
@@ -57,9 +57,9 @@ useTreeViewExpansion.models = {
|
|
|
57
57
|
getDefaultValue: params => params.defaultExpandedItems
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
|
-
const
|
|
60
|
+
const DEFAULT_EXPANDED_ITEMS = [];
|
|
61
61
|
useTreeViewExpansion.getDefaultizedParams = params => _extends({}, params, {
|
|
62
|
-
defaultExpandedItems: params.defaultExpandedItems ??
|
|
62
|
+
defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS
|
|
63
63
|
});
|
|
64
64
|
useTreeViewExpansion.params = {
|
|
65
65
|
expandedItems: true,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { DefaultizedProps, TreeViewPluginSignature } from '../../models';
|
|
3
|
-
import {
|
|
3
|
+
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
4
4
|
export interface UseTreeViewExpansionInstance {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
isItemExpanded: (itemId: string) => boolean;
|
|
6
|
+
isItemExpandable: (itemId: string) => boolean;
|
|
7
|
+
toggleItemExpansion: (event: React.SyntheticEvent, value: string) => void;
|
|
8
8
|
expandAllSiblings: (event: React.KeyboardEvent, itemId: string) => void;
|
|
9
9
|
}
|
|
10
10
|
export interface UseTreeViewExpansionParameters {
|
|
@@ -39,5 +39,5 @@ export type UseTreeViewExpansionSignature = TreeViewPluginSignature<{
|
|
|
39
39
|
defaultizedParams: UseTreeViewExpansionDefaultizedParameters;
|
|
40
40
|
instance: UseTreeViewExpansionInstance;
|
|
41
41
|
modelNames: 'expandedItems';
|
|
42
|
-
dependantPlugins: [
|
|
42
|
+
dependantPlugins: [UseTreeViewItemsSignature];
|
|
43
43
|
}>;
|
|
@@ -8,7 +8,7 @@ import { getActiveElement } from '../../utils/utils';
|
|
|
8
8
|
const useTabbableItemId = (instance, selectedItems) => {
|
|
9
9
|
const isItemVisible = itemId => {
|
|
10
10
|
const node = instance.getNode(itemId);
|
|
11
|
-
return node && (node.parentId == null || instance.
|
|
11
|
+
return node && (node.parentId == null || instance.isItemExpanded(node.parentId));
|
|
12
12
|
};
|
|
13
13
|
let tabbableItemId;
|
|
14
14
|
if (Array.isArray(selectedItems)) {
|
|
@@ -32,18 +32,18 @@ export const useTreeViewFocus = ({
|
|
|
32
32
|
}) => {
|
|
33
33
|
const tabbableItemId = useTabbableItemId(instance, models.selectedItems.value);
|
|
34
34
|
const setFocusedItemId = useEventCallback(itemId => {
|
|
35
|
-
const cleanItemId = typeof itemId === 'function' ? itemId(state.
|
|
36
|
-
if (state.
|
|
35
|
+
const cleanItemId = typeof itemId === 'function' ? itemId(state.focusedItemId) : itemId;
|
|
36
|
+
if (state.focusedItemId !== cleanItemId) {
|
|
37
37
|
setState(prevState => _extends({}, prevState, {
|
|
38
|
-
|
|
38
|
+
focusedItemId: cleanItemId
|
|
39
39
|
}));
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
const isTreeViewFocused = React.useCallback(() => !!rootRef.current && rootRef.current.contains(getActiveElement(ownerDocument(rootRef.current))), [rootRef]);
|
|
43
|
-
const
|
|
44
|
-
const
|
|
43
|
+
const isItemFocused = React.useCallback(itemId => state.focusedItemId === itemId && isTreeViewFocused(), [state.focusedItemId, isTreeViewFocused]);
|
|
44
|
+
const isItemVisible = itemId => {
|
|
45
45
|
const node = instance.getNode(itemId);
|
|
46
|
-
return node && (node.parentId == null || instance.
|
|
46
|
+
return node && (node.parentId == null || instance.isItemExpanded(node.parentId));
|
|
47
47
|
};
|
|
48
48
|
const innerFocusItem = (event, itemId) => {
|
|
49
49
|
const node = instance.getNode(itemId);
|
|
@@ -56,62 +56,64 @@ export const useTreeViewFocus = ({
|
|
|
56
56
|
params.onItemFocus(event, itemId);
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
-
const focusItem = useEventCallback((event,
|
|
60
|
-
// If we receive
|
|
61
|
-
if (
|
|
62
|
-
innerFocusItem(event,
|
|
59
|
+
const focusItem = useEventCallback((event, itemId) => {
|
|
60
|
+
// If we receive an itemId, and it is visible, the focus will be set to it
|
|
61
|
+
if (isItemVisible(itemId)) {
|
|
62
|
+
innerFocusItem(event, itemId);
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
|
-
const
|
|
66
|
-
let
|
|
65
|
+
const focusDefaultItem = useEventCallback(event => {
|
|
66
|
+
let itemToFocusId;
|
|
67
67
|
if (Array.isArray(models.selectedItems.value)) {
|
|
68
|
-
|
|
69
|
-
} else if (models.selectedItems.value != null &&
|
|
70
|
-
|
|
68
|
+
itemToFocusId = models.selectedItems.value.find(isItemVisible);
|
|
69
|
+
} else if (models.selectedItems.value != null && isItemVisible(models.selectedItems.value)) {
|
|
70
|
+
itemToFocusId = models.selectedItems.value;
|
|
71
71
|
}
|
|
72
|
-
if (
|
|
73
|
-
|
|
72
|
+
if (itemToFocusId == null) {
|
|
73
|
+
itemToFocusId = instance.getNavigableChildrenIds(null)[0];
|
|
74
74
|
}
|
|
75
|
-
innerFocusItem(event,
|
|
75
|
+
innerFocusItem(event, itemToFocusId);
|
|
76
76
|
});
|
|
77
77
|
const removeFocusedItem = useEventCallback(() => {
|
|
78
|
-
if (state.
|
|
78
|
+
if (state.focusedItemId == null) {
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
|
-
const node = instance.getNode(state.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
itemElement
|
|
81
|
+
const node = instance.getNode(state.focusedItemId);
|
|
82
|
+
if (node) {
|
|
83
|
+
const itemElement = document.getElementById(instance.getTreeItemId(state.focusedItemId, node.idAttribute));
|
|
84
|
+
if (itemElement) {
|
|
85
|
+
itemElement.blur();
|
|
86
|
+
}
|
|
85
87
|
}
|
|
86
88
|
setFocusedItemId(null);
|
|
87
89
|
});
|
|
88
90
|
const canItemBeTabbed = itemId => itemId === tabbableItemId;
|
|
89
91
|
populateInstance(instance, {
|
|
90
|
-
|
|
92
|
+
isItemFocused,
|
|
91
93
|
canItemBeTabbed,
|
|
92
94
|
focusItem,
|
|
93
|
-
|
|
95
|
+
focusDefaultItem,
|
|
94
96
|
removeFocusedItem
|
|
95
97
|
});
|
|
96
98
|
populatePublicAPI(publicAPI, {
|
|
97
99
|
focusItem
|
|
98
100
|
});
|
|
99
|
-
useInstanceEventHandler(instance, '
|
|
101
|
+
useInstanceEventHandler(instance, 'removeItem', ({
|
|
100
102
|
id
|
|
101
103
|
}) => {
|
|
102
|
-
if (state.
|
|
103
|
-
instance.
|
|
104
|
+
if (state.focusedItemId === id) {
|
|
105
|
+
instance.focusDefaultItem(null);
|
|
104
106
|
}
|
|
105
107
|
});
|
|
106
108
|
const createHandleFocus = otherHandlers => event => {
|
|
107
109
|
otherHandlers.onFocus?.(event);
|
|
108
110
|
// if the event bubbled (which is React specific) we don't want to steal focus
|
|
109
111
|
if (event.target === event.currentTarget) {
|
|
110
|
-
instance.
|
|
112
|
+
instance.focusDefaultItem(event);
|
|
111
113
|
}
|
|
112
114
|
};
|
|
113
|
-
const
|
|
114
|
-
const activeDescendant =
|
|
115
|
+
const focusedItem = instance.getNode(state.focusedItemId);
|
|
116
|
+
const activeDescendant = focusedItem ? instance.getTreeItemId(focusedItem.id, focusedItem.idAttribute) : null;
|
|
115
117
|
return {
|
|
116
118
|
getRootProps: otherHandlers => ({
|
|
117
119
|
onFocus: createHandleFocus(otherHandlers),
|
|
@@ -120,7 +122,7 @@ export const useTreeViewFocus = ({
|
|
|
120
122
|
};
|
|
121
123
|
};
|
|
122
124
|
useTreeViewFocus.getInitialState = () => ({
|
|
123
|
-
|
|
125
|
+
focusedItemId: null
|
|
124
126
|
});
|
|
125
127
|
useTreeViewFocus.params = {
|
|
126
128
|
onItemFocus: true
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { TreeViewPluginSignature } from '../../models';
|
|
3
3
|
import { UseTreeViewIdSignature } from '../useTreeViewId/useTreeViewId.types';
|
|
4
|
-
import type {
|
|
4
|
+
import type { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
5
5
|
import type { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
|
|
6
6
|
import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
|
|
7
7
|
export interface UseTreeViewFocusInstance {
|
|
8
|
-
|
|
8
|
+
isItemFocused: (itemId: string) => boolean;
|
|
9
9
|
canItemBeTabbed: (itemId: string) => boolean;
|
|
10
|
-
focusItem: (event: React.SyntheticEvent,
|
|
11
|
-
|
|
10
|
+
focusItem: (event: React.SyntheticEvent, itemId: string) => void;
|
|
11
|
+
focusDefaultItem: (event: React.SyntheticEvent | null) => void;
|
|
12
12
|
removeFocusedItem: () => void;
|
|
13
13
|
}
|
|
14
14
|
export interface UseTreeViewFocusPublicAPI extends Pick<UseTreeViewFocusInstance, 'focusItem'> {
|
|
@@ -24,7 +24,7 @@ export interface UseTreeViewFocusParameters {
|
|
|
24
24
|
}
|
|
25
25
|
export type UseTreeViewFocusDefaultizedParameters = UseTreeViewFocusParameters;
|
|
26
26
|
export interface UseTreeViewFocusState {
|
|
27
|
-
|
|
27
|
+
focusedItemId: string | null;
|
|
28
28
|
}
|
|
29
29
|
export type UseTreeViewFocusSignature = TreeViewPluginSignature<{
|
|
30
30
|
params: UseTreeViewFocusParameters;
|
|
@@ -34,7 +34,7 @@ export type UseTreeViewFocusSignature = TreeViewPluginSignature<{
|
|
|
34
34
|
state: UseTreeViewFocusState;
|
|
35
35
|
dependantPlugins: [
|
|
36
36
|
UseTreeViewIdSignature,
|
|
37
|
-
|
|
37
|
+
UseTreeViewItemsSignature,
|
|
38
38
|
UseTreeViewSelectionSignature,
|
|
39
39
|
UseTreeViewExpansionSignature
|
|
40
40
|
];
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { SlotComponentProps } from '@mui/base/utils';
|
|
3
3
|
import { TreeViewPluginSignature } from '../../models';
|
|
4
|
-
import {
|
|
4
|
+
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
5
5
|
import { UseTreeViewSelectionSignature } from '../useTreeViewSelection';
|
|
6
6
|
export interface UseTreeViewIconsParameters {
|
|
7
7
|
}
|
|
8
8
|
export type UseTreeViewIconsDefaultizedParameters = UseTreeViewIconsParameters;
|
|
9
9
|
interface UseTreeViewIconsSlots {
|
|
10
10
|
/**
|
|
11
|
-
* The default icon used to collapse the
|
|
11
|
+
* The default icon used to collapse the item.
|
|
12
12
|
*/
|
|
13
13
|
collapseIcon?: React.ElementType;
|
|
14
14
|
/**
|
|
15
|
-
* The default icon used to expand the
|
|
15
|
+
* The default icon used to expand the item.
|
|
16
16
|
*/
|
|
17
17
|
expandIcon?: React.ElementType;
|
|
18
18
|
/**
|
|
19
|
-
* The default icon displayed next to an end
|
|
20
|
-
* This is applied to all tree
|
|
19
|
+
* The default icon displayed next to an end item.
|
|
20
|
+
* This is applied to all tree items and can be overridden by the TreeItem `icon` slot prop.
|
|
21
21
|
*/
|
|
22
22
|
endIcon?: React.ElementType;
|
|
23
23
|
}
|
|
@@ -38,6 +38,6 @@ export type UseTreeViewIconsSignature = TreeViewPluginSignature<{
|
|
|
38
38
|
contextValue: UseTreeViewIconsContextValue;
|
|
39
39
|
slots: UseTreeViewIconsSlots;
|
|
40
40
|
slotProps: UseTreeViewIconsSlotProps;
|
|
41
|
-
dependantPlugins: [
|
|
41
|
+
dependantPlugins: [UseTreeViewItemsSignature, UseTreeViewSelectionSignature];
|
|
42
42
|
}>;
|
|
43
43
|
export {};
|
|
@@ -11,7 +11,7 @@ export interface UseTreeViewIdParameters {
|
|
|
11
11
|
}
|
|
12
12
|
export type UseTreeViewIdDefaultizedParameters = UseTreeViewIdParameters;
|
|
13
13
|
export interface UseTreeViewIdState {
|
|
14
|
-
|
|
14
|
+
focusedItemId: string | null;
|
|
15
15
|
}
|
|
16
16
|
export type UseTreeViewIdSignature = TreeViewPluginSignature<{
|
|
17
17
|
params: UseTreeViewIdParameters;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useTreeViewItems } from './useTreeViewItems';
|