@mui/x-tree-view 7.18.0 → 7.20.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 +213 -11
- package/RichTreeView/RichTreeView.js +6 -45
- package/RichTreeView/RichTreeView.plugins.d.ts +1 -1
- package/SimpleTreeView/SimpleTreeView.plugins.d.ts +1 -1
- package/TreeItem/TreeItem.js +19 -1
- package/TreeItem/TreeItem.types.d.ts +2 -0
- package/TreeItem/TreeItemContent.js +25 -29
- package/TreeItem2/TreeItem2.d.ts +6 -6
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.d.ts +24 -6
- package/hooks/useTreeItem2Utils/useTreeItem2Utils.js +10 -8
- package/index.js +1 -1
- package/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +7 -1
- package/internals/TreeViewProvider/TreeViewProvider.js +2 -1
- package/internals/TreeViewProvider/TreeViewProvider.types.d.ts +2 -1
- package/internals/TreeViewProvider/useTreeViewContext.d.ts +1 -1
- package/internals/components/RichTreeViewItems.d.ts +35 -0
- package/internals/components/RichTreeViewItems.js +56 -0
- package/internals/corePlugins/corePlugins.d.ts +1 -1
- package/internals/corePlugins/useTreeViewId/useTreeViewId.js +28 -7
- package/internals/corePlugins/useTreeViewId/useTreeViewId.types.d.ts +11 -13
- package/internals/corePlugins/useTreeViewId/useTreeViewId.utils.d.ts +17 -0
- package/internals/corePlugins/useTreeViewId/useTreeViewId.utils.js +26 -0
- package/internals/index.d.ts +1 -0
- package/internals/index.js +1 -0
- package/internals/models/plugin.d.ts +4 -1
- package/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +3 -1
- package/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -1
- package/internals/plugins/useTreeViewItems/index.d.ts +1 -1
- package/internals/plugins/useTreeViewItems/useTreeViewItems.js +9 -2
- package/internals/plugins/useTreeViewItems/useTreeViewItems.types.d.ts +6 -6
- package/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +11 -5
- package/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +6 -0
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -8
- package/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.d.ts +3 -2
- package/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +3 -1
- package/internals/useTreeView/extractPluginParamsFromProps.d.ts +1 -1
- package/internals/useTreeView/extractPluginParamsFromProps.js +7 -3
- package/modern/RichTreeView/RichTreeView.js +6 -45
- package/modern/TreeItem/TreeItem.js +19 -1
- package/modern/TreeItem/TreeItemContent.js +25 -29
- package/modern/hooks/useTreeItem2Utils/useTreeItem2Utils.js +10 -8
- package/modern/index.js +1 -1
- package/modern/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +7 -1
- package/modern/internals/TreeViewProvider/TreeViewProvider.js +2 -1
- package/modern/internals/components/RichTreeViewItems.js +56 -0
- package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.js +28 -7
- package/modern/internals/corePlugins/useTreeViewId/useTreeViewId.utils.js +26 -0
- package/modern/internals/index.js +1 -0
- package/modern/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +3 -1
- package/modern/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -1
- package/modern/internals/plugins/useTreeViewItems/useTreeViewItems.js +9 -2
- package/modern/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +11 -5
- package/modern/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +6 -0
- package/modern/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -8
- package/modern/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +3 -1
- package/modern/internals/useTreeView/extractPluginParamsFromProps.js +7 -3
- package/modern/useTreeItem2/useTreeItem2.js +7 -1
- package/node/RichTreeView/RichTreeView.js +6 -45
- package/node/TreeItem/TreeItem.js +19 -1
- package/node/TreeItem/TreeItemContent.js +25 -29
- package/node/hooks/useTreeItem2Utils/useTreeItem2Utils.js +10 -9
- package/node/index.js +1 -1
- package/node/internals/TreeViewProvider/TreeViewChildrenItemProvider.js +7 -1
- package/node/internals/TreeViewProvider/TreeViewProvider.js +2 -1
- package/node/internals/components/RichTreeViewItems.js +64 -0
- package/node/internals/corePlugins/useTreeViewId/useTreeViewId.js +29 -8
- package/node/internals/corePlugins/useTreeViewId/useTreeViewId.utils.js +34 -0
- package/node/internals/index.js +7 -0
- package/node/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.js +3 -1
- package/node/internals/plugins/useTreeViewFocus/useTreeViewFocus.js +1 -1
- package/node/internals/plugins/useTreeViewItems/useTreeViewItems.js +9 -2
- package/node/internals/plugins/useTreeViewJSXItems/useTreeViewJSXItems.js +11 -5
- package/node/internals/plugins/useTreeViewKeyboardNavigation/useTreeViewKeyboardNavigation.js +6 -0
- package/node/internals/plugins/useTreeViewLabel/useTreeViewLabel.js +16 -8
- package/node/internals/plugins/useTreeViewSelection/useTreeViewSelection.js +3 -1
- package/node/internals/useTreeView/extractPluginParamsFromProps.js +7 -3
- package/node/useTreeItem2/useTreeItem2.js +7 -1
- package/package.json +4 -4
- package/useTreeItem2/index.d.ts +3 -3
- package/useTreeItem2/useTreeItem2.js +7 -1
- package/useTreeItem2/useTreeItem2.types.d.ts +1 -1
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { UseTreeViewSelectionSignature } from '../../internals/plugins/useTreeViewSelection';
|
|
3
|
+
import { UseTreeViewExpansionSignature } from '../../internals/plugins/useTreeViewExpansion';
|
|
4
|
+
import { UseTreeViewItemsSignature } from '../../internals/plugins/useTreeViewItems';
|
|
5
|
+
import { UseTreeViewFocusSignature } from '../../internals/plugins/useTreeViewFocus';
|
|
2
6
|
import { UseTreeViewLabelSignature } from '../../internals/plugins/useTreeViewLabel';
|
|
3
7
|
import type { UseTreeItem2Status } from '../../useTreeItem2';
|
|
8
|
+
import { TreeViewPublicAPI } from '../../internals/models';
|
|
4
9
|
export interface UseTreeItem2Interactions {
|
|
5
10
|
handleExpansion: (event: React.MouseEvent) => void;
|
|
6
11
|
handleSelection: (event: React.MouseEvent) => void;
|
|
@@ -9,16 +14,29 @@ export interface UseTreeItem2Interactions {
|
|
|
9
14
|
handleSaveItemLabel: (event: React.SyntheticEvent, label: string) => void;
|
|
10
15
|
handleCancelItemLabelEditing: (event: React.SyntheticEvent) => void;
|
|
11
16
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Plugins that need to be present in the Tree View in order for `useTreeItem2Utils` to work correctly.
|
|
19
|
+
*/
|
|
20
|
+
type UseTreeItem2UtilsMinimalPlugins = readonly [
|
|
21
|
+
UseTreeViewSelectionSignature,
|
|
22
|
+
UseTreeViewExpansionSignature,
|
|
23
|
+
UseTreeViewItemsSignature,
|
|
24
|
+
UseTreeViewFocusSignature
|
|
25
|
+
];
|
|
16
26
|
/**
|
|
17
27
|
* Plugins that `useTreeItem2Utils` can use if they are present, but are not required.
|
|
18
28
|
*/
|
|
19
29
|
export type UseTreeItem2UtilsOptionalPlugins = readonly [UseTreeViewLabelSignature];
|
|
20
|
-
|
|
30
|
+
interface UseTreeItem2UtilsReturnValue<TSignatures extends UseTreeItem2UtilsMinimalPlugins, TOptionalSignatures extends UseTreeItem2UtilsOptionalPlugins> {
|
|
31
|
+
interactions: UseTreeItem2Interactions;
|
|
32
|
+
status: UseTreeItem2Status;
|
|
33
|
+
/**
|
|
34
|
+
* The object the allows Tree View manipulation.
|
|
35
|
+
*/
|
|
36
|
+
publicAPI: TreeViewPublicAPI<TSignatures, TOptionalSignatures>;
|
|
37
|
+
}
|
|
38
|
+
export declare const useTreeItem2Utils: <TSignatures extends UseTreeItem2UtilsMinimalPlugins = UseTreeItem2UtilsMinimalPlugins, TOptionalSignatures extends UseTreeItem2UtilsOptionalPlugins = UseTreeItem2UtilsOptionalPlugins>({ itemId, children, }: {
|
|
21
39
|
itemId: string;
|
|
22
40
|
children: React.ReactNode;
|
|
23
|
-
}) => UseTreeItem2UtilsReturnValue
|
|
41
|
+
}) => UseTreeItem2UtilsReturnValue<TSignatures, TOptionalSignatures>;
|
|
24
42
|
export {};
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { useTreeViewContext } from "../../internals/TreeViewProvider/index.js";
|
|
2
2
|
import { useTreeViewLabel } from "../../internals/plugins/useTreeViewLabel/index.js";
|
|
3
3
|
import { hasPlugin } from "../../internals/utils/plugins.js";
|
|
4
|
-
const isItemExpandable = reactChildren => {
|
|
5
|
-
if (Array.isArray(reactChildren)) {
|
|
6
|
-
return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
|
|
7
|
-
}
|
|
8
|
-
return Boolean(reactChildren);
|
|
9
|
-
};
|
|
10
4
|
|
|
11
5
|
/**
|
|
12
6
|
* Plugins that need to be present in the Tree View in order for `useTreeItem2Utils` to work correctly.
|
|
@@ -16,6 +10,12 @@ const isItemExpandable = reactChildren => {
|
|
|
16
10
|
* Plugins that `useTreeItem2Utils` can use if they are present, but are not required.
|
|
17
11
|
*/
|
|
18
12
|
|
|
13
|
+
const isItemExpandable = reactChildren => {
|
|
14
|
+
if (Array.isArray(reactChildren)) {
|
|
15
|
+
return reactChildren.length > 0 && reactChildren.some(isItemExpandable);
|
|
16
|
+
}
|
|
17
|
+
return Boolean(reactChildren);
|
|
18
|
+
};
|
|
19
19
|
export const useTreeItem2Utils = ({
|
|
20
20
|
itemId,
|
|
21
21
|
children
|
|
@@ -24,7 +24,8 @@ export const useTreeItem2Utils = ({
|
|
|
24
24
|
instance,
|
|
25
25
|
selection: {
|
|
26
26
|
multiSelect
|
|
27
|
-
}
|
|
27
|
+
},
|
|
28
|
+
publicAPI
|
|
28
29
|
} = useTreeViewContext();
|
|
29
30
|
const status = {
|
|
30
31
|
expandable: isItemExpandable(children),
|
|
@@ -134,6 +135,7 @@ export const useTreeItem2Utils = ({
|
|
|
134
135
|
};
|
|
135
136
|
return {
|
|
136
137
|
interactions,
|
|
137
|
-
status
|
|
138
|
+
status,
|
|
139
|
+
publicAPI
|
|
138
140
|
};
|
|
139
141
|
};
|
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { useTreeViewContext } from "./useTreeViewContext.js";
|
|
4
4
|
import { escapeOperandAttributeSelector } from "../utils/utils.js";
|
|
5
|
+
import { generateTreeItemIdAttribute } from "../corePlugins/useTreeViewId/useTreeViewId.utils.js";
|
|
5
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
7
|
export const TreeViewChildrenItemContext = /*#__PURE__*/React.createContext(null);
|
|
7
8
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -14,6 +15,7 @@ export function TreeViewChildrenItemProvider(props) {
|
|
|
14
15
|
} = props;
|
|
15
16
|
const {
|
|
16
17
|
instance,
|
|
18
|
+
treeId,
|
|
17
19
|
rootRef
|
|
18
20
|
} = useTreeViewContext();
|
|
19
21
|
const childrenIdAttrToIdRef = React.useRef(new Map());
|
|
@@ -28,7 +30,11 @@ export function TreeViewChildrenItemProvider(props) {
|
|
|
28
30
|
// Undefined during 1st render
|
|
29
31
|
const itemMeta = instance.getItemMeta(itemId);
|
|
30
32
|
if (itemMeta !== undefined) {
|
|
31
|
-
idAttr =
|
|
33
|
+
idAttr = generateTreeItemIdAttribute({
|
|
34
|
+
itemId,
|
|
35
|
+
treeId,
|
|
36
|
+
id: itemMeta.idAttribute
|
|
37
|
+
});
|
|
32
38
|
}
|
|
33
39
|
}
|
|
34
40
|
if (idAttr == null) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { MergeSignaturesProperty, TreeItemWrapper, TreeRootWrapper, TreeViewAnyPluginSignature, TreeViewInstance, TreeViewItemPluginResponse, TreeViewPublicAPI } from '../models';
|
|
3
|
+
import { TreeViewCorePluginSignatures } from '../corePlugins';
|
|
3
4
|
export type TreeViewItemPluginsRunner = <TProps extends {}>(props: TProps) => Required<TreeViewItemPluginResponse>;
|
|
4
|
-
export type TreeViewContextValue<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<TSignatures, 'contextValue'> & Partial<MergeSignaturesProperty<TOptionalSignatures, 'contextValue'>> & {
|
|
5
|
+
export type TreeViewContextValue<TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []> = MergeSignaturesProperty<[...TreeViewCorePluginSignatures, ...TSignatures], 'contextValue'> & Partial<MergeSignaturesProperty<TOptionalSignatures, 'contextValue'>> & {
|
|
5
6
|
instance: TreeViewInstance<TSignatures, TOptionalSignatures>;
|
|
6
7
|
publicAPI: TreeViewPublicAPI<TSignatures, TOptionalSignatures>;
|
|
7
8
|
rootRef: React.RefObject<HTMLUListElement>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { TreeViewAnyPluginSignature } from '../models';
|
|
2
2
|
import { TreeViewContextValue } from './TreeViewProvider.types';
|
|
3
|
-
export declare const useTreeViewContext: <TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []>() =>
|
|
3
|
+
export declare const useTreeViewContext: <TSignatures extends readonly TreeViewAnyPluginSignature[], TOptionalSignatures extends readonly TreeViewAnyPluginSignature[] = []>() => TreeViewContextValue<TSignatures, TOptionalSignatures>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { SlotComponentProps } from '@mui/utils';
|
|
3
|
+
import { TreeItem, TreeItemProps } from '../../TreeItem';
|
|
4
|
+
import { TreeItem2Props } from '../../TreeItem2';
|
|
5
|
+
import { TreeViewItemId } from '../../models';
|
|
6
|
+
import { TreeViewItemToRenderProps } from '../plugins/useTreeViewItems';
|
|
7
|
+
interface RichTreeViewItemsOwnerState {
|
|
8
|
+
itemId: TreeViewItemId;
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RichTreeViewItemsSlots {
|
|
12
|
+
/**
|
|
13
|
+
* Custom component for the item.
|
|
14
|
+
* @default TreeItem.
|
|
15
|
+
*/
|
|
16
|
+
item?: React.JSXElementConstructor<TreeItemProps> | React.JSXElementConstructor<TreeItem2Props>;
|
|
17
|
+
}
|
|
18
|
+
export interface RichTreeViewItemsSlotProps {
|
|
19
|
+
item?: SlotComponentProps<typeof TreeItem, {}, RichTreeViewItemsOwnerState>;
|
|
20
|
+
}
|
|
21
|
+
export interface RichTreeViewItemsProps {
|
|
22
|
+
itemsToRender: TreeViewItemToRenderProps[];
|
|
23
|
+
/**
|
|
24
|
+
* Overridable component slots.
|
|
25
|
+
* @default {}
|
|
26
|
+
*/
|
|
27
|
+
slots?: RichTreeViewItemsSlots;
|
|
28
|
+
/**
|
|
29
|
+
* The props used for each component slot.
|
|
30
|
+
* @default {}
|
|
31
|
+
*/
|
|
32
|
+
slotProps?: RichTreeViewItemsSlotProps;
|
|
33
|
+
}
|
|
34
|
+
export declare function RichTreeViewItems(props: RichTreeViewItemsProps): React.JSX.Element;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
+
const _excluded = ["ownerState"];
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import useSlotProps from '@mui/utils/useSlotProps';
|
|
6
|
+
import { TreeItem } from "../../TreeItem/index.js";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
function WrappedTreeItem({
|
|
9
|
+
slots,
|
|
10
|
+
slotProps,
|
|
11
|
+
label,
|
|
12
|
+
id,
|
|
13
|
+
itemId,
|
|
14
|
+
itemsToRender
|
|
15
|
+
}) {
|
|
16
|
+
const Item = slots?.item ?? TreeItem;
|
|
17
|
+
const _useSlotProps = useSlotProps({
|
|
18
|
+
elementType: Item,
|
|
19
|
+
externalSlotProps: slotProps?.item,
|
|
20
|
+
additionalProps: {
|
|
21
|
+
itemId,
|
|
22
|
+
id,
|
|
23
|
+
label
|
|
24
|
+
},
|
|
25
|
+
ownerState: {
|
|
26
|
+
itemId,
|
|
27
|
+
label
|
|
28
|
+
}
|
|
29
|
+
}),
|
|
30
|
+
itemProps = _objectWithoutPropertiesLoose(_useSlotProps, _excluded);
|
|
31
|
+
const children = React.useMemo(() => itemsToRender ? /*#__PURE__*/_jsx(RichTreeViewItems, {
|
|
32
|
+
itemsToRender: itemsToRender,
|
|
33
|
+
slots: slots,
|
|
34
|
+
slotProps: slotProps
|
|
35
|
+
}) : null, [itemsToRender, slots, slotProps]);
|
|
36
|
+
return /*#__PURE__*/_jsx(Item, _extends({}, itemProps, {
|
|
37
|
+
children: children
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
export function RichTreeViewItems(props) {
|
|
41
|
+
const {
|
|
42
|
+
itemsToRender,
|
|
43
|
+
slots,
|
|
44
|
+
slotProps
|
|
45
|
+
} = props;
|
|
46
|
+
return /*#__PURE__*/_jsx(React.Fragment, {
|
|
47
|
+
children: itemsToRender.map(item => /*#__PURE__*/_jsx(WrappedTreeItem, {
|
|
48
|
+
slots: slots,
|
|
49
|
+
slotProps: slotProps,
|
|
50
|
+
label: item.label,
|
|
51
|
+
id: item.id,
|
|
52
|
+
itemId: item.itemId,
|
|
53
|
+
itemsToRender: item.children
|
|
54
|
+
}, item.itemId))
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -4,7 +4,7 @@ import { ConvertPluginsIntoSignatures } from '../models';
|
|
|
4
4
|
* Internal plugins that create the tools used by the other plugins.
|
|
5
5
|
* These plugins are used by the tree view components.
|
|
6
6
|
*/
|
|
7
|
-
export declare const TREE_VIEW_CORE_PLUGINS: readonly [import("
|
|
7
|
+
export declare const TREE_VIEW_CORE_PLUGINS: readonly [import("..").TreeViewPlugin<import("./useTreeViewInstanceEvents").UseTreeViewInstanceEventsSignature>, import("..").TreeViewPlugin<import("./useTreeViewOptionalPlugins").UseTreeViewOptionalPluginsSignature>, import("..").TreeViewPlugin<import("./useTreeViewId").UseTreeViewIdSignature>];
|
|
8
8
|
export type TreeViewCorePluginSignatures = ConvertPluginsIntoSignatures<typeof TREE_VIEW_CORE_PLUGINS>;
|
|
9
9
|
export interface TreeViewCorePluginParameters extends UseTreeViewIdParameters {
|
|
10
10
|
}
|
|
@@ -1,19 +1,40 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
1
2
|
import * as React from 'react';
|
|
2
|
-
import
|
|
3
|
+
import { createTreeViewDefaultId } from "./useTreeViewId.utils.js";
|
|
3
4
|
export const useTreeViewId = ({
|
|
4
|
-
params
|
|
5
|
+
params,
|
|
6
|
+
state,
|
|
7
|
+
setState
|
|
5
8
|
}) => {
|
|
6
|
-
const treeId =
|
|
7
|
-
|
|
9
|
+
const treeId = state.id.treeId;
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
setState(prevState => {
|
|
12
|
+
if (prevState.id.treeId === params.id) {
|
|
13
|
+
return prevState;
|
|
14
|
+
}
|
|
15
|
+
return _extends({}, prevState, {
|
|
16
|
+
id: _extends({}, prevState.id, {
|
|
17
|
+
treeId: params.id ?? createTreeViewDefaultId()
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}, [setState, params.id]);
|
|
8
22
|
return {
|
|
9
23
|
getRootProps: () => ({
|
|
10
24
|
id: treeId
|
|
11
25
|
}),
|
|
12
|
-
|
|
13
|
-
|
|
26
|
+
contextValue: {
|
|
27
|
+
treeId
|
|
14
28
|
}
|
|
15
29
|
};
|
|
16
30
|
};
|
|
17
31
|
useTreeViewId.params = {
|
|
18
32
|
id: true
|
|
19
|
-
};
|
|
33
|
+
};
|
|
34
|
+
useTreeViewId.getInitialState = ({
|
|
35
|
+
id
|
|
36
|
+
}) => ({
|
|
37
|
+
id: {
|
|
38
|
+
treeId: id ?? createTreeViewDefaultId()
|
|
39
|
+
}
|
|
40
|
+
});
|
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
import { TreeViewPluginSignature } from '../../models';
|
|
2
|
-
import { TreeViewItemId } from '../../../models';
|
|
3
|
-
export interface UseTreeViewIdInstance {
|
|
4
|
-
/**
|
|
5
|
-
* Get the id attribute (i.e.: the `id` attribute passed to the DOM element) of a tree item.
|
|
6
|
-
* If the user explicitly defined an id attribute, it will be returned.
|
|
7
|
-
* Otherwise, the method created a unique id for the item based on the Tree View id attribute and the item `itemId`
|
|
8
|
-
* @param {TreeViewItemId} itemId The id of the item to get the id attribute of.
|
|
9
|
-
* @param {string | undefined} idAttribute The id attribute of the item if explicitly defined by the user.
|
|
10
|
-
* @returns {string} The id attribute of the item.
|
|
11
|
-
*/
|
|
12
|
-
getTreeItemIdAttribute: (itemId: TreeViewItemId, idAttribute: string | undefined) => string;
|
|
13
|
-
}
|
|
14
2
|
export interface UseTreeViewIdParameters {
|
|
15
3
|
/**
|
|
16
4
|
* This prop is used to help implement the accessibility logic.
|
|
@@ -19,8 +7,18 @@ export interface UseTreeViewIdParameters {
|
|
|
19
7
|
id?: string;
|
|
20
8
|
}
|
|
21
9
|
export type UseTreeViewIdDefaultizedParameters = UseTreeViewIdParameters;
|
|
10
|
+
export interface UseTreeViewIdState {
|
|
11
|
+
id: {
|
|
12
|
+
treeId: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
interface UseTreeViewIdContextValue {
|
|
16
|
+
treeId: string | undefined;
|
|
17
|
+
}
|
|
22
18
|
export type UseTreeViewIdSignature = TreeViewPluginSignature<{
|
|
23
19
|
params: UseTreeViewIdParameters;
|
|
24
20
|
defaultizedParams: UseTreeViewIdDefaultizedParameters;
|
|
25
|
-
|
|
21
|
+
state: UseTreeViewIdState;
|
|
22
|
+
contextValue: UseTreeViewIdContextValue;
|
|
26
23
|
}>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TreeViewItemId } from '../../../models';
|
|
2
|
+
export declare const createTreeViewDefaultId: () => string;
|
|
3
|
+
/**
|
|
4
|
+
* Generate the id attribute (i.e.: the `id` attribute passed to the DOM element) of a tree item.
|
|
5
|
+
* If the user explicitly defined an id attribute, it will be returned.
|
|
6
|
+
* Otherwise, the method creates a unique id for the item based on the Tree View id attribute and the item `itemId`
|
|
7
|
+
* @param {object} params The parameters to determine the id attribute of the item.
|
|
8
|
+
* @param {TreeViewItemId} params.itemId The id of the item to get the id attribute of.
|
|
9
|
+
* @param {string | undefined} params.idAttribute The id attribute of the item if explicitly defined by the user.
|
|
10
|
+
* @param {string} params.treeId The id attribute of the Tree View.
|
|
11
|
+
* @returns {string} The id attribute of the item.
|
|
12
|
+
*/
|
|
13
|
+
export declare const generateTreeItemIdAttribute: ({ id, treeId, itemId, }: {
|
|
14
|
+
id: TreeViewItemId | undefined;
|
|
15
|
+
treeId: string | undefined;
|
|
16
|
+
itemId: string;
|
|
17
|
+
}) => string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
let globalTreeViewDefaultId = 0;
|
|
2
|
+
export const createTreeViewDefaultId = () => {
|
|
3
|
+
globalTreeViewDefaultId += 1;
|
|
4
|
+
return `mui-tree-view-${globalTreeViewDefaultId}`;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate the id attribute (i.e.: the `id` attribute passed to the DOM element) of a tree item.
|
|
9
|
+
* If the user explicitly defined an id attribute, it will be returned.
|
|
10
|
+
* Otherwise, the method creates a unique id for the item based on the Tree View id attribute and the item `itemId`
|
|
11
|
+
* @param {object} params The parameters to determine the id attribute of the item.
|
|
12
|
+
* @param {TreeViewItemId} params.itemId The id of the item to get the id attribute of.
|
|
13
|
+
* @param {string | undefined} params.idAttribute The id attribute of the item if explicitly defined by the user.
|
|
14
|
+
* @param {string} params.treeId The id attribute of the Tree View.
|
|
15
|
+
* @returns {string} The id attribute of the item.
|
|
16
|
+
*/
|
|
17
|
+
export const generateTreeItemIdAttribute = ({
|
|
18
|
+
id,
|
|
19
|
+
treeId = '',
|
|
20
|
+
itemId
|
|
21
|
+
}) => {
|
|
22
|
+
if (id != null) {
|
|
23
|
+
return id;
|
|
24
|
+
}
|
|
25
|
+
return `${treeId}-${itemId}`;
|
|
26
|
+
};
|
package/internals/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { useTreeView } from './useTreeView';
|
|
2
2
|
export { TreeViewProvider, useTreeViewContext } from './TreeViewProvider';
|
|
3
|
+
export { RichTreeViewItems } from './components/RichTreeViewItems';
|
|
3
4
|
export { unstable_resetCleanupTracking } from './hooks/useInstanceEventHandler';
|
|
4
5
|
export type { TreeViewPlugin, TreeViewPluginSignature, ConvertPluginsIntoSignatures, MergeSignaturesProperty, TreeViewPublicAPI, TreeViewExperimentalFeatures, TreeViewItemMeta, TreeViewInstance, DefaultizedProps, TreeViewItemPlugin, MuiCancellableEvent, MuiCancellableEventHandler, } from './models';
|
|
5
6
|
export type { TreeViewCorePluginParameters } from './corePlugins';
|
package/internals/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { useTreeView } from "./useTreeView/index.js";
|
|
2
2
|
export { TreeViewProvider, useTreeViewContext } from "./TreeViewProvider/index.js";
|
|
3
|
+
export { RichTreeViewItems } from "./components/RichTreeViewItems.js";
|
|
3
4
|
export { unstable_resetCleanupTracking } from "./hooks/useInstanceEventHandler.js";
|
|
4
5
|
|
|
5
6
|
// Core plugins
|
|
@@ -138,7 +138,10 @@ export type TreeRootWrapper<TSignatures extends readonly TreeViewAnyPluginSignat
|
|
|
138
138
|
}) => React.ReactNode;
|
|
139
139
|
export type TreeViewPlugin<TSignature extends TreeViewAnyPluginSignature> = {
|
|
140
140
|
(options: TreeViewPluginOptions<TSignature>): TreeViewResponse<TSignature>;
|
|
141
|
-
getDefaultizedParams?: (
|
|
141
|
+
getDefaultizedParams?: (options: {
|
|
142
|
+
params: TreeViewUsedParams<TSignature>;
|
|
143
|
+
experimentalFeatures: TreeViewUsedExperimentalFeatures<TSignature>;
|
|
144
|
+
}) => TSignature['defaultizedParams'];
|
|
142
145
|
getInitialState?: (params: TreeViewUsedDefaultizedParams<TSignature>) => TSignature['state'];
|
|
143
146
|
models?: TreeViewModelsInitializer<TSignature>;
|
|
144
147
|
params: Record<keyof TSignature['params'], true>;
|
|
@@ -86,7 +86,9 @@ useTreeViewExpansion.models = {
|
|
|
86
86
|
}
|
|
87
87
|
};
|
|
88
88
|
const DEFAULT_EXPANDED_ITEMS = [];
|
|
89
|
-
useTreeViewExpansion.getDefaultizedParams =
|
|
89
|
+
useTreeViewExpansion.getDefaultizedParams = ({
|
|
90
|
+
params
|
|
91
|
+
}) => _extends({}, params, {
|
|
90
92
|
defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS
|
|
91
93
|
});
|
|
92
94
|
useTreeViewExpansion.params = {
|
|
@@ -64,7 +64,7 @@ export const useTreeViewFocus = ({
|
|
|
64
64
|
}
|
|
65
65
|
const itemMeta = instance.getItemMeta(state.focusedItemId);
|
|
66
66
|
if (itemMeta) {
|
|
67
|
-
const itemElement =
|
|
67
|
+
const itemElement = instance.getItemDOMElement(state.focusedItemId);
|
|
68
68
|
if (itemElement) {
|
|
69
69
|
itemElement.blur();
|
|
70
70
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { useTreeViewItems } from './useTreeViewItems';
|
|
2
|
-
export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsDefaultizedParameters, UseTreeViewItemsState, } from './useTreeViewItems.types';
|
|
2
|
+
export type { UseTreeViewItemsSignature, UseTreeViewItemsParameters, UseTreeViewItemsDefaultizedParameters, UseTreeViewItemsState, TreeViewItemToRenderProps, } from './useTreeViewItems.types';
|
|
3
3
|
export { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from './useTreeViewItems.utils';
|
|
@@ -5,6 +5,7 @@ import * as React from 'react';
|
|
|
5
5
|
import { publishTreeViewEvent } from "../../utils/publishTreeViewEvent.js";
|
|
6
6
|
import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "./useTreeViewItems.utils.js";
|
|
7
7
|
import { TreeViewItemDepthContext } from "../../TreeViewItemDepthContext/index.js";
|
|
8
|
+
import { generateTreeItemIdAttribute } from "../../corePlugins/useTreeViewId/useTreeViewId.utils.js";
|
|
8
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
10
|
const updateItemsState = ({
|
|
10
11
|
items,
|
|
@@ -110,7 +111,11 @@ export const useTreeViewItems = ({
|
|
|
110
111
|
if (itemMeta == null) {
|
|
111
112
|
return null;
|
|
112
113
|
}
|
|
113
|
-
return document.getElementById(
|
|
114
|
+
return document.getElementById(generateTreeItemIdAttribute({
|
|
115
|
+
treeId: state.id.treeId,
|
|
116
|
+
itemId,
|
|
117
|
+
id: itemMeta.idAttribute
|
|
118
|
+
}));
|
|
114
119
|
};
|
|
115
120
|
const isItemNavigable = itemId => {
|
|
116
121
|
if (params.disabledItemsFocusable) {
|
|
@@ -200,7 +205,9 @@ useTreeViewItems.getInitialState = params => ({
|
|
|
200
205
|
getItemLabel: params.getItemLabel
|
|
201
206
|
})
|
|
202
207
|
});
|
|
203
|
-
useTreeViewItems.getDefaultizedParams =
|
|
208
|
+
useTreeViewItems.getDefaultizedParams = ({
|
|
209
|
+
params
|
|
210
|
+
}) => _extends({}, params, {
|
|
204
211
|
disabledItemsFocusable: params.disabledItemsFocusable ?? false,
|
|
205
212
|
itemChildrenIndentation: params.itemChildrenIndentation ?? '12px'
|
|
206
213
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { TreeViewItemMeta, DefaultizedProps, TreeViewPluginSignature } from '../../models';
|
|
3
3
|
import { TreeViewBaseItem, TreeViewItemId } from '../../../models';
|
|
4
|
-
interface
|
|
4
|
+
export interface TreeViewItemToRenderProps {
|
|
5
5
|
label: string;
|
|
6
6
|
itemId: string;
|
|
7
7
|
id: string | undefined;
|
|
8
|
-
children?:
|
|
8
|
+
children?: TreeViewItemToRenderProps[];
|
|
9
9
|
}
|
|
10
10
|
export interface UseTreeViewItemsPublicAPI<R extends {}> {
|
|
11
11
|
/**
|
|
@@ -31,7 +31,7 @@ export interface UseTreeViewItemsPublicAPI<R extends {}> {
|
|
|
31
31
|
getItemOrderedChildrenIds: (itemId: TreeViewItemId | null) => TreeViewItemId[];
|
|
32
32
|
/**
|
|
33
33
|
* Get all the items in the same format as provided by `props.items`.
|
|
34
|
-
* @returns {
|
|
34
|
+
* @returns {TreeViewItemToRenderProps[]} The items in the tree.
|
|
35
35
|
*/
|
|
36
36
|
getItemTree: () => TreeViewBaseItem[];
|
|
37
37
|
}
|
|
@@ -46,10 +46,10 @@ export interface UseTreeViewItemsInstance<R extends {}> extends UseTreeViewItems
|
|
|
46
46
|
/**
|
|
47
47
|
* Get the item that should be rendered.
|
|
48
48
|
* This method is only used on Rich Tree View components.
|
|
49
|
-
* Check the `
|
|
50
|
-
* @returns {
|
|
49
|
+
* Check the `TreeViewItemToRenderProps` type for more information.
|
|
50
|
+
* @returns {TreeViewItemToRenderProps[]} The items to render.
|
|
51
51
|
*/
|
|
52
|
-
getItemsToRender: () =>
|
|
52
|
+
getItemsToRender: () => TreeViewItemToRenderProps[];
|
|
53
53
|
/**
|
|
54
54
|
* Check if a given item is disabled.
|
|
55
55
|
* An item is disabled if it was marked as disabled or if one of its ancestors is disabled.
|
|
@@ -8,6 +8,7 @@ import { useTreeViewContext } from "../../TreeViewProvider/index.js";
|
|
|
8
8
|
import { TreeViewChildrenItemContext, TreeViewChildrenItemProvider } from "../../TreeViewProvider/TreeViewChildrenItemProvider.js";
|
|
9
9
|
import { buildSiblingIndexes, TREE_VIEW_ROOT_PARENT_ID } from "../useTreeViewItems/useTreeViewItems.utils.js";
|
|
10
10
|
import { TreeViewItemDepthContext } from "../../TreeViewItemDepthContext/index.js";
|
|
11
|
+
import { generateTreeItemIdAttribute } from "../../corePlugins/useTreeViewId/useTreeViewId.utils.js";
|
|
11
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
13
|
export const useTreeViewJSXItems = ({
|
|
13
14
|
instance,
|
|
@@ -98,7 +99,8 @@ const useTreeViewJSXItemsItemPlugin = ({
|
|
|
98
99
|
contentRef
|
|
99
100
|
}) => {
|
|
100
101
|
const {
|
|
101
|
-
instance
|
|
102
|
+
instance,
|
|
103
|
+
treeId
|
|
102
104
|
} = useTreeViewContext();
|
|
103
105
|
const {
|
|
104
106
|
children,
|
|
@@ -122,12 +124,16 @@ const useTreeViewJSXItemsItemPlugin = ({
|
|
|
122
124
|
|
|
123
125
|
// Prevent any flashing
|
|
124
126
|
useEnhancedEffect(() => {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
+
const idAttribute = generateTreeItemIdAttribute({
|
|
128
|
+
itemId,
|
|
129
|
+
treeId,
|
|
130
|
+
id
|
|
131
|
+
});
|
|
132
|
+
registerChild(idAttribute, itemId);
|
|
127
133
|
return () => {
|
|
128
|
-
unregisterChild(
|
|
134
|
+
unregisterChild(idAttribute);
|
|
129
135
|
};
|
|
130
|
-
}, [
|
|
136
|
+
}, [registerChild, unregisterChild, itemId, id, treeId]);
|
|
131
137
|
React.useEffect(() => {
|
|
132
138
|
return instance.insertJSXItem({
|
|
133
139
|
id: itemId,
|
|
@@ -153,6 +153,9 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
153
153
|
// If the focused item is collapsed and has children, we expand it
|
|
154
154
|
case key === 'ArrowRight' && !isRtl || key === 'ArrowLeft' && isRtl:
|
|
155
155
|
{
|
|
156
|
+
if (ctrlPressed) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
156
159
|
if (instance.isItemExpanded(itemId)) {
|
|
157
160
|
const nextItemId = getNextNavigableItem(instance, itemId);
|
|
158
161
|
if (nextItemId) {
|
|
@@ -170,6 +173,9 @@ export const useTreeViewKeyboardNavigation = ({
|
|
|
170
173
|
// If the focused item is collapsed and has a parent, we move the focus to this parent
|
|
171
174
|
case key === 'ArrowLeft' && !isRtl || key === 'ArrowRight' && isRtl:
|
|
172
175
|
{
|
|
176
|
+
if (ctrlPressed) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
173
179
|
if (canToggleItemExpansion(itemId) && instance.isItemExpanded(itemId)) {
|
|
174
180
|
instance.toggleItemExpansion(event, itemId);
|
|
175
181
|
event.preventDefault();
|
|
@@ -6,14 +6,8 @@ export const useTreeViewLabel = ({
|
|
|
6
6
|
instance,
|
|
7
7
|
state,
|
|
8
8
|
setState,
|
|
9
|
-
params
|
|
10
|
-
experimentalFeatures
|
|
9
|
+
params
|
|
11
10
|
}) => {
|
|
12
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
13
|
-
if (params.isItemEditable && !experimentalFeatures?.labelEditing) {
|
|
14
|
-
warnOnce(['MUI X: The label editing feature requires the `labelEditing` experimental feature to be enabled.', 'You can do it by passing `experimentalFeatures={{ labelEditing: true}}` to the `RichTreeViewPro` component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/editing/']);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
11
|
const editedItemRef = React.useRef(state.editedItemId);
|
|
18
12
|
const isItemBeingEditedRef = itemId => editedItemRef.current === itemId;
|
|
19
13
|
const setEditedItemId = editedItemId => {
|
|
@@ -23,7 +17,7 @@ export const useTreeViewLabel = ({
|
|
|
23
17
|
editedItemRef.current = editedItemId;
|
|
24
18
|
};
|
|
25
19
|
const isItemBeingEdited = itemId => itemId === state.editedItemId;
|
|
26
|
-
const isTreeViewEditable = Boolean(params.isItemEditable)
|
|
20
|
+
const isTreeViewEditable = Boolean(params.isItemEditable);
|
|
27
21
|
const isItemEditable = itemId => {
|
|
28
22
|
if (itemId == null || !isTreeViewEditable) {
|
|
29
23
|
return false;
|
|
@@ -72,6 +66,20 @@ export const useTreeViewLabel = ({
|
|
|
72
66
|
};
|
|
73
67
|
};
|
|
74
68
|
useTreeViewLabel.itemPlugin = useTreeViewLabelItemPlugin;
|
|
69
|
+
useTreeViewLabel.getDefaultizedParams = ({
|
|
70
|
+
params,
|
|
71
|
+
experimentalFeatures
|
|
72
|
+
}) => {
|
|
73
|
+
const canUseFeature = experimentalFeatures?.labelEditing;
|
|
74
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
75
|
+
if (params.isItemEditable && !canUseFeature) {
|
|
76
|
+
warnOnce(['MUI X: The label editing feature requires the `labelEditing` experimental feature to be enabled.', 'You can do it by passing `experimentalFeatures={{ labelEditing: true}}` to the `RichTreeViewPro` component.', 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/editing/']);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return _extends({}, params, {
|
|
80
|
+
isItemEditable: canUseFeature ? params.isItemEditable ?? false : false
|
|
81
|
+
});
|
|
82
|
+
};
|
|
75
83
|
useTreeViewLabel.getInitialState = () => ({
|
|
76
84
|
editedItemId: null
|
|
77
85
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TreeViewPluginSignature } from '../../models';
|
|
1
|
+
import { DefaultizedProps, TreeViewPluginSignature } from '../../models';
|
|
2
2
|
import { TreeViewItemId } from '../../../models';
|
|
3
3
|
import { UseTreeViewItemsSignature } from '../useTreeViewItems';
|
|
4
4
|
import { TreeItem2LabelInputProps } from '../../../TreeItem2LabelInput';
|
|
@@ -59,12 +59,13 @@ export interface UseTreeViewLabelParameters<R extends {}> {
|
|
|
59
59
|
*/
|
|
60
60
|
isItemEditable?: boolean | ((item: R) => boolean);
|
|
61
61
|
}
|
|
62
|
+
export type UseTreeViewLabelDefaultizedParameters<R extends {}> = DefaultizedProps<UseTreeViewLabelParameters<R>, 'isItemEditable'>;
|
|
62
63
|
export interface UseTreeViewLabelState {
|
|
63
64
|
editedItemId: string | null;
|
|
64
65
|
}
|
|
65
66
|
export type UseTreeViewLabelSignature = TreeViewPluginSignature<{
|
|
66
67
|
params: UseTreeViewLabelParameters<any>;
|
|
67
|
-
defaultizedParams:
|
|
68
|
+
defaultizedParams: UseTreeViewLabelDefaultizedParameters<any>;
|
|
68
69
|
publicAPI: UseTreeViewLabelPublicAPI;
|
|
69
70
|
instance: UseTreeViewLabelInstance;
|
|
70
71
|
state: UseTreeViewLabelState;
|