Skip to content

Commit fff72c6

Browse files
committedAug 5, 2017
feat(node-renderer): Make title and subtitle insertable via props
1 parent 0abba80 commit fff72c6

File tree

4 files changed

+407
-7
lines changed

4 files changed

+407
-7
lines changed
 

Diff for: ‎examples/storybooks/__snapshots__/storyshots.test.js.snap

+335
Original file line numberDiff line numberDiff line change
@@ -1398,3 +1398,338 @@ exports[`Storyshots Basics Minimal implementation 1`] = `
13981398
</a>
13991399
</div>
14001400
`;
1401+
1402+
exports[`Storyshots Basics Modify nodes 1`] = `
1403+
<div>
1404+
<div>
1405+
<div
1406+
style={
1407+
Object {
1408+
"height": 300,
1409+
}
1410+
}
1411+
>
1412+
<div
1413+
className="tree"
1414+
style={
1415+
Object {
1416+
"height": "100%",
1417+
}
1418+
}
1419+
>
1420+
<div>
1421+
<div
1422+
aria-label="grid"
1423+
className="ReactVirtualized__Grid ReactVirtualized__List virtualScrollOverride"
1424+
id={undefined}
1425+
onScroll={[Function]}
1426+
role="grid"
1427+
style={
1428+
Object {
1429+
"WebkitOverflowScrolling": "touch",
1430+
"boxSizing": "border-box",
1431+
"direction": "ltr",
1432+
"height": 99999,
1433+
"overflowX": "hidden",
1434+
"overflowY": "hidden",
1435+
"position": "relative",
1436+
"width": 200,
1437+
"willChange": "transform",
1438+
}
1439+
}
1440+
tabIndex={0}
1441+
>
1442+
<div
1443+
className="ReactVirtualized__Grid__innerScrollContainer"
1444+
style={
1445+
Object {
1446+
"height": 186,
1447+
"maxHeight": 186,
1448+
"maxWidth": 200,
1449+
"overflow": "hidden",
1450+
"pointerEvents": "",
1451+
"position": "relative",
1452+
"width": "auto",
1453+
}
1454+
}
1455+
>
1456+
<div
1457+
className="node"
1458+
style={
1459+
Object {
1460+
"height": 62,
1461+
"left": 0,
1462+
"position": "absolute",
1463+
"top": 0,
1464+
"width": "100%",
1465+
}
1466+
}
1467+
>
1468+
<div
1469+
className="lineBlock lineHalfHorizontalRight lineHalfVerticalBottom"
1470+
style={
1471+
Object {
1472+
"width": 44,
1473+
}
1474+
}
1475+
/>
1476+
<div
1477+
className="nodeContent"
1478+
style={
1479+
Object {
1480+
"left": 44,
1481+
}
1482+
}
1483+
>
1484+
<div
1485+
style={
1486+
Object {
1487+
"height": "100%",
1488+
}
1489+
}
1490+
>
1491+
<div
1492+
className="rowWrapper"
1493+
>
1494+
<div
1495+
className="row"
1496+
style={
1497+
Object {
1498+
"opacity": 1,
1499+
}
1500+
}
1501+
>
1502+
<div
1503+
className="moveHandle"
1504+
/>
1505+
<div
1506+
className="rowContents"
1507+
>
1508+
<div
1509+
className="rowLabel"
1510+
>
1511+
<span
1512+
className="rowTitle"
1513+
>
1514+
<input
1515+
onChange={[Function]}
1516+
style={
1517+
Object {
1518+
"fontSize": "1.1rem",
1519+
}
1520+
}
1521+
value="IT Manager"
1522+
/>
1523+
</span>
1524+
</div>
1525+
<div
1526+
className="rowToolbar"
1527+
/>
1528+
</div>
1529+
</div>
1530+
</div>
1531+
</div>
1532+
</div>
1533+
</div>
1534+
<div
1535+
className="node"
1536+
style={
1537+
Object {
1538+
"height": 62,
1539+
"left": 0,
1540+
"position": "absolute",
1541+
"top": 62,
1542+
"width": "100%",
1543+
}
1544+
}
1545+
>
1546+
<div
1547+
className="lineBlock lineHalfVerticalTop lineHalfHorizontalRight"
1548+
style={
1549+
Object {
1550+
"width": 44,
1551+
}
1552+
}
1553+
/>
1554+
<div
1555+
className="nodeContent"
1556+
style={
1557+
Object {
1558+
"left": 44,
1559+
}
1560+
}
1561+
>
1562+
<div
1563+
style={
1564+
Object {
1565+
"height": "100%",
1566+
}
1567+
}
1568+
>
1569+
<div>
1570+
<button
1571+
aria-label="Collapse"
1572+
className="collapseButton"
1573+
onClick={[Function]}
1574+
style={
1575+
Object {
1576+
"left": -22,
1577+
}
1578+
}
1579+
type="button"
1580+
/>
1581+
<div
1582+
className="lineChildren"
1583+
style={
1584+
Object {
1585+
"width": 44,
1586+
}
1587+
}
1588+
/>
1589+
</div>
1590+
<div
1591+
className="rowWrapper"
1592+
>
1593+
<div
1594+
className="row"
1595+
style={
1596+
Object {
1597+
"opacity": 1,
1598+
}
1599+
}
1600+
>
1601+
<div
1602+
className="moveHandle"
1603+
/>
1604+
<div
1605+
className="rowContents"
1606+
>
1607+
<div
1608+
className="rowLabel"
1609+
>
1610+
<span
1611+
className="rowTitle"
1612+
>
1613+
<input
1614+
onChange={[Function]}
1615+
style={
1616+
Object {
1617+
"fontSize": "1.1rem",
1618+
}
1619+
}
1620+
value="Regional Manager"
1621+
/>
1622+
</span>
1623+
</div>
1624+
<div
1625+
className="rowToolbar"
1626+
/>
1627+
</div>
1628+
</div>
1629+
</div>
1630+
</div>
1631+
</div>
1632+
</div>
1633+
<div
1634+
className="node"
1635+
style={
1636+
Object {
1637+
"height": 62,
1638+
"left": 0,
1639+
"position": "absolute",
1640+
"top": 124,
1641+
"width": "100%",
1642+
}
1643+
}
1644+
>
1645+
<div
1646+
className="lineBlock "
1647+
style={
1648+
Object {
1649+
"width": 44,
1650+
}
1651+
}
1652+
/>
1653+
<div
1654+
className="lineBlock lineHalfVerticalTop lineHalfHorizontalRight"
1655+
style={
1656+
Object {
1657+
"width": 44,
1658+
}
1659+
}
1660+
/>
1661+
<div
1662+
className="nodeContent"
1663+
style={
1664+
Object {
1665+
"left": 88,
1666+
}
1667+
}
1668+
>
1669+
<div
1670+
style={
1671+
Object {
1672+
"height": "100%",
1673+
}
1674+
}
1675+
>
1676+
<div
1677+
className="rowWrapper"
1678+
>
1679+
<div
1680+
className="row"
1681+
style={
1682+
Object {
1683+
"opacity": 1,
1684+
}
1685+
}
1686+
>
1687+
<div
1688+
className="moveHandle"
1689+
/>
1690+
<div
1691+
className="rowContents"
1692+
>
1693+
<div
1694+
className="rowLabel"
1695+
>
1696+
<span
1697+
className="rowTitle"
1698+
>
1699+
<input
1700+
onChange={[Function]}
1701+
style={
1702+
Object {
1703+
"fontSize": "1.1rem",
1704+
}
1705+
}
1706+
value="Branch Manager"
1707+
/>
1708+
</span>
1709+
</div>
1710+
<div
1711+
className="rowToolbar"
1712+
/>
1713+
</div>
1714+
</div>
1715+
</div>
1716+
</div>
1717+
</div>
1718+
</div>
1719+
</div>
1720+
</div>
1721+
</div>
1722+
</div>
1723+
</div>
1724+
</div>
1725+
<br />
1726+
<a
1727+
className="sourceLink"
1728+
href="https://github.com/fritz-c/react-sortable-tree/blob/master/examples/storybooks/modify-nodes.js"
1729+
rel="noopener noreferrer"
1730+
target="_top"
1731+
>
1732+
VIEW SOURCE →
1733+
</a>
1734+
</div>
1735+
`;

