Skip to content

Commit

Permalink
[TreeView] Always apply the indentation on the item content instead o…
Browse files Browse the repository at this point in the history
…f its parent's group (#15089)
  • Loading branch information
flaviendelangle authored Nov 7, 2024
1 parent fc5bd87 commit c2f8067
Show file tree
Hide file tree
Showing 48 changed files with 93 additions and 295 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,40 @@ All the new Tree Item-related components and utils (introduced in the previous m
- } from '@mui/x-tree-view/TreeItem2LabelInput';
+ } from '@mui/x-tree-view/TreeItemLabelInput';
```

## Apply the indentation on the item content instead of it's parent's group

The indentation of nested Tree Items is now applied on the content of the element.
This is required to support features like the drag and drop re-ordering which requires every Tree Item to go to the far left of the Tree View.

### Apply custom indentation

If you used to set custom indentation in your Tree Item, you can use the new `itemChildrenIndentation` prop to do it while supporting the new DOM structure:

```tsx
<RichTreeView
items={MUI_X_PRODUCTS}
itemChildrenIndentation={24}
defaultExpandedItems={['grid']}
/>
```

:::info
See [Tree Item Customization—Change nested item's indentation](/x/react-tree-view/tree-item-customization/#change-nested-items-indentation) for more details.
:::

### Fallback to the old behavior

If you used to style your content element (for example to add a border to it) and you don't use the drag and drop re-ordering, you can manually put the padding on the group transition element to restore the previous behavior:

```tsx
const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({
// Remove the additional padding of nested elements
padding: theme.spacing(0.5, 1),
}));

const CustomTreeItemGroupTransition = styled(TreeItemGroupTransition)({
// Add the padding back on the group transition element
paddingLeft: 'var(--TreeView-itemChildrenIndentation) !important',
});
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import Avatar from '@mui/material/Avatar';
import { RichTreeView } from '@mui/x-tree-view/RichTreeView';
Expand Down Expand Up @@ -37,10 +36,6 @@ const ITEMS = [
},
];

const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({
padding: theme.spacing(0.5, 1),
}));

const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
const { id, itemId, label, disabled, children, ...other } = props;

Expand All @@ -58,7 +53,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
return (
<TreeItemProvider itemId={itemId}>
<TreeItemRoot {...getRootProps(other)}>
<CustomTreeItemContent {...getContentProps()}>
<TreeItemContent {...getContentProps()}>
<TreeItemIconContainer {...getIconContainerProps()}>
<TreeItemIcon status={status} />
</TreeItemIconContainer>
Expand All @@ -77,7 +72,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
<TreeItemLabel {...getLabelProps()} />
</Box>
<TreeItemDragAndDropOverlay {...getDragAndDropOverlayProps()} />
</CustomTreeItemContent>
</TreeItemContent>
{children && <TreeItemGroupTransition {...getGroupTransitionProps()} />}
</TreeItemRoot>
</TreeItemProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import Avatar from '@mui/material/Avatar';
import { RichTreeView } from '@mui/x-tree-view/RichTreeView';
Expand Down Expand Up @@ -37,10 +36,6 @@ const ITEMS: TreeViewBaseItem[] = [
},
];

const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({
padding: theme.spacing(0.5, 1),
}));

