Skip to content

Commit

Permalink
fix: Incremental updates (#153)
Browse files Browse the repository at this point in the history
* fix: Do not toggle dropwdown on pill removal (#141) 🐛

* fix: Show partial select with empty children (#139) 🐛

* fix: Fix outside click in case of multiple dropdowns

* docs: Add showDropdown prop description to readme (#152)

Closes #144
  • Loading branch information
mrchief committed Aug 14, 2018
1 parent c0ee452 commit ece8fe9
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 79 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ A lightweight and fast control to render a select component that can display hie
- [keepTreeOnSearch](#keeptreeonsearch)
- [simpleSelect](#simpleselect)
- [showPartiallySelected](#showpartiallyselected)
- [showDropdown](#showDropdown)
- [Styling and Customization](#styling-and-customization)
- [Using default styles](#default-styles)
- [Customizing with Bootstrap, Material Design styles](#customizing-styles)
Expand Down Expand Up @@ -287,6 +288,12 @@ Type: `bool` (default: `false`)

If set to true, shows checkboxes in a partial state when one, but not all of their children are selected. Allows styling of partially selected nodes as well, by using [:indeterminate](https://developer.mozilla.org/en-US/docs/Web/CSS/:indeterminate) pseudo class. Simply add desired styles to `.node.partial .checkbox-item:indeterminate { ... }` in your CSS.

### showDropdown

Type: `bool` (default: `false`)

If set to true, shows the dropdown when rendered. This can be used to render the component with the dropdown open as its initial state.

## Styling and Customization

### Default styles
Expand Down
2 changes: 1 addition & 1 deletion docs/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class DropdownTreeSelect extends Component {
}

handleOutsideClick = e => {
if (!isOutsideClick(e)) {
if (!isOutsideClick(e, this.props.className)) {
return
}

Expand Down
5 changes: 3 additions & 2 deletions src/tag/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ class Tag extends PureComponent {
onDelete: PropTypes.func
}

handleClick = () => {
handleClick = e => {
const { id, onDelete } = this.props

e.stopPropagation()
e.nativeEvent.stopImmediatePropagation()
onDelete(id)
}

Expand Down
22 changes: 20 additions & 2 deletions src/tag/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,33 @@ import toJson from 'enzyme-to-json'

import Tag from './index'

const nativeEvent = { nativeEvent: { stopImmediatePropagation: () => {} } }

test('renders label when passed in', t => {
const wrapper = toJson(shallow(<Tag label="hello" id="abc" />))
t.snapshot(wrapper)
})

test('call stopPropagation and stopImmediatePropagation when pill is closed', t => {
const onDelete = spy()
const wrapper = mount(<Tag label="hello" id="abc" onDelete={onDelete} />)
const event = {
type: 'click',
stopPropagation: spy(),
nativeEvent: {
stopImmediatePropagation: spy()
}
}
wrapper.find('.tag-remove').prop('onClick')(event)
t.true(event.stopPropagation.called)
t.true(event.nativeEvent.stopImmediatePropagation.called)
})


test('call onDelete handler when pill is closed', t => {
const onDelete = spy()
const wrapper = mount(<Tag label="hello" id="abc" onDelete={onDelete} />)
wrapper.find('.tag-remove').simulate('click')
wrapper.find('.tag-remove').simulate('click', nativeEvent)
t.true(onDelete.calledWith('abc'))
})

Expand All @@ -24,6 +42,6 @@ test('should not cause form submit', t => {
const wrapper = mount(<form onSubmit={onSubmit}>
<Tag label="hello" id="abc" onDelete={onDelete} />
</form>)
wrapper.find('.tag-remove').simulate('click')
wrapper.find('.tag-remove').simulate('click', nativeEvent)
t.false(onSubmit.called)
})
4 changes: 3 additions & 1 deletion src/tree-manager/flatten-tree.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import getPartialState from './getPartialState'

import { isEmpty } from '../utils'

/**
* Converts a nested node into an associative array with pointers to child and parent nodes
* Given:
Expand Down Expand Up @@ -159,7 +161,7 @@ function walkNodes({ nodes, list = new Map(), parent, depth = 0, simple, showPar
node.partial = getPartialState(node)

// re-check if all children are checked. if so, check thyself
if (node.children.every(c => c.checked)) {
if (!isEmpty(node.children) && node.children.every(c => c.checked)) {
node.checked = true
}
}
Expand Down
53 changes: 53 additions & 0 deletions src/tree-manager/tests/flatten-tree.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,56 @@ test('sets default values', t => {
t.deepEqual(defaultValues, expectedDefaultValues)
t.deepEqual(mapToObject(list), expectedTree)
})

test('does not check parent with empty children when showing partial state', t => {
const tree = [
{
name: 'item1',
value: 'value1',
children: []
},
{
name: 'item2',
value: 'value2',
children: []
},
{
name: 'item3',
value: 'value3',
children: []
}
]

const expectedTree = {
0: {
_id: '0',
_children: [],
_depth: 0,
children: undefined,
name: 'item1',
value: 'value1',
partial: false
},
1: {
_id: '1',
_children: [],
_depth: 0,
children: undefined,
name: 'item2',
value: 'value2',
partial: false
},
2: {
_id: '2',
_children: [],
_depth: 0,
children: undefined,
name: 'item3',
value: 'value3',
partial: false
},
}

const { list } = flattenTree(tree, false, true)
t.deepEqual(mapToObject(list), expectedTree)
})
5 changes: 3 additions & 2 deletions src/utils/isOutsideClick.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const getPath = e => {
return path
}

export default e => {
export default (e, className) => {
if (!(e instanceof Event)) return false
return !getPath(e).some(node => node.className && node.className.indexOf('react-dropdown-tree-select') >= 0)
const completeClassName = className ? `${className} react-dropdown-tree-select` : 'react-dropdown-tree-select'
return !getPath(e).some(node => node.className && node.className.indexOf(completeClassName) >= 0)
}
Loading

0 comments on commit ece8fe9

Please sign in to comment.