Diff for: ‎examples/storybooks/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { storiesOf } from '@storybook/react';
55
// import { action } from '@storybook/addon-actions';
66
import BarebonesExample from './barebones';
77
import AddRemoveExample from './add-remove';
8+
import ModifyNodesExample from './modify-nodes';
89
import ExternalNodeExample from './external-node';
910
import TouchSupportExample from './touch-support';
1011
import TreeToTreeExample from './tree-to-tree';
@@ -31,6 +32,9 @@ storiesOf('Basics', module)
3132
)
3233
.add('Add and remove nodes programmatically', () =>
3334
wrapWithSource(<AddRemoveExample />, 'add-remove.js')
35+
)
36+
.add('Modify nodes', () =>
37+
wrapWithSource(<ModifyNodesExample />, 'modify-nodes.js')
3438
);
3539

3640
storiesOf('Advanced', module)

Diff for: ‎examples/storybooks/modify-nodes.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, { Component } from 'react';
2+
import SortableTree, { changeNodeAtPath } from '../../src';
3+
4+
export default class App extends Component {
5+
constructor(props) {
6+
super(props);
7+
8+
this.state = {
9+
treeData: [
10+
{ name: 'IT Manager' },
11+
{
12+
name: 'Regional Manager',
13+
expanded: true,
14+
children: [{ name: 'Branch Manager' }],
15+
},
16+
],
17+
};
18+
}
19+
20+
render() {
21+
const getNodeKey = ({ treeIndex }) => treeIndex;
22+
return (
23+
<div>
24+
<div style={{ height: 300 }}>
25+
<SortableTree
26+
treeData={this.state.treeData}
27+
onChange={treeData => this.setState({ treeData })}
28+
generateNodeProps={({ node, path }) => ({
29+
title: (
30+
<input
31+
style={{ fontSize: '1.1rem' }}
32+
value={node.name}
33+
onChange={event => {
34+
const name = event.target.value;
35+
36+
this.setState(state => ({
37+
treeData: changeNodeAtPath({
38+
treeData: state.treeData,
39+
path,
40+
getNodeKey,
41+
newNode: { ...node, name },
42+
}),
43+
}));
44+
}}
45+
/>
46+
),
47+
})}
48+
/>
49+
</div>
50+
</div>
51+
);
52+
}
53+
}

