Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: optionally disable popping on backspace #551

Merged
merged 9 commits into from
Mar 7, 2022
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ A lightweight and fast control to render a select component that can display hie
- [searchPredicate](#searchpredicate)
- [inlineSearchInput](#inlinesearchinput)
- [tabIndex](#tabIndex)
- [disablePoppingOnBackspace](#disablePoppingOnBackspace)
- [Styling and Customization](#styling-and-customization)
- [Using default styles](#default-styles)
- [Customizing with Bootstrap, Material Design styles](#customizing-styles)
Expand Down Expand Up @@ -421,6 +422,12 @@ Type: `number` (default: `0`)

`tabIndex=0` attribute indicates that its element can be focused, and where it participates in sequential keyboard navigation.

### disablePoppingOnBackspace

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

`disablePoppingOnBackspace=true` attribute indicates that when a user triggers a 'backspace' keyDown in the empty search bar, the tree will not deselect nodes.

## Styling and Customization

### Default styles
Expand Down
2 changes: 2 additions & 0 deletions __snapshots__/src/index.test.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ Generated by [AVA](https://ava.li).
},
]
}
disablePoppingOnBackspace={false}
id="rdts"
inlineSearchInput={false}
mode="radioSelect"
Expand Down Expand Up @@ -617,6 +618,7 @@ Generated by [AVA](https://ava.li).
},
]
}
disablePoppingOnBackspace={false}
id="rdts"
inlineSearchInput={false}
onAction={Function onAction {}}
Expand Down
Binary file modified __snapshots__/src/index.test.js.snap
Binary file not shown.
11 changes: 9 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class DropdownTreeSelect extends Component {
searchPredicate: PropTypes.func,
inlineSearchInput: PropTypes.bool,
tabIndex: PropTypes.number,
disablePoppingOnBackspace: PropTypes.bool,
}

static defaultProps = {
Expand All @@ -60,6 +61,7 @@ class DropdownTreeSelect extends Component {
showDropdown: 'default',
inlineSearchInput: false,
tabIndex: 0,
disablePoppingOnBackspace: false,
}

constructor(props) {
Expand Down Expand Up @@ -236,7 +238,7 @@ class DropdownTreeSelect extends Component {
}

onKeyboardKeyDown = e => {
const { readOnly, mode } = this.props
const { readOnly, mode, disablePoppingOnBackspace } = this.props
const { showDropdown, tags, searchModeOn, currentFocus } = this.state
const tm = this.treeManager
const tree = searchModeOn ? tm.matchTree : tm.tree
Expand Down Expand Up @@ -271,7 +273,12 @@ class DropdownTreeSelect extends Component {
this.handleClick()
}
return
} else if (e.key === 'Backspace' && tags.length && this.searchInput.value.length === 0) {
} else if (
!disablePoppingOnBackspace &&
e.key === 'Backspace' &&
tags.length &&
this.searchInput.value.length === 0
) {
const lastTag = tags.pop()
this.onCheckboxChange(lastTag._id, false)
} else {
Expand Down
12 changes: 12 additions & 0 deletions src/index.keyboardNav.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ test('can delete tags with backspace/delete on keyboardNavigation', t => {
t.deepEqual(wrapper.state().tags.length, 0)
})

test('cannot delete tags on empty search input with backspace on keyboardNavigation when disablePoppingOnBackspace is true', t => {
const data = [{ ...node('a', 'a'), checked: true }, { ...node('b', 'b'), checked: true }]
const wrapper = mount(<DropdownTreeSelect data={data} disablePoppingOnBackspace={true} />)
wrapper.instance().searchInput.value = 'x'
triggerOnKeyboardKeyDown(wrapper, 'Backspace')
t.deepEqual(wrapper.state().tags.length, 2)

wrapper.instance().searchInput.value = ''
triggerOnKeyboardKeyDown(wrapper, 'Backspace')
t.deepEqual(wrapper.state().tags.length, 2)
})

test('remembers current focus between prop updates', t => {
const wrapper = mount(<DropdownTreeSelect data={tree} showDropdown="initial" />)
t.false(wrapper.find('li.focused').exists())
Expand Down