@mui/x-tree-view 7.4.0 → 7.5.1
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 +132 -5395
- package/RichTreeView/RichTreeView.js +7 -2
- package/SimpleTreeView/SimpleTreeView.js +7 -2
- package/TreeItem/TreeItem.js +8 -3
- package/TreeItem/TreeItemContent.d.ts +2 -0
- package/TreeItem/TreeItemContent.js +19 -2
- package/TreeItem/treeItemClasses.d.ts +2 -0
- package/TreeItem/treeItemClasses.js +1 -1
- package/TreeItem/useTreeItemState.d.ts +4 -1
- package/TreeItem/useTreeItemState.js +18 -2
- package/TreeItem2/TreeItem2.d.ts +4 -0
- package/TreeItem2/TreeItem2.js +34 -4
- package/TreeItem2/TreeItem2.types.d.ts +6 -0
- package/TreeItem2/index.d.ts +1 -1
- package/TreeItem2/index.js +1 -1
- package/TreeItem2Icon/TreeItem2Icon.js +1 -1
- package/TreeItem2Provider/TreeItem2Provider.js +1 -1
- package/TreeView/TreeView.js +7 -2
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +1 -0
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +18 -3
- package/index.js +1 -1
- package/internals/models/plugin.d.ts +0 -6
- package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +1 -0
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +3 -3
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +18 -6
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.types.d.ts +16 -4
- package/internals/useTreeView/useTreeViewModels.d.ts +1 -1
- package/internals/useTreeView/useTreeViewModels.js +1 -1
- package/modern/RichTreeView/RichTreeView.js +7 -2
- package/modern/SimpleTreeView/SimpleTreeView.js +7 -2
- package/modern/TreeItem/TreeItem.js +8 -3
- package/modern/TreeItem/TreeItemContent.js +19 -2
- package/modern/TreeItem/treeItemClasses.js +1 -1
- package/modern/TreeItem/useTreeItemState.js +18 -2
- package/modern/TreeItem2/TreeItem2.js +34 -4
- package/modern/TreeItem2/index.js +1 -1
- package/modern/TreeItem2Icon/TreeItem2Icon.js +1 -1
- package/modern/TreeItem2Provider/TreeItem2Provider.js +1 -1
- package/modern/TreeView/TreeView.js +7 -2
- package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +18 -3
- package/modern/index.js +1 -1
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +3 -3
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +18 -6
- package/modern/internals/useTreeView/useTreeViewModels.js +1 -1
- package/modern/useTreeItem2/useTreeItem2.js +32 -3
- package/node/RichTreeView/RichTreeView.js +7 -2
- package/node/SimpleTreeView/SimpleTreeView.js +7 -2
- package/node/TreeItem/TreeItem.js +8 -3
- package/node/TreeItem/TreeItemContent.js +19 -2
- package/node/TreeItem/treeItemClasses.js +1 -1
- package/node/TreeItem/useTreeItemState.js +18 -2
- package/node/TreeItem2/TreeItem2.js +35 -5
- package/node/TreeItem2/index.js +6 -0
- package/node/TreeItem2Icon/TreeItem2Icon.js +1 -1
- package/node/TreeItem2Provider/TreeItem2Provider.js +1 -1
- package/node/TreeView/TreeView.js +7 -2
- package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +18 -3
- package/node/index.js +1 -1
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +3 -3
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +18 -6
- package/node/internals/useTreeView/useTreeViewModels.js +1 -1
- package/node/useTreeItem2/useTreeItem2.js +34 -3
- package/package.json +2 -2
- package/useTreeItem2/useTreeItem2.js +32 -3
- package/useTreeItem2/useTreeItem2.types.d.ts +15 -0
|
@@ -4,7 +4,14 @@ import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
|
4
4
|
import { UseTreeViewExpansionSignature } from '../useTreeViewExpansion';
|
|
5
5
|
export interface UseTreeViewSelectionInstance {
|
|
6
6
|
isItemSelected: (itemId: string) => boolean;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Select or deselect an item.
|
|
9
|
+
* @param {React.SyntheticEvent} event The event source of the callback.
|
|
10
|
+
* @param {string} itemId The id of the item to select or deselect.
|
|
11
|
+
* @param {boolean} keepExistingSelection If `true`, don't remove the other selected items.
|
|
12
|
+
* @param {boolean | undefined} newValue The new selection status of the item. If not defined, the new state will be the opposite of the current state.
|
|
13
|
+
*/
|
|
14
|
+
selectItem: (event: React.SyntheticEvent, itemId: string, keepExistingSelection: boolean, newValue?: boolean) => void;
|
|
8
15
|
/**
|
|
9
16
|
* Select all the navigable items in the tree.
|
|
10
17
|
* @param {React.SyntheticEvent} event The event source of the callback.
|
|
@@ -55,10 +62,15 @@ export interface UseTreeViewSelectionParameters<Multiple extends boolean | undef
|
|
|
55
62
|
*/
|
|
56
63
|
selectedItems?: TreeViewSelectionValue<Multiple>;
|
|
57
64
|
/**
|
|
58
|
-
* If true `ctrl` and `shift` will trigger multiselect.
|
|
65
|
+
* If `true`, `ctrl` and `shift` will trigger multiselect.
|
|
59
66
|
* @default false
|
|
60
67
|
*/
|
|
61
68
|
multiSelect?: Multiple;
|
|
69
|
+
/**
|
|
70
|
+
* If `true`, the tree view renders a checkbox at the left of its label that allows selecting it.
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
checkboxSelection?: boolean;
|
|
62
74
|
/**
|
|
63
75
|
* Callback fired when tree items are selected/deselected.
|
|
64
76
|
* @param {React.SyntheticEvent} event The event source of the callback
|
|
@@ -74,9 +86,9 @@ export interface UseTreeViewSelectionParameters<Multiple extends boolean | undef
|
|
|
74
86
|
*/
|
|
75
87
|
onItemSelectionToggle?: (event: React.SyntheticEvent, itemId: string, isSelected: boolean) => void;
|
|
76
88
|
}
|
|
77
|
-
export type UseTreeViewSelectionDefaultizedParameters<Multiple extends boolean> = DefaultizedProps<UseTreeViewSelectionParameters<Multiple>, 'disableSelection' | 'defaultSelectedItems' | 'multiSelect'>;
|
|
89
|
+
export type UseTreeViewSelectionDefaultizedParameters<Multiple extends boolean> = DefaultizedProps<UseTreeViewSelectionParameters<Multiple>, 'disableSelection' | 'defaultSelectedItems' | 'multiSelect' | 'checkboxSelection'>;
|
|
78
90
|
interface UseTreeViewSelectionContextValue {
|
|
79
|
-
selection: Pick<UseTreeViewSelectionDefaultizedParameters<boolean>, 'multiSelect'>;
|
|
91
|
+
selection: Pick<UseTreeViewSelectionDefaultizedParameters<boolean>, 'multiSelect' | 'checkboxSelection' | 'disableSelection'>;
|
|
80
92
|
}
|
|
81
93
|
export type UseTreeViewSelectionSignature = TreeViewPluginSignature<{
|
|
82
94
|
params: UseTreeViewSelectionParameters<any>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TreeViewAnyPluginSignature, TreeViewPlugin, ConvertPluginsIntoSignatures, MergePluginsProperty } from '../models';
|
|
2
2
|
/**
|
|
3
3
|
* Implements the same behavior as `useControlled` but for several models.
|
|
4
|
-
* The controlled models are never stored in the state and the state is only updated if the model is not controlled.
|
|
4
|
+
* The controlled models are never stored in the state, and the state is only updated if the model is not controlled.
|
|
5
5
|
*/
|
|
6
6
|
export declare const useTreeViewModels: <TPlugins extends readonly TreeViewPlugin<TreeViewAnyPluginSignature>[]>(plugins: TPlugins, props: MergePluginsProperty<ConvertPluginsIntoSignatures<TPlugins>, 'defaultizedParams'>) => MergePluginsProperty<ConvertPluginsIntoSignatures<TPlugins>, "models">;
|
|
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
/**
|
|
4
4
|
* Implements the same behavior as `useControlled` but for several models.
|
|
5
|
-
* The controlled models are never stored in the state and the state is only updated if the model is not controlled.
|
|
5
|
+
* The controlled models are never stored in the state, and the state is only updated if the model is not controlled.
|
|
6
6
|
*/
|
|
7
7
|
export const useTreeViewModels = (plugins, props) => {
|
|
8
8
|
const modelsRef = React.useRef({});
|
|
@@ -131,7 +131,7 @@ const RichTreeView = /*#__PURE__*/React.forwardRef(function RichTreeView(inProps
|
|
|
131
131
|
process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
132
132
|
// ----------------------------- Warning --------------------------------
|
|
133
133
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
134
|
-
// | To update them edit the TypeScript types and run "
|
|
134
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
135
135
|
// ----------------------------------------------------------------------
|
|
136
136
|
/**
|
|
137
137
|
* The ref object that allows Tree View manipulation. Can be instantiated with `useTreeViewApiRef()`.
|
|
@@ -143,6 +143,11 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
|
143
143
|
setItemExpansion: PropTypes.func.isRequired
|
|
144
144
|
})
|
|
145
145
|
}),
|
|
146
|
+
/**
|
|
147
|
+
* If `true`, the tree view renders a checkbox at the left of its label that allows selecting it.
|
|
148
|
+
* @default false
|
|
149
|
+
*/
|
|
150
|
+
checkboxSelection: PropTypes.bool,
|
|
146
151
|
/**
|
|
147
152
|
* Override or extend the styles applied to the component.
|
|
148
153
|
*/
|
|
@@ -207,7 +212,7 @@ process.env.NODE_ENV !== "production" ? RichTreeView.propTypes = {
|
|
|
207
212
|
isItemDisabled: PropTypes.func,
|
|
208
213
|
items: PropTypes.array.isRequired,
|
|
209
214
|
/**
|
|
210
|
-
* If true `ctrl` and `shift` will trigger multiselect.
|
|
215
|
+
* If `true`, `ctrl` and `shift` will trigger multiselect.
|
|
211
216
|
* @default false
|
|
212
217
|
*/
|
|
213
218
|
multiSelect: PropTypes.bool,
|
|
@@ -89,7 +89,7 @@ const SimpleTreeView = /*#__PURE__*/React.forwardRef(function SimpleTreeView(inP
|
|
|
89
89
|
process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
|
|
90
90
|
// ----------------------------- Warning --------------------------------
|
|
91
91
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
92
|
-
// | To update them edit the TypeScript types and run "
|
|
92
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
93
93
|
// ----------------------------------------------------------------------
|
|
94
94
|
/**
|
|
95
95
|
* The ref object that allows Tree View manipulation. Can be instantiated with `useTreeViewApiRef()`.
|
|
@@ -101,6 +101,11 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
|
|
|
101
101
|
setItemExpansion: PropTypes.func.isRequired
|
|
102
102
|
})
|
|
103
103
|
}),
|
|
104
|
+
/**
|
|
105
|
+
* If `true`, the tree view renders a checkbox at the left of its label that allows selecting it.
|
|
106
|
+
* @default false
|
|
107
|
+
*/
|
|
108
|
+
checkboxSelection: PropTypes.bool,
|
|
104
109
|
/**
|
|
105
110
|
* The content of the component.
|
|
106
111
|
*/
|
|
@@ -143,7 +148,7 @@ process.env.NODE_ENV !== "production" ? SimpleTreeView.propTypes = {
|
|
|
143
148
|
*/
|
|
144
149
|
id: PropTypes.string,
|
|
145
150
|
/**
|
|
146
|
-
* If true `ctrl` and `shift` will trigger multiselect.
|
|
151
|
+
* If `true`, `ctrl` and `shift` will trigger multiselect.
|
|
147
152
|
* @default false
|
|
148
153
|
*/
|
|
149
154
|
multiSelect: PropTypes.bool,
|
|
@@ -32,6 +32,7 @@ const useUtilityClasses = ownerState => {
|
|
|
32
32
|
focused: ['focused'],
|
|
33
33
|
disabled: ['disabled'],
|
|
34
34
|
iconContainer: ['iconContainer'],
|
|
35
|
+
checkbox: ['checkbox'],
|
|
35
36
|
label: ['label'],
|
|
36
37
|
groupTransition: ['groupTransition']
|
|
37
38
|
};
|
|
@@ -113,7 +114,10 @@ const StyledTreeItemContent = styled(TreeItemContent, {
|
|
|
113
114
|
// fixes overflow - see https://github.com/mui/material-ui/issues/27372
|
|
114
115
|
minWidth: 0,
|
|
115
116
|
position: 'relative'
|
|
116
|
-
}, theme.typography.body1)
|
|
117
|
+
}, theme.typography.body1),
|
|
118
|
+
[`& .${treeItemClasses.checkbox}`]: {
|
|
119
|
+
padding: 0
|
|
120
|
+
}
|
|
117
121
|
}));
|
|
118
122
|
const TreeItemGroup = styled(Collapse, {
|
|
119
123
|
name: 'MuiTreeItem',
|
|
@@ -296,7 +300,8 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
|
|
|
296
300
|
focused: classes.focused,
|
|
297
301
|
disabled: classes.disabled,
|
|
298
302
|
iconContainer: classes.iconContainer,
|
|
299
|
-
label: classes.label
|
|
303
|
+
label: classes.label,
|
|
304
|
+
checkbox: classes.checkbox
|
|
300
305
|
},
|
|
301
306
|
label: label,
|
|
302
307
|
itemId: itemId,
|
|
@@ -319,7 +324,7 @@ export const TreeItem = /*#__PURE__*/React.forwardRef(function TreeItem(inProps,
|
|
|
319
324
|
process.env.NODE_ENV !== "production" ? TreeItem.propTypes = {
|
|
320
325
|
// ----------------------------- Warning --------------------------------
|
|
321
326
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
322
|
-
// | To update them edit the TypeScript types and run "
|
|
327
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
323
328
|
// ----------------------------------------------------------------------
|
|
324
329
|
/**
|
|
325
330
|
* The content of the component.
|
|
@@ -4,6 +4,7 @@ const _excluded = ["classes", "className", "displayIcon", "expansionIcon", "icon
|
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import clsx from 'clsx';
|
|
7
|
+
import Checkbox from '@mui/material/Checkbox';
|
|
7
8
|
import { useTreeItemState } from './useTreeItemState';
|
|
8
9
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
10
|
/**
|
|
@@ -27,11 +28,15 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
|
|
|
27
28
|
expanded,
|
|
28
29
|
selected,
|
|
29
30
|
focused,
|
|
31
|
+
disableSelection,
|
|
32
|
+
checkboxSelection,
|
|
30
33
|
handleExpansion,
|
|
31
34
|
handleSelection,
|
|
35
|
+
handleCheckboxSelection,
|
|
32
36
|
preventSelection
|
|
33
37
|
} = useTreeItemState(itemId);
|
|
34
38
|
const icon = iconProp || expansionIcon || displayIcon;
|
|
39
|
+
const checkboxRef = React.useRef(null);
|
|
35
40
|
const handleMouseDown = event => {
|
|
36
41
|
preventSelection(event);
|
|
37
42
|
if (onMouseDown) {
|
|
@@ -39,8 +44,13 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
|
|
|
39
44
|
}
|
|
40
45
|
};
|
|
41
46
|
const handleClick = event => {
|
|
47
|
+
if (checkboxRef.current?.contains(event.target)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
42
50
|
handleExpansion(event);
|
|
43
|
-
|
|
51
|
+
if (!checkboxSelection) {
|
|
52
|
+
handleSelection(event);
|
|
53
|
+
}
|
|
44
54
|
if (onClick) {
|
|
45
55
|
onClick(event);
|
|
46
56
|
}
|
|
@@ -56,6 +66,13 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
|
|
|
56
66
|
children: [/*#__PURE__*/_jsx("div", {
|
|
57
67
|
className: classes.iconContainer,
|
|
58
68
|
children: icon
|
|
69
|
+
}), checkboxSelection && /*#__PURE__*/_jsx(Checkbox, {
|
|
70
|
+
className: classes.checkbox,
|
|
71
|
+
checked: selected,
|
|
72
|
+
onChange: handleCheckboxSelection,
|
|
73
|
+
disabled: disabled || disableSelection,
|
|
74
|
+
ref: checkboxRef,
|
|
75
|
+
tabIndex: -1
|
|
59
76
|
}), /*#__PURE__*/_jsx("div", {
|
|
60
77
|
className: classes.label,
|
|
61
78
|
children: label
|
|
@@ -66,7 +83,7 @@ const TreeItemContent = /*#__PURE__*/React.forwardRef(function TreeItemContent(p
|
|
|
66
83
|
process.env.NODE_ENV !== "production" ? TreeItemContent.propTypes = {
|
|
67
84
|
// ----------------------------- Warning --------------------------------
|
|
68
85
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
69
|
-
// | To update them edit the TypeScript types and run "
|
|
86
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
70
87
|
// ----------------------------------------------------------------------
|
|
71
88
|
/**
|
|
72
89
|
* Override or extend the styles applied to the component.
|
|
@@ -3,4 +3,4 @@ import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
|
|
|
3
3
|
export function getTreeItemUtilityClass(slot) {
|
|
4
4
|
return generateUtilityClass('MuiTreeItem', slot);
|
|
5
5
|
}
|
|
6
|
-
export const treeItemClasses = generateUtilityClasses('MuiTreeItem', ['root', 'groupTransition', 'content', 'expanded', 'selected', 'focused', 'disabled', 'iconContainer', 'label']);
|
|
6
|
+
export const treeItemClasses = generateUtilityClasses('MuiTreeItem', ['root', 'groupTransition', 'content', 'expanded', 'selected', 'focused', 'disabled', 'iconContainer', 'label', 'checkbox']);
|
|
@@ -3,7 +3,9 @@ export function useTreeItemState(itemId) {
|
|
|
3
3
|
const {
|
|
4
4
|
instance,
|
|
5
5
|
selection: {
|
|
6
|
-
multiSelect
|
|
6
|
+
multiSelect,
|
|
7
|
+
checkboxSelection,
|
|
8
|
+
disableSelection
|
|
7
9
|
}
|
|
8
10
|
} = useTreeViewContext();
|
|
9
11
|
const expandable = instance.isItemExpandable(itemId);
|
|
@@ -37,10 +39,21 @@ export function useTreeItemState(itemId) {
|
|
|
37
39
|
instance.selectItem(event, itemId, true);
|
|
38
40
|
}
|
|
39
41
|
} else {
|
|
40
|
-
instance.selectItem(event, itemId);
|
|
42
|
+
instance.selectItem(event, itemId, false);
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
};
|
|
46
|
+
const handleCheckboxSelection = event => {
|
|
47
|
+
if (disableSelection || disabled) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const hasShift = event.nativeEvent.shiftKey;
|
|
51
|
+
if (multiSelect && hasShift) {
|
|
52
|
+
instance.expandSelectionRange(event, itemId);
|
|
53
|
+
} else {
|
|
54
|
+
instance.selectItem(event, itemId, multiSelect, event.target.checked);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
44
57
|
const preventSelection = event => {
|
|
45
58
|
if (event.shiftKey || event.ctrlKey || event.metaKey || disabled) {
|
|
46
59
|
// Prevent text selection
|
|
@@ -52,8 +65,11 @@ export function useTreeItemState(itemId) {
|
|
|
52
65
|
expanded,
|
|
53
66
|
selected,
|
|
54
67
|
focused,
|
|
68
|
+
disableSelection,
|
|
69
|
+
checkboxSelection,
|
|
55
70
|
handleExpansion,
|
|
56
71
|
handleSelection,
|
|
72
|
+
handleCheckboxSelection,
|
|
57
73
|
preventSelection
|
|
58
74
|
};
|
|
59
75
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
2
2
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
-
const _excluded = ["
|
|
3
|
+
const _excluded = ["visible"],
|
|
4
|
+
_excluded2 = ["id", "itemId", "label", "disabled", "children", "slots", "slotProps"];
|
|
4
5
|
import * as React from 'react';
|
|
5
6
|
import PropTypes from 'prop-types';
|
|
6
7
|
import clsx from 'clsx';
|
|
7
8
|
import unsupportedProp from '@mui/utils/unsupportedProp';
|
|
8
9
|
import { alpha, styled, useThemeProps } from '@mui/material/styles';
|
|
9
10
|
import Collapse from '@mui/material/Collapse';
|
|
11
|
+
import MuiCheckbox from '@mui/material/Checkbox';
|
|
10
12
|
import { useSlotProps } from '@mui/base/utils';
|
|
11
13
|
import { shouldForwardProp } from '@mui/system';
|
|
12
14
|
import composeClasses from '@mui/utils/composeClasses';
|
|
@@ -129,6 +131,24 @@ export const TreeItem2GroupTransition = styled(Collapse, {
|
|
|
129
131
|
padding: 0,
|
|
130
132
|
paddingLeft: 12
|
|
131
133
|
});
|
|
134
|
+
export const TreeItem2Checkbox = styled( /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
135
|
+
const {
|
|
136
|
+
visible
|
|
137
|
+
} = props,
|
|
138
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
139
|
+
if (!visible) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return /*#__PURE__*/_jsx(MuiCheckbox, _extends({}, other, {
|
|
143
|
+
ref: ref
|
|
144
|
+
}));
|
|
145
|
+
}), {
|
|
146
|
+
name: 'MuiTreeItem2',
|
|
147
|
+
slot: 'Checkbox',
|
|
148
|
+
overridesResolver: (props, styles) => styles.checkbox
|
|
149
|
+
})({
|
|
150
|
+
padding: 0
|
|
151
|
+
});
|
|
132
152
|
const useUtilityClasses = ownerState => {
|
|
133
153
|
const {
|
|
134
154
|
classes
|
|
@@ -141,6 +161,7 @@ const useUtilityClasses = ownerState => {
|
|
|
141
161
|
focused: ['focused'],
|
|
142
162
|
disabled: ['disabled'],
|
|
143
163
|
iconContainer: ['iconContainer'],
|
|
164
|
+
checkbox: ['checkbox'],
|
|
144
165
|
label: ['label'],
|
|
145
166
|
groupTransition: ['groupTransition']
|
|
146
167
|
};
|
|
@@ -170,11 +191,12 @@ export const TreeItem2 = /*#__PURE__*/React.forwardRef(function TreeItem2(inProp
|
|
|
170
191
|
slots = {},
|
|
171
192
|
slotProps = {}
|
|
172
193
|
} = props,
|
|
173
|
-
other = _objectWithoutPropertiesLoose(props,
|
|
194
|
+
other = _objectWithoutPropertiesLoose(props, _excluded2);
|
|
174
195
|
const {
|
|
175
196
|
getRootProps,
|
|
176
197
|
getContentProps,
|
|
177
198
|
getIconContainerProps,
|
|
199
|
+
getCheckboxProps,
|
|
178
200
|
getLabelProps,
|
|
179
201
|
getGroupTransitionProps,
|
|
180
202
|
status
|
|
@@ -223,6 +245,14 @@ export const TreeItem2 = /*#__PURE__*/React.forwardRef(function TreeItem2(inProp
|
|
|
223
245
|
ownerState: {},
|
|
224
246
|
className: classes.label
|
|
225
247
|
});
|
|
248
|
+
const Checkbox = slots.checkbox ?? TreeItem2Checkbox;
|
|
249
|
+
const checkboxProps = useSlotProps({
|
|
250
|
+
elementType: Checkbox,
|
|
251
|
+
getSlotProps: getCheckboxProps,
|
|
252
|
+
externalSlotProps: slotProps.checkbox,
|
|
253
|
+
ownerState: {},
|
|
254
|
+
className: classes.checkbox
|
|
255
|
+
});
|
|
226
256
|
const GroupTransition = slots.groupTransition ?? undefined;
|
|
227
257
|
const groupTransitionProps = useSlotProps({
|
|
228
258
|
elementType: GroupTransition,
|
|
@@ -241,7 +271,7 @@ export const TreeItem2 = /*#__PURE__*/React.forwardRef(function TreeItem2(inProp
|
|
|
241
271
|
slots: slots,
|
|
242
272
|
slotProps: slotProps
|
|
243
273
|
})
|
|
244
|
-
})), /*#__PURE__*/_jsx(Label, _extends({}, labelProps))]
|
|
274
|
+
})), /*#__PURE__*/_jsx(Checkbox, _extends({}, checkboxProps)), /*#__PURE__*/_jsx(Label, _extends({}, labelProps))]
|
|
245
275
|
})), children && /*#__PURE__*/_jsx(TreeItem2GroupTransition, _extends({
|
|
246
276
|
as: GroupTransition
|
|
247
277
|
}, groupTransitionProps))]
|
|
@@ -251,7 +281,7 @@ export const TreeItem2 = /*#__PURE__*/React.forwardRef(function TreeItem2(inProp
|
|
|
251
281
|
process.env.NODE_ENV !== "production" ? TreeItem2.propTypes = {
|
|
252
282
|
// ----------------------------- Warning --------------------------------
|
|
253
283
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
254
|
-
// | To update them edit the TypeScript types and run "
|
|
284
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
255
285
|
// ----------------------------------------------------------------------
|
|
256
286
|
/**
|
|
257
287
|
* The content of the component.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { TreeItem2, TreeItem2Root, TreeItem2Content, TreeItem2IconContainer, TreeItem2GroupTransition, TreeItem2Label } from './TreeItem2';
|
|
1
|
+
export { TreeItem2, TreeItem2Root, TreeItem2Content, TreeItem2IconContainer, TreeItem2GroupTransition, TreeItem2Checkbox, TreeItem2Label } from './TreeItem2';
|
|
@@ -44,7 +44,7 @@ function TreeItem2Icon(props) {
|
|
|
44
44
|
process.env.NODE_ENV !== "production" ? TreeItem2Icon.propTypes = {
|
|
45
45
|
// ----------------------------- Warning --------------------------------
|
|
46
46
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
47
|
-
// | To update them edit the TypeScript types and run "
|
|
47
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
48
48
|
// ----------------------------------------------------------------------
|
|
49
49
|
/**
|
|
50
50
|
* The props used for each component slot.
|
|
@@ -16,7 +16,7 @@ function TreeItem2Provider(props) {
|
|
|
16
16
|
TreeItem2Provider.propTypes = {
|
|
17
17
|
// ----------------------------- Warning --------------------------------
|
|
18
18
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
19
|
-
// | To update them edit the TypeScript types and run "
|
|
19
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
20
20
|
// ----------------------------------------------------------------------
|
|
21
21
|
children: PropTypes.node,
|
|
22
22
|
itemId: PropTypes.string.isRequired
|
|
@@ -62,7 +62,7 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeView(inProps, ref) {
|
|
|
62
62
|
process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
|
|
63
63
|
// ----------------------------- Warning --------------------------------
|
|
64
64
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
65
|
-
// | To update them edit the TypeScript types and run "
|
|
65
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
66
66
|
// ----------------------------------------------------------------------
|
|
67
67
|
/**
|
|
68
68
|
* The ref object that allows Tree View manipulation. Can be instantiated with `useTreeViewApiRef()`.
|
|
@@ -74,6 +74,11 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
|
|
|
74
74
|
setItemExpansion: PropTypes.func.isRequired
|
|
75
75
|
})
|
|
76
76
|
}),
|
|
77
|
+
/**
|
|
78
|
+
* If `true`, the tree view renders a checkbox at the left of its label that allows selecting it.
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
checkboxSelection: PropTypes.bool,
|
|
77
82
|
/**
|
|
78
83
|
* The content of the component.
|
|
79
84
|
*/
|
|
@@ -116,7 +121,7 @@ process.env.NODE_ENV !== "production" ? TreeView.propTypes = {
|
|
|
116
121
|
*/
|
|
117
122
|
id: PropTypes.string,
|
|
118
123
|
/**
|
|
119
|
-
* If true `ctrl` and `shift` will trigger multiselect.
|
|
124
|
+
* If `true`, `ctrl` and `shift` will trigger multiselect.
|
|
120
125
|
* @default false
|
|
121
126
|
*/
|
|
122
127
|
multiSelect: PropTypes.bool,
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { useTreeViewContext } from '../../internals/TreeViewProvider/useTreeViewContext';
|
|
2
|
+
const isItemExpandable = reactChildren => {
|
|
3
|
+
if (Array.isArray(reactChildren)) {
|
|
4
|
+
return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
|
|
5
|
+
}
|
|
6
|
+
return Boolean(reactChildren);
|
|
7
|
+
};
|
|
2
8
|
export const useTreeItem2Utils = ({
|
|
3
9
|
itemId,
|
|
4
10
|
children
|
|
@@ -10,7 +16,7 @@ export const useTreeItem2Utils = ({
|
|
|
10
16
|
}
|
|
11
17
|
} = useTreeViewContext();
|
|
12
18
|
const status = {
|
|
13
|
-
expandable:
|
|
19
|
+
expandable: isItemExpandable(children),
|
|
14
20
|
expanded: instance.isItemExpanded(itemId),
|
|
15
21
|
focused: instance.isItemFocused(itemId),
|
|
16
22
|
selected: instance.isItemSelected(itemId),
|
|
@@ -45,12 +51,21 @@ export const useTreeItem2Utils = ({
|
|
|
45
51
|
instance.selectItem(event, itemId, true);
|
|
46
52
|
}
|
|
47
53
|
} else {
|
|
48
|
-
instance.selectItem(event, itemId);
|
|
54
|
+
instance.selectItem(event, itemId, false);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const handleCheckboxSelection = event => {
|
|
58
|
+
const hasShift = event.nativeEvent.shiftKey;
|
|
59
|
+
if (multiSelect && hasShift) {
|
|
60
|
+
instance.expandSelectionRange(event, itemId);
|
|
61
|
+
} else {
|
|
62
|
+
instance.selectItem(event, itemId, multiSelect, event.target.checked);
|
|
49
63
|
}
|
|
50
64
|
};
|
|
51
65
|
const interactions = {
|
|
52
66
|
handleExpansion,
|
|
53
|
-
handleSelection
|
|
67
|
+
handleSelection,
|
|
68
|
+
handleCheckboxSelection
|
|
54
69
|
};
|
|
55
70
|
return {
|
|
56
71
|
interactions,
|
package/modern/index.js
CHANGED
package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js
CHANGED
|
@@ -61,7 +61,7 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
61
61
|
if (event.defaultMuiPrevented) {
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
|
-
if (event.altKey || event.currentTarget !== event.target) {
|
|
64
|
+
if (event.altKey || event.currentTarget !== event.target.closest('*[role="treeitem"]')) {
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
const ctrlPressed = event.ctrlKey || event.metaKey;
|
|
@@ -78,7 +78,7 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
78
78
|
} else if (params.multiSelect) {
|
|
79
79
|
instance.selectItem(event, itemId, true);
|
|
80
80
|
} else {
|
|
81
|
-
instance.selectItem(event, itemId);
|
|
81
|
+
instance.selectItem(event, itemId, false);
|
|
82
82
|
}
|
|
83
83
|
break;
|
|
84
84
|
}
|
|
@@ -95,7 +95,7 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
95
95
|
event.preventDefault();
|
|
96
96
|
instance.selectItem(event, itemId, true);
|
|
97
97
|
} else if (!instance.isItemSelected(itemId)) {
|
|
98
|
-
instance.selectItem(event, itemId);
|
|
98
|
+
instance.selectItem(event, itemId, false);
|
|
99
99
|
event.preventDefault();
|
|
100
100
|
}
|
|
101
101
|
}
|
|
@@ -46,20 +46,28 @@ export const useTreeViewSelection = ({
|
|
|
46
46
|
models.selectedItems.setControlledValue(newSelectedItems);
|
|
47
47
|
};
|
|
48
48
|
const isItemSelected = itemId => selectedItemsMap.has(itemId);
|
|
49
|
-
const selectItem = (event, itemId,
|
|
49
|
+
const selectItem = (event, itemId, keepExistingSelection, newValue) => {
|
|
50
50
|
if (params.disableSelection) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
let newSelected;
|
|
54
|
-
if (
|
|
54
|
+
if (keepExistingSelection) {
|
|
55
55
|
const cleanSelectedItems = convertSelectedItemsToArray(models.selectedItems.value);
|
|
56
|
-
|
|
56
|
+
const isSelectedBefore = instance.isItemSelected(itemId);
|
|
57
|
+
if (isSelectedBefore && (newValue === false || newValue == null)) {
|
|
57
58
|
newSelected = cleanSelectedItems.filter(id => id !== itemId);
|
|
58
|
-
} else {
|
|
59
|
+
} else if (!isSelectedBefore && (newValue === true || newValue == null)) {
|
|
59
60
|
newSelected = [itemId].concat(cleanSelectedItems);
|
|
61
|
+
} else {
|
|
62
|
+
newSelected = cleanSelectedItems;
|
|
60
63
|
}
|
|
61
64
|
} else {
|
|
62
|
-
|
|
65
|
+
// eslint-disable-next-line no-lonely-if
|
|
66
|
+
if (newValue === false) {
|
|
67
|
+
newSelected = params.multiSelect ? [] : null;
|
|
68
|
+
} else {
|
|
69
|
+
newSelected = params.multiSelect ? [itemId] : itemId;
|
|
70
|
+
}
|
|
63
71
|
}
|
|
64
72
|
setSelectedItems(event, newSelected);
|
|
65
73
|
lastSelectedItem.current = itemId;
|
|
@@ -145,7 +153,9 @@ export const useTreeViewSelection = ({
|
|
|
145
153
|
},
|
|
146
154
|
contextValue: {
|
|
147
155
|
selection: {
|
|
148
|
-
multiSelect: params.multiSelect
|
|
156
|
+
multiSelect: params.multiSelect,
|
|
157
|
+
checkboxSelection: params.checkboxSelection,
|
|
158
|
+
disableSelection: params.disableSelection
|
|
149
159
|
}
|
|
150
160
|
}
|
|
151
161
|
};
|
|
@@ -159,11 +169,13 @@ const DEFAULT_SELECTED_ITEMS = [];
|
|
|
159
169
|
useTreeViewSelection.getDefaultizedParams = params => _extends({}, params, {
|
|
160
170
|
disableSelection: params.disableSelection ?? false,
|
|
161
171
|
multiSelect: params.multiSelect ?? false,
|
|
172
|
+
checkboxSelection: params.checkboxSelection ?? false,
|
|
162
173
|
defaultSelectedItems: params.defaultSelectedItems ?? (params.multiSelect ? DEFAULT_SELECTED_ITEMS : null)
|
|
163
174
|
});
|
|
164
175
|
useTreeViewSelection.params = {
|
|
165
176
|
disableSelection: true,
|
|
166
177
|
multiSelect: true,
|
|
178
|
+
checkboxSelection: true,
|
|
167
179
|
defaultSelectedItems: true,
|
|
168
180
|
selectedItems: true,
|
|
169
181
|
onSelectedItemsChange: true,
|
|
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
/**
|
|
4
4
|
* Implements the same behavior as `useControlled` but for several models.
|
|
5
|
-
* The controlled models are never stored in the state and the state is only updated if the model is not controlled.
|
|
5
|
+
* The controlled models are never stored in the state, and the state is only updated if the model is not controlled.
|
|
6
6
|
*/
|
|
7
7
|
export const useTreeViewModels = (plugins, props) => {
|
|
8
8
|
const modelsRef = React.useRef({});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
2
3
|
import { extractEventHandlers } from '@mui/base/utils';
|
|
3
4
|
import useForkRef from '@mui/utils/useForkRef';
|
|
4
5
|
import { useTreeViewContext } from '../internals/TreeViewProvider/useTreeViewContext';
|
|
@@ -7,7 +8,9 @@ export const useTreeItem2 = parameters => {
|
|
|
7
8
|
const {
|
|
8
9
|
runItemPlugins,
|
|
9
10
|
selection: {
|
|
10
|
-
multiSelect
|
|
11
|
+
multiSelect,
|
|
12
|
+
disableSelection,
|
|
13
|
+
checkboxSelection
|
|
11
14
|
},
|
|
12
15
|
disabledItemsFocusable,
|
|
13
16
|
instance,
|
|
@@ -33,6 +36,7 @@ export const useTreeItem2 = parameters => {
|
|
|
33
36
|
});
|
|
34
37
|
const idAttribute = instance.getTreeItemIdAttribute(itemId, id);
|
|
35
38
|
const handleRootRef = useForkRef(rootRef, pluginRootRef);
|
|
39
|
+
const checkboxRef = React.useRef(null);
|
|
36
40
|
const createRootHandleFocus = otherHandlers => event => {
|
|
37
41
|
otherHandlers.onFocus?.(event);
|
|
38
42
|
if (event.defaultMuiPrevented) {
|
|
@@ -59,11 +63,13 @@ export const useTreeItem2 = parameters => {
|
|
|
59
63
|
};
|
|
60
64
|
const createContentHandleClick = otherHandlers => event => {
|
|
61
65
|
otherHandlers.onClick?.(event);
|
|
62
|
-
if (event.defaultMuiPrevented) {
|
|
66
|
+
if (event.defaultMuiPrevented || checkboxRef.current?.contains(event.target)) {
|
|
63
67
|
return;
|
|
64
68
|
}
|
|
65
69
|
interactions.handleExpansion(event);
|
|
66
|
-
|
|
70
|
+
if (!checkboxSelection) {
|
|
71
|
+
interactions.handleSelection(event);
|
|
72
|
+
}
|
|
67
73
|
};
|
|
68
74
|
const createContentHandleMouseDown = otherHandlers => event => {
|
|
69
75
|
otherHandlers.onMouseDown?.(event);
|
|
@@ -76,6 +82,16 @@ export const useTreeItem2 = parameters => {
|
|
|
76
82
|
event.preventDefault();
|
|
77
83
|
}
|
|
78
84
|
};
|
|
85
|
+
const createCheckboxHandleChange = otherHandlers => event => {
|
|
86
|
+
otherHandlers.onChange?.(event);
|
|
87
|
+
if (event.defaultMuiPrevented) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (disableSelection || status.disabled) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
interactions.handleCheckboxSelection(event);
|
|
94
|
+
};
|
|
79
95
|
const getRootProps = (externalProps = {}) => {
|
|
80
96
|
const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
|
|
81
97
|
let ariaSelected;
|
|
@@ -113,6 +129,18 @@ export const useTreeItem2 = parameters => {
|
|
|
113
129
|
status
|
|
114
130
|
});
|
|
115
131
|
};
|
|
132
|
+
const getCheckboxProps = (externalProps = {}) => {
|
|
133
|
+
const externalEventHandlers = extractEventHandlers(externalProps);
|
|
134
|
+
return _extends({}, externalEventHandlers, {
|
|
135
|
+
visible: checkboxSelection,
|
|
136
|
+
ref: checkboxRef,
|
|
137
|
+
checked: status.selected,
|
|
138
|
+
disabled: disableSelection || status.disabled,
|
|
139
|
+
tabIndex: -1
|
|
140
|
+
}, externalProps, {
|
|
141
|
+
onChange: createCheckboxHandleChange(externalEventHandlers)
|
|
142
|
+
});
|
|
143
|
+
};
|
|
116
144
|
const getLabelProps = (externalProps = {}) => {
|
|
117
145
|
const externalEventHandlers = _extends({}, extractEventHandlers(parameters), extractEventHandlers(externalProps));
|
|
118
146
|
return _extends({}, externalEventHandlers, {
|
|
@@ -138,6 +166,7 @@ export const useTreeItem2 = parameters => {
|
|
|
138
166
|
getContentProps,
|
|
139
167
|
getGroupTransitionProps,
|
|
140
168
|
getIconContainerProps,
|
|
169
|
+
getCheckboxProps,
|
|
141
170
|
getLabelProps,
|
|
142
171
|
rootRef: handleRootRef,
|
|
143
172
|
status,
|