interface CustomTreeItemProps
extends Omit<UseTreeItemParameters, 'rootRef'>,
Omit<React.HTMLAttributes<HTMLLIElement>, 'onFocus'> {}
Expand All @@ -65,7 +60,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(
return (
<TreeItemProvider itemId={itemId}>
<TreeItemRoot {...getRootProps(other)}>
<CustomTreeItemContent {...getContentProps()}>
<TreeItemContent {...getContentProps()}>
<TreeItemIconContainer {...getIconContainerProps()}>
<TreeItemIcon status={status} />
</TreeItemIconContainer>
Expand All @@ -84,7 +79,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(
<TreeItemLabel {...getLabelProps()} />
</Box>
<TreeItemDragAndDropOverlay {...getDragAndDropOverlayProps()} />
</CustomTreeItemContent>
</TreeItemContent>
{children && <TreeItemGroupTransition {...getGroupTransitionProps()} />}
</TreeItemRoot>
</TreeItemProvider>
Expand Down
1 change: 0 additions & 1 deletion docs/data/tree-view/rich-tree-view/ordering/DragAndDrop.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export default function DragAndDrop() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export default function DragAndDrop() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
/>
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ export default function FileExplorer() {
defaultExpandedItems={['1', '1.1']}
sx={{ height: 'fit-content', flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
slots={{ item: CustomTreeItem }}
experimentalFeatures={{ indentationAtItemLevel: true, itemsReordering: true }}
experimentalFeatures={{ itemsReordering: true }}
itemsReordering
canMoveItemToNewPosition={(params) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export default function FileExplorer() {
defaultExpandedItems={['1', '1.1']}
sx={{ height: 'fit-content', flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
slots={{ item: CustomTreeItem }}
experimentalFeatures={{ indentationAtItemLevel: true, itemsReordering: true }}
experimentalFeatures={{ itemsReordering: true }}
itemsReordering
canMoveItemToNewPosition={(params) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export default function OnItemPositionChange() {
items={MUI_X_PRODUCTS}
itemsReordering
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
defaultExpandedItems={['grid', 'pickers']}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export default function OnItemPositionChange() {
items={MUI_X_PRODUCTS}
itemsReordering
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
defaultExpandedItems={['grid', 'pickers']}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ export default function OnlyReorderFromDragHandle() {
items={MUI_X_PRODUCTS}
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
itemsReordering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ export default function OnlyReorderFromDragHandle() {
items={MUI_X_PRODUCTS}
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
itemsReordering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
items={MUI_X_PRODUCTS}
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
itemsReordering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export default function OnlyReorderInSameParent() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
canMoveItemToNewPosition={(params) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export default function OnlyReorderInSameParent() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
canMoveItemToNewPosition={(params) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
canMoveItemToNewPosition={(params) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export default function OnlyReorderLeaves() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
apiRef={apiRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export default function OnlyReorderLeaves() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
apiRef={apiRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
apiRef={apiRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export default function SendAllItemsToServer() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
onItemPositionChange={handleItemPositionChangeTreeViewA}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export default function SendAllItemsToServer() {
itemsReordering
defaultExpandedItems={['grid', 'pickers']}
experimentalFeatures={{
indentationAtItemLevel: true,
itemsReordering: true,
}}
onItemPositionChange={handleItemPositionChangeTreeViewA}
Expand Down
8 changes: 2 additions & 6 deletions docs/data/tree-view/rich-tree-view/ordering/ordering.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
<p class="description">Drag and drop your items to reorder them.</p>

:::success
To be able to reorder items, you first have to enable the `indentationAtItemLevel` and the `itemsReordering` experimental features:
To be able to reorder items, you first have to enable the `itemsReordering` experimental feature:

```tsx
<RichTreeViewPro
items={ITEMS}
experimentalFeatures={{ indentationAtItemLevel: true, itemsReordering: true }}
/>
<RichTreeViewPro items={ITEMS} experimentalFeatures={{ itemsReordering: true }} />
```

See [Tree Item Customization—Apply the nested item's indentation at the item level](/x/react-tree-view/tree-item-customization/#apply-the-nested-items-indentation-at-the-item-level) for more details.
:::

## Enable drag & drop re-ordering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({
color: theme.palette.text.secondary,
borderRadius: theme.spacing(2),
paddingRight: theme.spacing(1),
paddingLeft: `calc(${theme.spacing(1)} + var(--TreeView-itemChildrenIndentation) * var(--TreeView-itemDepth))`,
fontWeight: theme.typography.fontWeightMedium,
'&.expanded': {
fontWeight: theme.typography.fontWeightRegular,
Expand All @@ -50,15 +51,6 @@ const CustomTreeItemIconContainer = styled(TreeItemIconContainer)(({ theme }) =>
marginRight: theme.spacing(1),
}));

const CustomTreeItemGroupTransition = styled(TreeItemGroupTransition)(
({ theme }) => ({
marginLeft: 0,
[`& .content`]: {
paddingLeft: theme.spacing(2),
},
}),
);

const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
const theme = useTheme();
const {
Expand Down Expand Up @@ -127,9 +119,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
</Typography>
</Box>
</CustomTreeItemContent>
{children && (
<CustomTreeItemGroupTransition {...getGroupTransitionProps()} />
)}
{children && <TreeItemGroupTransition {...getGroupTransitionProps()} />}
</CustomTreeItemRoot>
</TreeItemProvider>
);
Expand All @@ -151,6 +141,7 @@ export default function GmailTreeView() {
endIcon: EndIcon,
}}
sx={{ flexGrow: 1, maxWidth: 400 }}
itemChildrenIndentation={20}
>
<CustomTreeItem itemId="1" label="All Mail" labelIcon={MailIcon} />
<CustomTreeItem itemId="2" label="Trash" labelIcon={DeleteIcon} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({
color: theme.palette.text.secondary,
borderRadius: theme.spacing(2),
paddingRight: theme.spacing(1),
paddingLeft: `calc(${theme.spacing(1)} + var(--TreeView-itemChildrenIndentation) * var(--TreeView-itemDepth))`,
fontWeight: theme.typography.fontWeightMedium,
'&.expanded': {
fontWeight: theme.typography.fontWeightRegular,
Expand All @@ -68,15 +69,6 @@ const CustomTreeItemIconContainer = styled(TreeItemIconContainer)(({ theme }) =>
marginRight: theme.spacing(1),
}));

const CustomTreeItemGroupTransition = styled(TreeItemGroupTransition)(
({ theme }) => ({
marginLeft: 0,
[`& .content`]: {
paddingLeft: theme.spacing(2),
},
}),
);

const CustomTreeItem = React.forwardRef(function CustomTreeItem(
props: StyledTreeItemProps,
ref: React.Ref<HTMLLIElement>,
Expand Down Expand Up @@ -148,9 +140,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(
</Typography>
</Box>
</CustomTreeItemContent>
{children && (
<CustomTreeItemGroupTransition {...getGroupTransitionProps()} />
)}
{children && <TreeItemGroupTransition {...getGroupTransitionProps()} />}
</CustomTreeItemRoot>
</TreeItemProvider>
);
Expand All @@ -172,6 +162,7 @@ export default function GmailTreeView() {
endIcon: EndIcon,
}}
sx={{ flexGrow: 1, maxWidth: 400 }}
itemChildrenIndentation={20}
>
<CustomTreeItem itemId="1" label="All Mail" labelIcon={MailIcon} />
<CustomTreeItem itemId="2" label="Trash" labelIcon={DeleteIcon} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import Avatar from '@mui/material/Avatar';
import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';
Expand All @@ -15,10 +14,6 @@ import {
import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon';
import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider';

const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({
padding: theme.spacing(0.5, 1),
}));

const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
const { id, itemId, label, disabled, children, ...other } = props;

Expand All @@ -35,7 +30,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
return (
<TreeItemProvider itemId={itemId}>
<TreeItemRoot {...getRootProps(other)}>
<CustomTreeItemContent {...getContentProps()}>
<TreeItemContent {...getContentProps()}>
<TreeItemIconContainer {...getIconContainerProps()}>
<TreeItemIcon status={status} />
</TreeItemIconContainer>
Expand All @@ -53,7 +48,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) {
</Avatar>
<TreeItemLabel {...getLabelProps()} />
</Box>
</CustomTreeItemContent>
</TreeItemContent>
{children && <TreeItemGroupTransition {...getGroupTransitionProps()} />}
</TreeItemRoot>
</TreeItemProvider>
Expand Down
Loading

0 comments on commit c2f8067

Please sign in to comment.