Skip to content

Commit 4e1d5af

Browse files
moonjy1993mrchief
authored andcommitted
feat: Ability to keep the dropdown open always (#241) ✨
Closes #239
1 parent ef6e584 commit 4e1d5af

File tree

6 files changed

+177
-3
lines changed

6 files changed

+177
-3
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ A lightweight and fast control to render a select component that can display hie
5454
- [radioSelect](#radioSelect)
5555
- [showPartiallySelected](#showpartiallyselected)
5656
- [showDropdown](#showDropdown)
57+
- [showDropdownAlways](#showDropdownAlways)
5758
- [form states (disabled|readOnly)](#formstates)
5859
- [id](#id)
5960
- [Styling and Customization](#styling-and-customization)
@@ -341,6 +342,12 @@ Type: `bool` (default: `false`)
341342

342343
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.
343344

345+
### showDropdownAlways
346+
347+
Type: `bool`
348+
349+
If set to true, always shows the dropdown when rendered, and toggling dropdown will be disabled.
350+
344351
### form states (disabled|readOnly)
345352

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

__snapshots__/src/index.test.js.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,154 @@ Generated by [AVA](https://ava.li).
407407
/>
408408
</div>
409409
</div>
410+
</div
411+
412+
## always shows dropdown
413+
414+
> Snapshot 1
415+
416+
<div
417+
className="react-dropdown-tree-select"
418+
id="rdts"
419+
>
420+
<div
421+
className="dropdown"
422+
>
423+
<a
424+
className="dropdown-trigger arrow top"
425+
onClick={Function {}}
426+
>
427+
<Input
428+
inputRef={Function inputRef {}}
429+
onBlur={Function {}}
430+
onFocus={Function {}}
431+
onInputChange={Function {}}
432+
onTagRemove={Function {}}
433+
tags={[]}
434+
/>
435+
</a>
436+
<div
437+
className="dropdown-content"
438+
>
439+
<Tree
440+
clientId="rdts"
441+
data={
442+
Map {
443+
'rdts-0' => {
444+
_children: [
445+
'rdts-0-0',
446+
'rdts-0-1',
447+
],
448+
_depth: 0,
449+
_id: 'rdts-0',
450+
children: undefined,
451+
label: 'item1',
452+
value: 'value1',
453+
},
454+
'rdts-0-0' => {
455+
_children: [
456+
'rdts-0-0-0',
457+
'rdts-0-0-1',
458+
],
459+
_depth: 1,
460+
_id: 'rdts-0-0',
461+
_parent: 'rdts-0',
462+
children: undefined,
463+
label: 'item1-1',
464+
value: 'value1-1',
465+
},
466+
'rdts-0-0-0' => {
467+
_depth: 2,
468+
_id: 'rdts-0-0-0',
469+
_parent: 'rdts-0-0',
470+
label: 'item1-1-1',
471+
value: 'value1-1-1',
472+
},
473+
'rdts-0-0-1' => {
474+
_depth: 2,
475+
_id: 'rdts-0-0-1',
476+
_parent: 'rdts-0-0',
477+
label: 'item1-1-2',
478+
value: 'value1-1-2',
479+
},
480+
'rdts-0-1' => {
481+
_depth: 1,
482+
_id: 'rdts-0-1',
483+
_parent: 'rdts-0',
484+
label: 'item1-2',
485+
value: 'value1-2',
486+
},
487+
'rdts-1' => {
488+
_children: [
489+
'rdts-1-0',
490+
'rdts-1-1',
491+
],
492+
_depth: 0,
493+
_id: 'rdts-1',
494+
children: undefined,
495+
label: 'item2',
496+
value: 'value2',
497+
},
498+
'rdts-1-0' => {
499+
_children: [
500+
'rdts-1-0-0',
501+
'rdts-1-0-1',
502+
'rdts-1-0-2',
503+
],
504+
_depth: 1,
505+
_id: 'rdts-1-0',
506+
_parent: 'rdts-1',
507+
children: undefined,
508+
label: 'item2-1',
509+
value: 'value2-1',
510+
},
511+
'rdts-1-0-0' => {
512+
_depth: 2,
513+
_id: 'rdts-1-0-0',
514+
_parent: 'rdts-1-0',
515+
label: 'item2-1-1',
516+
value: 'value2-1-1',
517+
},
518+
'rdts-1-0-1' => {
519+
_depth: 2,
520+
_id: 'rdts-1-0-1',
521+
_parent: 'rdts-1-0',
522+
label: 'item2-1-2',
523+
value: 'value2-1-2',
524+
},
525+
'rdts-1-0-2' => {
526+
_children: [
527+
'rdts-1-0-2-0',
528+
],
529+
_depth: 2,
530+
_id: 'rdts-1-0-2',
531+
_parent: 'rdts-1-0',
532+
children: undefined,
533+
label: 'item2-1-3',
534+
value: 'value2-1-3',
535+
},
536+
'rdts-1-0-2-0' => {
537+
_depth: 3,
538+
_id: 'rdts-1-0-2-0',
539+
_parent: 'rdts-1-0-2',
540+
label: 'item2-1-3-1',
541+
value: 'value2-1-3-1',
542+
},
543+
'rdts-1-1' => {
544+
_depth: 1,
545+
_id: 'rdts-1-1',
546+
_parent: 'rdts-1',
547+
label: 'item2-2',
548+
value: 'value2-2',
549+
},
550+
}
551+
}
552+
onAction={Function {}}
553+
onCheckboxChange={Function {}}
554+
onNodeToggle={Function {}}
555+
pageSize={100}
556+
searchModeOn={false}
557+
/>
558+
</div>
559+
</div>
410560
</div>

__snapshots__/src/index.test.js.snap

101 Bytes
Binary file not shown.

src/index.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class DropdownTreeSelect extends Component {
2828
keepOpenOnSelect: PropTypes.bool,
2929
placeholderText: PropTypes.string,
3030
showDropdown: PropTypes.bool,
31+
showDropdownAlways: PropTypes.bool,
3132
className: PropTypes.string,
3233
onChange: PropTypes.func,
3334
onAction: PropTypes.func,
@@ -53,7 +54,7 @@ class DropdownTreeSelect extends Component {
5354
constructor(props) {
5455
super(props)
5556
this.state = {
56-
showDropdown: this.props.showDropdown || false,
57+
showDropdown: this.props.showDropdown || this.props.showDropdownAlways || false,
5758
searchModeOn: false,
5859
}
5960
this.clientId = props.id || clientIdGenerator.get(this)
@@ -97,7 +98,7 @@ class DropdownTreeSelect extends Component {
9798
handleClick = () => {
9899
this.setState(prevState => {
99100
// keep dropdown active when typing in search box
100-
const showDropdown = this.keepDropdownActive || !prevState.showDropdown
101+
const showDropdown = this.props.showDropdownAlways || this.keepDropdownActive || !prevState.showDropdown
101102

102103
// register event listeners only if there is a state change
103104
if (showDropdown !== prevState.showDropdown) {
@@ -116,7 +117,7 @@ class DropdownTreeSelect extends Component {
116117
}
117118

118119
handleOutsideClick = e => {
119-
if (!isOutsideClick(e, this.node)) {
120+
if (this.props.showDropdownAlways || !isOutsideClick(e, this.node)) {
120121
return
121122
}
122123

src/index.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ test('shows dropdown', t => {
7272
t.snapshot(toJson(wrapper))
7373
})
7474

75+
test('always shows dropdown', t => {
76+
const { tree } = t.context
77+
const wrapper = shallow(<DropdownTreeSelect id={dropdownId} data={tree} showDropdownAlways />)
78+
t.snapshot(toJson(wrapper))
79+
})
80+
81+
test('keeps dropdown open for showDropdownAlways', t => {
82+
const { tree } = t.context
83+
const wrapper = mount(<DropdownTreeSelect id={dropdownId} data={tree} showDropdownAlways />)
84+
wrapper.instance().handleClick()
85+
t.true(wrapper.state().showDropdown)
86+
})
87+
7588
test('notifies on action', t => {
7689
const handler = spy()
7790
const { tree } = t.context

types/react-dropdown-tree-select.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ declare module "react-dropdown-tree-select" {
2525
* This can be used to render the component with the dropdown open as its initial state
2626
*/
2727
showDropdown?: boolean;
28+
/** If set to true, always shows the dropdown when rendered, and toggling dropdown will be disabled.
29+
*/
30+
showDropdownAlways?: boolean;
2831
/** Additional classname for container.
2932
* The container renders with a default classname of react-dropdown-tree-select
3033
*/

0 commit comments

Comments
 (0)