diff --git a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js index d7a4285c49c21..1b76b33540846 100644 --- a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js +++ b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.js @@ -23,7 +23,7 @@ const useTreeViewLogExpanded = ({ params, models }) => { }; // Sets the default value of this plugin parameters. -useTreeViewLogExpanded.getDefaultizedParams = (params) => ({ +useTreeViewLogExpanded.getDefaultizedParams = ({ params }) => ({ ...params, areLogsEnabled: params.areLogsEnabled ?? false, }); diff --git a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx index 70285558cbb90..5c6942d61458b 100644 --- a/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx +++ b/docs/data/tree-view/rich-tree-view/headless/LogExpandedItems.tsx @@ -56,7 +56,7 @@ const useTreeViewLogExpanded: TreeViewPlugin<TreeViewLogExpandedSignature> = ({ }; // Sets the default value of this plugin parameters. -useTreeViewLogExpanded.getDefaultizedParams = (params) => ({ +useTreeViewLogExpanded.getDefaultizedParams = ({ params }) => ({ ...params, areLogsEnabled: params.areLogsEnabled ?? false, }); diff --git a/docs/data/tree-view/rich-tree-view/headless/headless.md b/docs/data/tree-view/rich-tree-view/headless/headless.md index 6afb2d8403a04..8d1c35ea57f04 100644 --- a/docs/data/tree-view/rich-tree-view/headless/headless.md +++ b/docs/data/tree-view/rich-tree-view/headless/headless.md @@ -56,7 +56,7 @@ const useCustomPlugin = ({ params }) => { useCustomPlugin.params = { customParam: true }; -useCustomPlugin.getDefaultizedParams = (params) => ({ +useCustomPlugin.getDefaultizedParams = ({ params }) => ({ ...params, customParam: params.customParam ?? false, }); @@ -76,7 +76,7 @@ useCustomPlugin.params = { customModel: true, }; -useCustomPlugin.getDefaultizedParams = (params) => ({ +useCustomPlugin.getDefaultizedParams = ({ params }) => ({ ...params, // ... other defaultized params defaultCustomModel: params.defaultCustomModel ?? false, diff --git a/packages/x-tree-view-pro/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.ts b/packages/x-tree-view-pro/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.ts index a840f2d074b4a..263083dce4a99 100644 --- a/packages/x-tree-view-pro/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.ts +++ b/packages/x-tree-view-pro/src/internals/plugins/useTreeViewItemsReordering/useTreeViewItemsReordering.ts @@ -20,27 +20,10 @@ export const useTreeViewItemsReordering: TreeViewPlugin<UseTreeViewItemsReorderi instance, state, setState, - experimentalFeatures, }) => { - const isItemsReorderingEnabled = - params.itemsReordering && !!experimentalFeatures?.itemsReordering; - - if (process.env.NODE_ENV !== 'production') { - if ( - params.itemsReordering && - (!experimentalFeatures?.indentationAtItemLevel || !experimentalFeatures?.itemsReordering) - ) { - warnOnce([ - 'MUI X: The items reordering feature requires the `indentationAtItemLevel` and `itemsReordering` experimental features to be enabled.', - 'You can do it by passing `experimentalFeatures={{ indentationAtItemLevel: true, itemsReordering: true }}` to the `RichTreeViewPro` component.', - 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/', - ]); - } - } - const canItemBeDragged = React.useCallback( (itemId: string) => { - if (!isItemsReorderingEnabled) { + if (!params.itemsReordering) { return false; } @@ -51,7 +34,7 @@ export const useTreeViewItemsReordering: TreeViewPlugin<UseTreeViewItemsReorderi return true; }, - [isItemsReorderingEnabled, params.isItemReorderable], + [params.itemsReordering, params.isItemReorderable], ); const getDroppingTargetValidActions = React.useCallback( @@ -256,7 +239,7 @@ export const useTreeViewItemsReordering: TreeViewPlugin<UseTreeViewItemsReorderi }, contextValue: { itemsReordering: { - enabled: isItemsReorderingEnabled, + enabled: params.itemsReordering, currentDrag: state.itemsReordering, }, }, @@ -265,10 +248,25 @@ export const useTreeViewItemsReordering: TreeViewPlugin<UseTreeViewItemsReorderi useTreeViewItemsReordering.itemPlugin = useTreeViewItemsReorderingItemPlugin; -useTreeViewItemsReordering.getDefaultizedParams = (params) => ({ - ...params, - itemsReordering: params.itemsReordering ?? false, -}); +useTreeViewItemsReordering.getDefaultizedParams = ({ params, experimentalFeatures }) => { + const canUseFeature = + experimentalFeatures?.indentationAtItemLevel && experimentalFeatures?.itemsReordering; + + if (process.env.NODE_ENV !== 'production') { + if (params.itemsReordering && !canUseFeature) { + warnOnce([ + 'MUI X: The items reordering feature requires the `indentationAtItemLevel` and `itemsReordering` experimental features to be enabled.', + 'You can do it by passing `experimentalFeatures={{ indentationAtItemLevel: true, itemsReordering: true }}` to the `RichTreeViewPro` component.', + 'Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/', + ]); + } + } + + return { + ...params, + itemsReordering: canUseFeature ? (params.itemsReordering ?? false) : false, + }; +}; useTreeViewItemsReordering.getInitialState = () => ({ itemsReordering: null }); diff --git a/packages/x-tree-view/src/internals/models/plugin.ts b/packages/x-tree-view/src/internals/models/plugin.ts index 9dda02da75653..cb5e819e30c91 100644 --- a/packages/x-tree-view/src/internals/models/plugin.ts +++ b/packages/x-tree-view/src/internals/models/plugin.ts @@ -150,9 +150,10 @@ export type TreeRootWrapper<TSignatures extends readonly TreeViewAnyPluginSignat export type TreeViewPlugin<TSignature extends TreeViewAnyPluginSignature> = { (options: TreeViewPluginOptions<TSignature>): TreeViewResponse<TSignature>; - getDefaultizedParams?: ( - params: TreeViewUsedParams<TSignature>, - ) => TSignature['defaultizedParams']; + getDefaultizedParams?: (options: { + params: TreeViewUsedParams<TSignature>; + experimentalFeatures: TreeViewUsedExperimentalFeatures<TSignature>; + }) => TSignature['defaultizedParams']; getInitialState?: (params: TreeViewUsedDefaultizedParams<TSignature>) => TSignature['state']; models?: TreeViewModelsInitializer<TSignature>; params: Record<keyof TSignature['params'], true>; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts index b9dabd1bd1a25..d01813aeab710 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewExpansion/useTreeViewExpansion.ts @@ -122,7 +122,7 @@ useTreeViewExpansion.models = { const DEFAULT_EXPANDED_ITEMS: string[] = []; -useTreeViewExpansion.getDefaultizedParams = (params) => ({ +useTreeViewExpansion.getDefaultizedParams = ({ params }) => ({ ...params, defaultExpandedItems: params.defaultExpandedItems ?? DEFAULT_EXPANDED_ITEMS, }); diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.tsx b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.tsx index 01ac6d4de49c7..71b6717225542 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.tsx +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewItems/useTreeViewItems.tsx @@ -290,7 +290,7 @@ useTreeViewItems.getInitialState = (params) => ({ }), }); -useTreeViewItems.getDefaultizedParams = (params) => ({ +useTreeViewItems.getDefaultizedParams = ({ params }) => ({ ...params, disabledItemsFocusable: params.disabledItemsFocusable ?? false, itemChildrenIndentation: params.itemChildrenIndentation ?? '12px', diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.ts index 1a314fff4a9ac..ef43558d8394a 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.ts @@ -10,17 +10,7 @@ export const useTreeViewLabel: TreeViewPlugin<UseTreeViewLabelSignature> = ({ state, setState, params, - experimentalFeatures, }) => { - if (process.env.NODE_ENV !== 'production') { - if (params.isItemEditable && !experimentalFeatures?.labelEditing) { - 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/', - ]); - } - } const editedItemRef = React.useRef(state.editedItemId); const isItemBeingEditedRef = (itemId: TreeViewItemId) => editedItemRef.current === itemId; @@ -32,7 +22,7 @@ export const useTreeViewLabel: TreeViewPlugin<UseTreeViewLabelSignature> = ({ const isItemBeingEdited = (itemId: TreeViewItemId) => itemId === state.editedItemId; - const isTreeViewEditable = Boolean(params.isItemEditable) && !!experimentalFeatures.labelEditing; + const isTreeViewEditable = Boolean(params.isItemEditable); const isItemEditable = (itemId: TreeViewItemId): boolean => { if (itemId == null || !isTreeViewEditable) { @@ -95,6 +85,24 @@ export const useTreeViewLabel: TreeViewPlugin<UseTreeViewLabelSignature> = ({ useTreeViewLabel.itemPlugin = useTreeViewLabelItemPlugin; +useTreeViewLabel.getDefaultizedParams = ({ params, experimentalFeatures }) => { + const canUseFeature = experimentalFeatures?.labelEditing; + if (process.env.NODE_ENV !== 'production') { + if (params.isItemEditable && !canUseFeature) { + 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/', + ]); + } + } + + return { + ...params, + isItemEditable: canUseFeature ? (params.isItemEditable ?? false) : false, + }; +}; + useTreeViewLabel.getInitialState = () => ({ editedItemId: null, }); diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.ts index 12f5296ef61ab..3f23f27ca86d1 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewLabel/useTreeViewLabel.types.ts @@ -1,4 +1,4 @@ -import { TreeViewPluginSignature } from '../../models'; +import { DefaultizedProps, TreeViewPluginSignature } from '../../models'; import { TreeViewItemId } from '../../../models'; import { UseTreeViewItemsSignature } from '../useTreeViewItems'; import { TreeItem2LabelInputProps } from '../../../TreeItem2LabelInput'; @@ -63,13 +63,18 @@ export interface UseTreeViewLabelParameters<R extends {}> { isItemEditable?: boolean | ((item: R) => boolean); } +export type UseTreeViewLabelDefaultizedParameters<R extends {}> = DefaultizedProps< + UseTreeViewLabelParameters<R>, + 'isItemEditable' +>; + export interface UseTreeViewLabelState { editedItemId: string | null; } export type UseTreeViewLabelSignature = TreeViewPluginSignature<{ params: UseTreeViewLabelParameters<any>; - defaultizedParams: UseTreeViewLabelParameters<any>; + defaultizedParams: UseTreeViewLabelDefaultizedParameters<any>; publicAPI: UseTreeViewLabelPublicAPI; instance: UseTreeViewLabelInstance; state: UseTreeViewLabelState; diff --git a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts index 048f429a4fe0a..c24fad0b6bbe5 100644 --- a/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts +++ b/packages/x-tree-view/src/internals/plugins/useTreeViewSelection/useTreeViewSelection.ts @@ -226,7 +226,7 @@ useTreeViewSelection.models = { const DEFAULT_SELECTED_ITEMS: string[] = []; -useTreeViewSelection.getDefaultizedParams = (params) => ({ +useTreeViewSelection.getDefaultizedParams = ({ params }) => ({ ...params, disableSelection: params.disableSelection ?? false, multiSelect: params.multiSelect ?? false, diff --git a/packages/x-tree-view/src/internals/useTreeView/extractPluginParamsFromProps.ts b/packages/x-tree-view/src/internals/useTreeView/extractPluginParamsFromProps.ts index cc81cb92400e2..a78619a421d5a 100644 --- a/packages/x-tree-view/src/internals/useTreeView/extractPluginParamsFromProps.ts +++ b/packages/x-tree-view/src/internals/useTreeView/extractPluginParamsFromProps.ts @@ -28,7 +28,7 @@ export const extractPluginParamsFromProps = < TSignatures extends readonly TreeViewPluginSignature<any>[], TProps extends Partial<UseTreeViewBaseProps<TSignatures>>, >({ - props: { slots, slotProps, apiRef, experimentalFeatures, ...props }, + props: { slots, slotProps, apiRef, experimentalFeatures: inExperimentalFeatures, ...props }, plugins, }: ExtractPluginParamsFromPropsParameters< TSignatures, @@ -54,10 +54,16 @@ export const extractPluginParamsFromProps = < } }); + const experimentalFeatures = + inExperimentalFeatures ?? ({} as NonNullable<typeof inExperimentalFeatures>); + const defaultizedPluginParams = plugins.reduce( (acc, plugin: TreeViewPlugin<TreeViewAnyPluginSignature>) => { if (plugin.getDefaultizedParams) { - return plugin.getDefaultizedParams(acc); + return plugin.getDefaultizedParams({ + params: acc, + experimentalFeatures, + }); } return acc; @@ -71,6 +77,6 @@ export const extractPluginParamsFromProps = < pluginParams: defaultizedPluginParams, slots: slots ?? ({} as any), slotProps: slotProps ?? ({} as any), - experimentalFeatures: experimentalFeatures ?? ({} as any), + experimentalFeatures, }; };