Skip to content

Commit

Permalink
Merge d34edf4 into 2bec2dd
Browse files Browse the repository at this point in the history
  • Loading branch information
mrchief committed Dec 29, 2018
2 parents 2bec2dd + d34edf4 commit 79d90d7
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 61 deletions.
2 changes: 1 addition & 1 deletion docs/bundle.js

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions docs/src/stories/Options/index.js
Expand Up @@ -16,7 +16,8 @@ class WithOptions extends PureComponent {
simpleSelect: false,
showPartiallySelected: false,
disabled: false,
readOnly: false
readOnly: false,
hierarchical: false
}
}

Expand All @@ -35,7 +36,7 @@ class WithOptions extends PureComponent {
}

render() {
const { clearSearchOnChange, keepTreeOnSearch, simpleSelect, showPartiallySelected, disabled, readOnly } = this.state
const { clearSearchOnChange, keepTreeOnSearch, simpleSelect, showPartiallySelected, disabled, readOnly, hierarchical } = this.state

return (
<div>
Expand All @@ -55,6 +56,7 @@ class WithOptions extends PureComponent {
<Checkbox label="Show Partially Selected" value="showPartiallySelected" checked={showPartiallySelected} onChange={this.onOptionsChange} />
<Checkbox label="Disabled" value="disabled" checked={disabled} onChange={this.onOptionsChange} />
<Checkbox label="Read Only" value="readOnly" checked={readOnly} onChange={this.onOptionsChange} />
<Checkbox label="Hierarchical" value="hierarchical" checked={hierarchical} onChange={this.onOptionsChange} />
</div>
<div>
<DropdownTreeSelect
Expand All @@ -68,6 +70,7 @@ class WithOptions extends PureComponent {
showPartiallySelected={showPartiallySelected}
disabled={disabled}
readOnly={readOnly}
hierarchical={hierarchical}
/>
</div>
</div>
Expand Down
13 changes: 8 additions & 5 deletions src/index.js
Expand Up @@ -36,7 +36,8 @@ class DropdownTreeSelect extends Component {
noMatchesText: PropTypes.string,
showPartiallySelected: PropTypes.bool,
disabled: PropTypes.bool,
readOnly: PropTypes.bool
readOnly: PropTypes.bool,
hierarchical: PropTypes.bool
}

static defaultProps = {
Expand All @@ -53,8 +54,8 @@ class DropdownTreeSelect extends Component {
}
}

createList = (tree, simple, showPartial) => {
this.treeManager = new TreeManager(tree, simple, showPartial)
createList = ({ data, simpleSelect, showPartiallySelected, hierarchical }) => {
this.treeManager = new TreeManager({ data, simpleSelect, showPartiallySelected, hierarchical })
return this.treeManager.tree
}

Expand All @@ -69,7 +70,8 @@ class DropdownTreeSelect extends Component {
}

componentWillMount() {
const tree = this.createList(this.props.data, this.props.simpleSelect, this.props.showPartiallySelected)
const { data, simpleSelect, showPartiallySelected, hierarchical } = this.props
const tree = this.createList({ data, simpleSelect, showPartiallySelected, hierarchical })
const tags = this.treeManager.getTags()
this.setState({ tree, tags })
}
Expand All @@ -79,7 +81,8 @@ class DropdownTreeSelect extends Component {
}

componentWillReceiveProps(nextProps) {
const tree = this.createList(nextProps.data, nextProps.simpleSelect, nextProps.showPartiallySelected)
const { data, simpleSelect, showPartiallySelected, hierarchical } = nextProps
const tree = this.createList({ data, simpleSelect, showPartiallySelected, hierarchical })
const tags = this.treeManager.getTags()
this.setState({ tree, tags })
}
Expand Down
12 changes: 7 additions & 5 deletions src/tree-manager/flatten-tree.js
Expand Up @@ -96,14 +96,15 @@ const tree = [
* @param {[bool]} showPartialState Whether to show partially checked state
* @return {object} The flattened list
*/
function flattenTree(tree, simple, showPartialState) {
function flattenTree(tree, simple, showPartialState, hierarchical) {
const forest = Array.isArray(tree) ? tree : [tree]

// eslint-disable-next-line no-use-before-define
const { list, defaultValues } = walkNodes({
nodes: forest,
simple,
showPartialState
showPartialState,
hierarchical
})
return { list, defaultValues }
}
Expand All @@ -126,7 +127,7 @@ function setInitialStateProps(node, parent = {}) {
}
}

function walkNodes({ nodes, list = new Map(), parent, depth = 0, simple, showPartialState, defaultValues = [] }) {
function walkNodes({ nodes, list = new Map(), parent, depth = 0, simple, showPartialState, defaultValues = [], hierarchical }) {
nodes.forEach((node, i) => {
node._depth = depth

Expand All @@ -143,7 +144,7 @@ function walkNodes({ nodes, list = new Map(), parent, depth = 0, simple, showPar
node.checked = true
}

setInitialStateProps(node, parent)
if (!hierarchical) setInitialStateProps(node, parent)

list.set(node._id, node)
if (!simple && node.children) {
Expand All @@ -154,7 +155,8 @@ function walkNodes({ nodes, list = new Map(), parent, depth = 0, simple, showPar
parent: node,
depth: depth + 1,
showPartialState,
defaultValues
defaultValues,
hierarchical
})

if (showPartialState && !node.checked) {
Expand Down
23 changes: 14 additions & 9 deletions src/tree-manager/index.js
Expand Up @@ -4,14 +4,15 @@ import { isEmpty } from '../utils'
import flattenTree from './flatten-tree'

class TreeManager {
constructor(tree, simple, showPartialState) {
this._src = tree
const { list, defaultValues } = flattenTree(JSON.parse(JSON.stringify(tree)), simple, showPartialState)
constructor({ data, simpleSelect, showPartiallySelected, hierarchical }) {
this._src = data
const { list, defaultValues } = flattenTree(JSON.parse(JSON.stringify(data)), simpleSelect, showPartiallySelected, hierarchical)
this.tree = list
this.defaultValues = defaultValues
this.simpleSelect = simple
this.showPartialState = showPartialState
this.simpleSelect = simpleSelect
this.showPartialState = !hierarchical && showPartiallySelected
this.searchMaps = new Map()
this.hierarchical = hierarchical
}

getNodeById(id) {
Expand Down Expand Up @@ -118,20 +119,21 @@ class TreeManager {
const node = this.getNodeById(id)
node.checked = checked

// TODO: this can probably be combined with the same check in the else block. investigate in a separate release.
if (this.showPartialState) {
node.partial = false
}

if (this.simpleSelect) {
this.togglePreviousChecked(id)
} else {
this.toggleChildren(id, checked)
if (!this.hierarchical) this.toggleChildren(id, checked)

if (this.showPartialState) {
this.partialCheckParents(node)
}

if (!checked) {
if (!this.hierarchical && !checked) {
this.unCheckParents(node)
}
}
Expand Down Expand Up @@ -206,9 +208,12 @@ class TreeManager {
if (visited[key]) return

if (node.checked) {
// Parent node, so no need to walk children
tags.push(node)
markSubTreeVisited(node)

if (!this.hierarchical) {
// Parent node, so no need to walk children
markSubTreeVisited(node)
}
} else {
visited[key] = true
}
Expand Down
42 changes: 21 additions & 21 deletions src/tree-manager/tests/index.test.js
Expand Up @@ -23,7 +23,7 @@ test('should not mutate input', t => {
]
}
/* eslint-disable no-new */
new TreeManager(actual)
new TreeManager({ data: actual })
t.deepEqual(actual, expected)
})

Expand All @@ -41,7 +41,7 @@ test('should set initial check state based on parent check state when node check
],
checked: true
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
t.true(manager.getNodeById('c1').checked)
})

Expand All @@ -59,7 +59,7 @@ test('should set initial check state based on node check state when node check s
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
t.true(manager.getNodeById('c1').checked)
})

Expand All @@ -77,7 +77,7 @@ test('should set initial check state based on node check state when node check s
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
t.false(manager.getNodeById('c1').checked)
})

Expand All @@ -95,7 +95,7 @@ test('should get tags based on children check state', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
t.deepEqual(manager.getTags().map(t => t.label), ['l1c1'])
})

Expand All @@ -112,7 +112,7 @@ test('should get tags based on parent check state', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
t.deepEqual(manager.getTags().map(t => t.label), ['l1'])
})

Expand Down Expand Up @@ -141,7 +141,7 @@ test('should get tags based on multiple parent check state', t => {
]
}
]
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
t.deepEqual(manager.getTags().map(t => t.label), ['l1', 'l2'])
})

Expand Down Expand Up @@ -170,7 +170,7 @@ test('should get tags based on multiple parent/child check state', t => {
]
}
]
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
t.deepEqual(manager.getTags().map(t => t.label), ['l1', 'l2c2'])
})

Expand All @@ -187,7 +187,7 @@ test('should toggle children when checked', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.setNodeCheckedState('i1', true)
t.true(manager.getNodeById('c1').checked)
})
Expand All @@ -206,7 +206,7 @@ test('should toggle children when unchecked', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.setNodeCheckedState('i1', false)
t.false(manager.getNodeById('c1').checked)
})
Expand All @@ -225,7 +225,7 @@ test('should uncheck parent when unchecked', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.setNodeCheckedState('c1', false)
t.false(manager.getNodeById('i1').checked)
})
Expand All @@ -250,7 +250,7 @@ test('should uncheck all parents when unchecked', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.setNodeCheckedState('c2', false)
t.false(manager.getNodeById('c1').checked)
t.false(manager.getNodeById('i1').checked)
Expand Down Expand Up @@ -279,7 +279,7 @@ test('should collapse all children when collapsed', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.toggleNodeExpandState('i1')
t.false(manager.getNodeById('c1').expanded)
t.false(manager.getNodeById('c2').expanded)
Expand All @@ -305,7 +305,7 @@ test('should expand node (and not children) when expanded', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.toggleNodeExpandState('i1')
t.true(manager.getNodeById('i1').expanded)
t.falsy(manager.getNodeById('c1').expanded)
Expand All @@ -332,7 +332,7 @@ test('should get matching nodes when searched', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
const { allNodesHidden, tree: matchTree } = manager.filterTree('search')
t.false(allNodesHidden)
const nodes = ['i1', 'c1']
Expand Down Expand Up @@ -360,7 +360,7 @@ test('should hide all nodes when search term is not found', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
const { allNodesHidden } = manager.filterTree('bla-bla')
t.true(allNodesHidden)
})
Expand Down Expand Up @@ -392,7 +392,7 @@ test('should use cached results for subsequent searches', t => {
value: 'sears'
}
]
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
const { allNodesHidden } = manager.filterTree('sea')
manager.filterTree('sear')
manager.filterTree('on')
Expand Down Expand Up @@ -428,7 +428,7 @@ test('should restore nodes', t => {
value: 'sears'
}
]
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.filterTree('search')
manager.restoreNodes()
const visibleNodes = ['i1', 'i2', 'c1', 'c2']
Expand All @@ -455,7 +455,7 @@ test('should get matching nodes with mixed case when searched', t => {
}
]
}
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
const { allNodesHidden, tree: matchTree } = manager.filterTree('SearCH')
t.false(allNodesHidden)
const nodes = ['i1', 'c1']
Expand Down Expand Up @@ -490,7 +490,7 @@ test('should uncheck previous node in simple select mode', t => {
]
}
]
const manager = new TreeManager(tree, true)
const manager = new TreeManager({ data: tree, simpleSelect: true })
manager.setNodeCheckedState('i1', true)
t.true(manager.getNodeById('i1').checked)

Expand Down Expand Up @@ -532,7 +532,7 @@ test('should restore default values', t => {
]
}
]
const manager = new TreeManager(tree)
const manager = new TreeManager({ data: tree })
manager.setNodeCheckedState('c1', false)
t.false(manager.getNodeById('c1').checked)

Expand Down

0 comments on commit 79d90d7

Please sign in to comment.