Diff for: ‎src/node-renderer-default.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class NodeRendererDefault extends Component {
2727
canDrop,
2828
canDrag,
2929
node,
30+
title,
31+
subtitle,
3032
draggedNode,
3133
path,
3234
treeIndex,
@@ -45,6 +47,8 @@ class NodeRendererDefault extends Component {
4547
/* eslint-enable no-unused-vars */
4648
...otherProps
4749
} = this.props;
50+
const nodeTitle = title || node.title;
51+
const nodeSubtitle = subtitle || node.subtitle;
4852

4953
let handle;
5054
if (canDrag) {
@@ -143,24 +147,24 @@ class NodeRendererDefault extends Component {
143147
(node.subtitle ? ` ${styles.rowTitleWithSubtitle}` : '')
144148
}
145149
>
146-
{typeof node.title === 'function'
147-
? node.title({
150+
{typeof nodeTitle === 'function'
151+
? nodeTitle({
148152
node,
149153
path,
150154
treeIndex,
151155
})
152-
: node.title}
156+
: nodeTitle}
153157
</span>
154158

155-
{node.subtitle &&
159+
{nodeSubtitle &&
156160
<span className={styles.rowSubtitle}>
157-
{typeof node.subtitle === 'function'
158-
? node.subtitle({
161+
{typeof nodeSubtitle === 'function'
162+
? nodeSubtitle({
159163
node,
160164
path,
161165
treeIndex,
162166
})
163-
: node.subtitle}
167+
: nodeSubtitle}
164168
</span>}
165169
</div>
166170

@@ -194,10 +198,14 @@ NodeRendererDefault.defaultProps = {
194198
parentNode: null,
195199
draggedNode: null,
196200
canDrop: false,
201+
title: null,
202+
subtitle: null,
197203
};
198204

199205
NodeRendererDefault.propTypes = {
200206
node: PropTypes.shape({}).isRequired,
207+
title: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
208+
subtitle: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
201209
path: PropTypes.arrayOf(
202210
PropTypes.oneOfType([PropTypes.string, PropTypes.number])
203211
).isRequired,

0 commit comments

Comments
 (0)
Please sign in to comment.