diff --git a/examples/storybooks/__snapshots__/storyshots.test.js.snap b/examples/storybooks/__snapshots__/storyshots.test.js.snap index e50f9fc5..6e78ed09 100644 --- a/examples/storybooks/__snapshots__/storyshots.test.js.snap +++ b/examples/storybooks/__snapshots__/storyshots.test.js.snap @@ -1398,3 +1398,338 @@ exports[`Storyshots Basics Minimal implementation 1`] = ` `; + +exports[`Storyshots Basics Modify nodes 1`] = ` +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + VIEW SOURCE → + +
+`; diff --git a/examples/storybooks/index.js b/examples/storybooks/index.js index b3f864eb..f55521f7 100644 --- a/examples/storybooks/index.js +++ b/examples/storybooks/index.js @@ -5,6 +5,7 @@ import { storiesOf } from '@storybook/react'; // import { action } from '@storybook/addon-actions'; import BarebonesExample from './barebones'; import AddRemoveExample from './add-remove'; +import ModifyNodesExample from './modify-nodes'; import ExternalNodeExample from './external-node'; import TouchSupportExample from './touch-support'; import TreeToTreeExample from './tree-to-tree'; @@ -31,6 +32,9 @@ storiesOf('Basics', module) ) .add('Add and remove nodes programmatically', () => wrapWithSource(, 'add-remove.js') + ) + .add('Modify nodes', () => + wrapWithSource(, 'modify-nodes.js') ); storiesOf('Advanced', module) diff --git a/examples/storybooks/modify-nodes.js b/examples/storybooks/modify-nodes.js new file mode 100644 index 00000000..c2d2cbf4 --- /dev/null +++ b/examples/storybooks/modify-nodes.js @@ -0,0 +1,53 @@ +import React, { Component } from 'react'; +import SortableTree, { changeNodeAtPath } from '../../src'; + +export default class App extends Component { + constructor(props) { + super(props); + + this.state = { + treeData: [ + { name: 'IT Manager' }, + { + name: 'Regional Manager', + expanded: true, + children: [{ name: 'Branch Manager' }], + }, + ], + }; + } + + render() { + const getNodeKey = ({ treeIndex }) => treeIndex; + return ( +
+
+ this.setState({ treeData })} + generateNodeProps={({ node, path }) => ({ + title: ( + { + const name = event.target.value; + + this.setState(state => ({ + treeData: changeNodeAtPath({ + treeData: state.treeData, + path, + getNodeKey, + newNode: { ...node, name }, + }), + })); + }} + /> + ), + })} + /> +
+
+ ); + } +} diff --git a/src/node-renderer-default.js b/src/node-renderer-default.js index 89f95f41..a85f1aec 100644 --- a/src/node-renderer-default.js +++ b/src/node-renderer-default.js @@ -27,6 +27,8 @@ class NodeRendererDefault extends Component { canDrop, canDrag, node, + title, + subtitle, draggedNode, path, treeIndex, @@ -45,6 +47,8 @@ class NodeRendererDefault extends Component { /* eslint-enable no-unused-vars */ ...otherProps } = this.props; + const nodeTitle = title || node.title; + const nodeSubtitle = subtitle || node.subtitle; let handle; if (canDrag) { @@ -143,24 +147,24 @@ class NodeRendererDefault extends Component { (node.subtitle ? ` ${styles.rowTitleWithSubtitle}` : '') } > - {typeof node.title === 'function' - ? node.title({ + {typeof nodeTitle === 'function' + ? nodeTitle({ node, path, treeIndex, }) - : node.title} + : nodeTitle} - {node.subtitle && + {nodeSubtitle && - {typeof node.subtitle === 'function' - ? node.subtitle({ + {typeof nodeSubtitle === 'function' + ? nodeSubtitle({ node, path, treeIndex, }) - : node.subtitle} + : nodeSubtitle} }
@@ -194,10 +198,14 @@ NodeRendererDefault.defaultProps = { parentNode: null, draggedNode: null, canDrop: false, + title: null, + subtitle: null, }; NodeRendererDefault.propTypes = { node: PropTypes.shape({}).isRequired, + title: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), + subtitle: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), path: PropTypes.arrayOf( PropTypes.oneOfType([PropTypes.string, PropTypes.number]) ).isRequired,