## Tree Display a Tree structure Category: Navigation ### Simple Example `Tree` component is used to display hierarchical data. `Tree` component has minimal styling by default, you can customize styles with Styles API. ```python import dash_mantine_components as dmc from .data import data component = dmc.Tree(data=data) ``` ### Data Data passed to the `data` prop should follow these rules: - Data must be an array - Each item in the array represents a node in the tree - Each node must be a dictionary with value and label keys - Each node can have children key with an array of child nodes - The value of each node must be unique ```python # ✅ Valid data, all values are unique valid_data = [ { "value": "src", "label": "src", "children": [ {"value": "src/components", "label": "components"}, {"value": "src/hooks", "label": "hooks"}, ], }, {"value": "package.json", "label": "package.json"}, ] # ❌ Invalid data, values are not unique (components is used twice) invalid_data = [ { "value": "src", "label": "src", "children": [{"value": "components", "label": "components"}], }, {"value": "components", "label": "components"}, ] ``` ### Icon Side The expanded and collapsed icons are on the left side of the label by default. To move them to the right side, set `iconSide="right` ```python import dash_mantine_components as dmc from .data import data component = dmc.Tree(data=data, iconSide="right") ``` ### Remove Expanded Icon By default the `Tree` includes a chevron to indicate expanded and collapsed nodes. To remove the icons, set `expandedIcon=None` ```python import dash_mantine_components as dmc from .data import data component = dmc.Tree(data=data, expandedIcon=None) ``` ### Change Expanded Icon Use any icon in the `expandedIcon` prop. If no `collapsedIcon` is set, the icon will be rotated to indicate the collapsed state. ```python import dash_mantine_components as dmc from dash_iconify import DashIconify from .data import data component = dmc.Tree( data=data, expandedIcon=DashIconify(icon="fa6-solid:arrow-down") ) ``` ### Change Expanded and Collapsed Icons When both the `expandedIcon` and `collapsedIcon` props are set, the icons will not be rotated. ```python import dash_mantine_components as dmc from dash_iconify import DashIconify from .data import data component = dmc.Tree( data=data, expandedIcon=DashIconify(icon="fa6-regular:folder-open"), collapsedIcon=DashIconify(icon="fa6-solid:folder-plus"), ) ``` ### Set Expanded state To set the state of the nodes, use the `expanded` prop. Note that leaf nodes can be included, but it will only change the expanded/collapsed display of the nodes with children. ```python import json import dash_mantine_components as dmc from dash import callback, Input, Output from .data import data component = dmc.Stack([ dmc.Tree( data=data, expanded=[ "node_modules", "node_modules/@mantine", "node_modules/@mantine/form", "node_modules/@mantine/form/index.d.ts", ], id="tree-expanded" ), dmc.CodeHighlight(id="expanded-nodes", code="", language="json"), ]) @callback( Output("expanded-nodes", "code"), Input("tree-expanded", "expanded") ) def update(expanded): return json.dumps( expanded, indent=4) ``` ### Expand or Collapse All Expand all will include all items of the `data` prop in the `expanded` prop. ```python import dash_mantine_components as dmc from dash import callback, Input, Output from .data import data component = dmc.Box([ dmc.SegmentedControl( id="tree-expand-all", data=["Expand All", "Collapse All"], value="Collapse All", mb="sm" ), dmc.Tree( data=data, id="tree-all" ) ],p="lg") @callback( Output("tree-all", "expanded"), Input("tree-expand-all", "value") ) def update(value): if value=="Collapse All": return [] return '*' ``` ### Expanded State in callbacks. When using the expanded property as a callback input to track the user's selected expanded state, note that the `expanded` list may include or exclude leaf nodes (nodes without children) depending on user interaction. This happens because users can toggle the state of leaf nodes, even though they don’t affect how the tree data is displayed. To handle this, ensure your callback logic accounts for the possibility that leaf nodes may or may not be present in the `expanded` prop. Note also that the nodes included in the `expanded` prop are ordered based on user interation and the order of operations. ### With Checkboxes Use the `checked` prop to set or track the checked items. Note that only leaves can be checked, and the order will be based on user interation and the order of operations. ```python import json import dash_mantine_components as dmc from dash import callback, Input, Output from .data import data component = dmc.Stack([ dmc.Tree(data=data, checkboxes=True, id="tree-checkboxes" ), dmc.CodeHighlight(id="checked-nodes", code="", language="json"), ]) @callback( Output("checked-nodes", "code"), Input("tree-checkboxes", "checked") ) def update(checked): return json.dumps( checked, indent=4) ``` ### Custom Tree rendering By default, `dmc.Tree` includes a built-in `renderNode` function that covers most common use cases. It requires no JavaScript and supports some customization through props like `checkboxes`, `expandedIcon`, and `iconSide`. If you need more control over how each node is rendered, such as using custom icons based on the data, arranging content differently or advanced styling, you can provide your own `renderNode` function written in JavaScript. This advanced feature is designed for use cases that go beyond what the built-in options support. #### Ignored Props When you supply your own `renderNode` function, the following props are ignored: * `checkboxes` * `expandedIcon` * `collapsedIcon` * `iconSide` These props only apply when you're using the default built-in renderer. If you're using a custom `renderNode`, you are responsible for rendering icons, checkboxes, or any other visual element. #### Example: Files Tree Note: This example uses custom JavaScript defined in the assets folder. Learn more in the "Functions As Props" section of this document. ```python import dash_mantine_components as dmc import dash_iconify # required in order to use DashIconify in the renderNode function from .data import data component = dmc.Tree( data=data, renderNode={"function": "myLeaf"}, expanded=[ "node_modules", "node_modules/react", ] ) ``` ```javascript var dmcfuncs = window.dashMantineFunctions = window.dashMantineFunctions || {}; dmcfuncs.myLeaf = function (payload) { const dmc = window.dash_mantine_components; const iconify = window.dash_iconify; function getIcon(name, isFolder, expanded) { const size = 14; if (name.endsWith('package.json')) { return React.createElement(iconify.DashIconify, { icon: 'logos:npm-icon', width: size, height: size }); } if ( name.endsWith('.ts') || name.endsWith('.tsx') || name.endsWith('tsconfig.json') ) { return React.createElement(iconify.DashIconify, { icon: 'logos:typescript-icon', width: size, height: size }); } if (name.endsWith('.css')) { return React.createElement(iconify.DashIconify, { icon: 'vscode-icons:file-type-css', width: size, height: size }); } if (isFolder) { return React.createElement(iconify.DashIconify, { icon: expanded ? 'tabler:folder-open' : 'tabler:folder', width: size, height: size, color: '#f59f00' // Mantine yellow-9 }); } return null; } const { node, expanded, hasChildren, elementProps } = payload; return React.createElement( dmc.Group, { key: payload.node.value, gap: 5, ...elementProps }, getIcon(node.value, hasChildren, expanded), React.createElement('span', null, node.label) ); }; ``` #### Example: Tree with Checkboxes Note: This example uses custom JavaScript defined in the assets folder. Learn more in the "Functions As Props" section of this document. If the "With Checkboxes" example above does not meet your needs, you can use the `renderNode` prop to fully customize how each tree node is rendered using JavaScript. When using a custom `renderNode`, you are responsible for implementing the checkbox and expand/collapse logic yourself. To handle the checked state, you'll need to render a `CheckboxIndicator` manually inside your custom render function and call `tree.checkNode(...)` or `tree.uncheckNode(...)` to update it. ```python import json import dash_mantine_components as dmc from dash import callback, Input, Output import dash_iconify # necessary to import here in order to use in the renderNode function from .data import data component = dmc.Stack([ dmc.Tree( data=data, levelOffset=23, expandOnClick=False, renderNode={"function": "myLeafCheckbox"}, id="tree-checkboxes-renderNode" ), dmc.CodeHighlight(id="checked-nodes-renderNode", code="", language="json"), ]) @callback( Output("checked-nodes-renderNode", "code"), Input("tree-checkboxes-renderNode", "checked") ) def update(checked): return json.dumps( checked, indent=4) ``` ```javascript var dmcfuncs = window.dashMantineFunctions = window.dashMantineFunctions || {}; dmcfuncs.myLeafCheckbox = function (payload) { const React = window.React; const dmc = window.dash_mantine_components; const iconify = window.dash_iconify; const { node, expanded, hasChildren, elementProps, tree } = payload; const checked = tree.isNodeChecked(node.value); const indeterminate = tree.isNodeIndeterminate(node.value); return React.createElement( dmc.Group, { key: node.value, gap: "xs", ...elementProps }, [ React.createElement(dmc.CheckboxIndicator, { key: "checkbox", checked, indeterminate, onClick: (e) => { e.stopPropagation(); if (checked) { tree.uncheckNode(node.value); } else { tree.checkNode(node.value); } }, }), React.createElement( dmc.Group, { key: "label-group", gap: 5, onClick: () => tree.toggleExpanded(node.value), }, [ React.createElement("span", { key: "label" }, node.label), hasChildren && React.createElement(iconify.DashIconify, { key: "icon", icon: "tabler:chevron-down", width: 14, style: { transform: expanded ? "rotate(180deg)" : "rotate(0deg)", transition: "transform 0.2s ease", }, }), ] ), ] ); }; ``` #### renderNode Arguments The `renderNode` function receives a single `payload` object with the following fields: ```js export interface RenderTreeNodePayload { /** Node level in the tree */ level: number; /** `true` if the node is expanded, applicable only for nodes with `children` */ expanded: boolean; /** `true` if the node has non-empty `children` array */ hasChildren: boolean; /** `true` if the node is selected */ selected: boolean; /** Node data from the `data` prop of `Tree` */ node: TreeNodeData; /** Tree controller instance, return value of `useTree` hook */ tree: TreeController; /** Props to spread into the root node element */ elementProps: { className: string; style: React.CSSProperties; onClick: (event: React.MouseEvent) => void; 'data-selected': boolean | undefined; 'data-value': string; 'data-hovered': boolean | undefined; }; } ``` ### Styles API This component supports Styles API. With Styles API, you can customize styles of any inner element. See the Styling and Theming sections of these docs for more information. #### Tree Selectors | Selector | Static selector | Description | |----------|--------------------------|-------------------------------------| | root | .mantine-Tree-root | Root element | | node | .mantine-Tree-node | Node element (`li`), contains label and subtree elements | | subtree | .mantine-Tree-subtree | Subtree element (`ul`) | | label | .mantine-Tree-label | Node label | #### Tree CSS Variables | Selector | Variable | Description | |----------|-----------------|---------------------------------------| | root | --level-offset | Controls offset of nested tree levels | #### Tree Data Attributes | Selector | Attribute | Condition | Value | |--------------|----------------|------------------------|------------------------| | node, label | data-selected | The node is selected | – | | node, label | data-hovered | The node is hovered | – | | node | data-level | – | Nesting level of the node | ### Keyword Arguments #### Tree - id (string; optional): Unique ID to identify this component in Dash callbacks. - allowRangeSelection (boolean; optional): Determines whether tree nodes range can be selected with click when Shift key is pressed, `True` by default. - aria-* (string; optional): Wild card aria attributes. - attributes (boolean | number | string | dict | list; optional): Passes attributes to inner elements of a component. See Styles API docs. - checkOnSpace (boolean; optional): Determines whether tree node should be checked on space key press, `False` by default. - checkboxes (boolean; optional): Determines if checkboxes should be rendered, `False` by default. Ignored when using a custom `renderNode` function. - checked (list of strings; optional): Determines checked nodes as a list of values (note that only leaves can be checked), `[]` by default. - className (string; optional): Class added to the root element, if applicable. - classNames (dict; optional): Adds custom CSS class names to inner elements of a component. See Styles API docs. - clearSelectionOnOutsideClick (boolean; optional): Determines whether selection should be cleared when user clicks outside of the tree, `False` by default. - collapsedIcon (a list of or a singular dash component, string or number; optional): Collapsed state icon. Ignored when using a custom `renderNode` function. - darkHidden (boolean; optional): Determines whether component should be hidden in dark color scheme with `display: none`. - data (list of dicts; required): Data used to render nodes. `data` is a list of dicts with keys: - data-* (string; optional): Wild card data attributes. - expandOnClick (boolean; optional): Determines whether tree node with children should be expanded on click, `True` by default. - expandOnSpace (boolean; optional): Determines whether tree node with children should be expanded on space key press, `True` by default. - expanded (list of strings; optional): Determines expanded nodes as a list of values or `'*'` for all, `[]` by default. - expandedIcon (a list of or a singular dash component, string or number; default ): Expanded state icon. Ignored when using a custom `renderNode` function. - hiddenFrom (string; optional): Breakpoint above which the component is hidden with `display: none`. - iconSide (a value equal to: 'left', 'right', 'none'; default 'left'): Side to display expanded/collapsed state icon on, `'left'` by default. Ignored when using a custom `renderNode` function. - levelOffset (string | number; optional): Horizontal padding of each subtree level, key of `theme.spacing` or any valid CSS value, `'lg'` by default. - lightHidden (boolean; optional): Determines whether component should be hidden in light color scheme with `display: none`. - loading_state (dict; optional): Object that holds the loading state object coming from dash-renderer. For use with dash<3. `loading_state` is a dict with keys: - mod (string | dict | list of string | dicts; optional): Element modifiers transformed into `data-` attributes. For example: "xl" or {"data-size": "xl"}. Can also be a list of strings or dicts for multiple modifiers. Falsy values are removed. - renderNode (boolean | number | string | dict | list; optional): A function to render the tree node label. Replaces the default component rendering See https://www.dash-mantine-components.com/functions-as-props. - selectOnClick (boolean; optional): Determines whether node should be selected on click, `False` by default. - selected (list of strings; optional): Determines selected nodes as a list of values, `[]` by default. - styles (boolean | number | string | dict | list; optional): Adds inline styles directly to inner elements of a component. See Styles API docs. - tabIndex (number; optional): tab-index. - variant (string; optional): variant. - visibleFrom (string; optional): Breakpoint below which the component is hidden with `display: none`.