Skip to content

Commit b7d426e

Browse files
ellingemrchief
authored andcommitted
feat: Add unique ids on dropdowns if not provided (#220)
Added possibility to provide a id by property. If not provided it generates a unique by a global counter. Fixes #215 Fixes #212 Fixes #208 ## Type of change - [x] Bug fix - [x] New feature
1 parent e6b949d commit b7d426e

19 files changed

+212
-109
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ A lightweight and fast control to render a select component that can display hie
5151
- [showPartiallySelected](#showpartiallyselected)
5252
- [showDropdown](#showDropdown)
5353
- [form states (disabled|readOnly)](#formstates)
54+
- [id](#id)
5455
- [Styling and Customization](#styling-and-customization)
5556
- [Using default styles](#default-styles)
5657
- [Customizing with Bootstrap, Material Design styles](#customizing-styles)
@@ -309,6 +310,14 @@ Type: `bool` (default: `false`)
309310
`disabled=true` disables the dropdown completely. This is useful during form submit events.
310311
`readOnly=true` makes the dropdown read only, which means that the user can still interact with it but cannot change any of its values. This can be useful for display only forms.
311312

313+
### id
314+
315+
Type: `string`
316+
317+
Specific id for container. The container renders with a default id of `rdtsN` where N is count of the current component rendered.
318+
319+
Use to ensure a own unique id when a simple counter is not sufficient, e.g in a partial server render (SSR)
320+
312321
## Styling and Customization
313322

314323
### Default styles

__snapshots__/src/index.test.js.md

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Generated by [AVA](https://ava.li).
1010
1111
<div
1212
className="react-dropdown-tree-select"
13+
id="rdts"
1314
>
1415
<div
1516
className="dropdown"
@@ -98,12 +99,14 @@ Generated by [AVA](https://ava.li).
9899
},
99100
]
100101
}
102+
id="rdts"
101103
onBlur={Function onBlur {}}
102104
onChange={Function onChange {}}
103105
onFocus={Function onFocus {}}
104106
>
105107
<div
106108
className="react-dropdown-tree-select"
109+
id="rdts"
107110
>
108111
<div
109112
className="dropdown"
@@ -148,6 +151,7 @@ Generated by [AVA](https://ava.li).
148151
149152
<div
150153
className="react-dropdown-tree-select"
154+
id="rdts"
151155
>
152156
<div
153157
className="dropdown"
@@ -171,110 +175,110 @@ Generated by [AVA](https://ava.li).
171175
<Tree
172176
data={
173177
Map {
174-
'0' => {
178+
'rdts-0' => {
175179
_children: [
176-
'0-0',
177-
'0-1',
180+
'rdts-0-0',
181+
'rdts-0-1',
178182
],
179183
_depth: 0,
180-
_id: '0',
184+
_id: 'rdts-0',
181185
children: undefined,
182186
label: 'item1',
183187
value: 'value1',
184188
},
185-
'0-0' => {
189+
'rdts-0-0' => {
186190
_children: [
187-
'0-0-0',
188-
'0-0-1',
191+
'rdts-0-0-0',
192+
'rdts-0-0-1',
189193
],
190194
_depth: 1,
191-
_id: '0-0',
192-
_parent: '0',
195+
_id: 'rdts-0-0',
196+
_parent: 'rdts-0',
193197
children: undefined,
194198
label: 'item1-1',
195199
value: 'value1-1',
196200
},
197-
'0-0-0' => {
201+
'rdts-0-0-0' => {
198202
_depth: 2,
199-
_id: '0-0-0',
200-
_parent: '0-0',
203+
_id: 'rdts-0-0-0',
204+
_parent: 'rdts-0-0',
201205
label: 'item1-1-1',
202206
value: 'value1-1-1',
203207
},
204-
'0-0-1' => {
208+
'rdts-0-0-1' => {
205209
_depth: 2,
206-
_id: '0-0-1',
207-
_parent: '0-0',
210+
_id: 'rdts-0-0-1',
211+
_parent: 'rdts-0-0',
208212
label: 'item1-1-2',
209213
value: 'value1-1-2',
210214
},
211-
'0-1' => {
215+
'rdts-0-1' => {
212216
_depth: 1,
213-
_id: '0-1',
214-
_parent: '0',
217+
_id: 'rdts-0-1',
218+
_parent: 'rdts-0',
215219
label: 'item1-2',
216220
value: 'value1-2',
217221
},
218-
'1' => {
222+
'rdts-1' => {
219223
_children: [
220-
'1-0',
221-
'1-1',
224+
'rdts-1-0',
225+
'rdts-1-1',
222226
],
223227
_depth: 0,
224-
_id: '1',
228+
_id: 'rdts-1',
225229
children: undefined,
226230
label: 'item2',
227231
value: 'value2',
228232
},
229-
'1-0' => {
233+
'rdts-1-0' => {
230234
_children: [
231-
'1-0-0',
232-
'1-0-1',
233-
'1-0-2',
235+
'rdts-1-0-0',
236+
'rdts-1-0-1',
237+
'rdts-1-0-2',
234238
],
235239
_depth: 1,
236-
_id: '1-0',
237-
_parent: '1',
240+
_id: 'rdts-1-0',
241+
_parent: 'rdts-1',
238242
children: undefined,
239243
label: 'item2-1',
240244
value: 'value2-1',
241245
},
242-
'1-0-0' => {
246+
'rdts-1-0-0' => {
243247
_depth: 2,
244-
_id: '1-0-0',
245-
_parent: '1-0',
248+
_id: 'rdts-1-0-0',
249+
_parent: 'rdts-1-0',
246250
label: 'item2-1-1',
247251
value: 'value2-1-1',
248252
},
249-
'1-0-1' => {
253+
'rdts-1-0-1' => {
250254
_depth: 2,
251-
_id: '1-0-1',
252-
_parent: '1-0',
255+
_id: 'rdts-1-0-1',
256+
_parent: 'rdts-1-0',
253257
label: 'item2-1-2',
254258
value: 'value2-1-2',
255259
},
256-
'1-0-2' => {
260+
'rdts-1-0-2' => {
257261
_children: [
258-
'1-0-2-0',
262+
'rdts-1-0-2-0',
259263
],
260264
_depth: 2,
261-
_id: '1-0-2',
262-
_parent: '1-0',
265+
_id: 'rdts-1-0-2',
266+
_parent: 'rdts-1-0',
263267
children: undefined,
264268
label: 'item2-1-3',
265269
value: 'value2-1-3',
266270
},
267-
'1-0-2-0' => {
271+
'rdts-1-0-2-0' => {
268272
_depth: 3,
269-
_id: '1-0-2-0',
270-
_parent: '1-0-2',
273+
_id: 'rdts-1-0-2-0',
274+
_parent: 'rdts-1-0-2',
271275
label: 'item2-1-3-1',
272276
value: 'value2-1-3-1',
273277
},
274-
'1-1' => {
278+
'rdts-1-1' => {
275279
_depth: 1,
276-
_id: '1-1',
277-
_parent: '1',
280+
_id: 'rdts-1-1',
281+
_parent: 'rdts-1',
278282
label: 'item2-2',
279283
value: 'value2-2',
280284
},
14 Bytes
Binary file not shown.

__snapshots__/src/tree-node/actions.test.js.md

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,20 @@ Generated by [AVA](https://ava.li).
88

99
> Snapshot 1
1010
11-
[
12-
<Action
13-
actionData={
14-
{
15-
action: 'action-0',
16-
id: undefined,
17-
}
11+
<Action
12+
actionData={
13+
{
14+
action: 'action-0',
15+
id: 'snapshot',
1816
}
19-
className="cn0-0-0"
20-
junk="1"
21-
key="action-0"
22-
onAction={Function onAction {}}
23-
text="hello"
24-
title="action"
25-
/>,
26-
]
17+
}
18+
className="cn0-0-0"
19+
junk="1"
20+
key="action-0"
21+
onAction={Function onAction {}}
22+
text="hello"
23+
title="action"
24+
/>
2725

2826
## returns null if actions are empty
2927

-30 Bytes
Binary file not shown.

__snapshots__/src/tree/index.test.js.md

Lines changed: 0 additions & 13 deletions
This file was deleted.
-195 Bytes
Binary file not shown.

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"format": "prettier-eslint \"src/**/*.js\" \"docs/**/*.js\" webpack.config.js",
3636
"test": "cross-env NODE_ENV=test ava",
3737
"test:cov": "rimraf .nyc_output && nyc npm test && nyc report --reporter=lcov ",
38+
"test:watch": "cross-env NODE_ENV=test ava --watch",
3839
"semantic-release": "semantic-release",
3940
"contributors": "all-contributors add && all-contributors generate"
4041
},
@@ -68,9 +69,9 @@
6869
"cross-env": "^5.0.5",
6970
"css-loader": "^0.28.0",
7071
"cz-conventional-changelog-emoji": "^0.1.0",
71-
"enzyme": "^3.3.0",
72-
"enzyme-adapter-react-16": "^1.0.4",
73-
"enzyme-to-json": "^3.3.3",
72+
"enzyme": "^3.9.0",
73+
"enzyme-adapter-react-16": "^1.11.2",
74+
"enzyme-to-json": "^3.3.5",
7475
"eslint": "^4.19.0",
7576
"eslint-config-airbnb": "^16.1.0",
7677
"eslint-plugin-import": "^2.9.0",

src/index.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import cn from 'classnames/bind'
1010
import PropTypes from 'prop-types'
1111
import React, { Component } from 'react'
1212

13-
import { isOutsideClick } from './utils'
13+
import { isOutsideClick, clientIdGenerator } from './utils'
1414
import Input from './input'
1515
import Tree from './tree'
1616
import TreeManager from './tree-manager'
@@ -38,7 +38,8 @@ class DropdownTreeSelect extends Component {
3838
showPartiallySelected: PropTypes.bool,
3939
disabled: PropTypes.bool,
4040
readOnly: PropTypes.bool,
41-
hierarchical: PropTypes.bool
41+
hierarchical: PropTypes.bool,
42+
id: PropTypes.string
4243
}
4344

4445
static defaultProps = {
@@ -53,10 +54,11 @@ class DropdownTreeSelect extends Component {
5354
showDropdown: this.props.showDropdown || false,
5455
searchModeOn: false
5556
}
57+
this.clientId = props.id || clientIdGenerator.get(this)
5658
}
5759

5860
createList = ({ data, simpleSelect, showPartiallySelected, hierarchical }) => {
59-
this.treeManager = new TreeManager({ data, simpleSelect, showPartiallySelected, hierarchical })
61+
this.treeManager = new TreeManager({ data, simpleSelect, showPartiallySelected, hierarchical, rootPrefixId: this.clientId })
6062
return this.treeManager.tree
6163
}
6264

@@ -110,7 +112,7 @@ class DropdownTreeSelect extends Component {
110112
}
111113

112114
handleOutsideClick = e => {
113-
if (!isOutsideClick(e, this.props.className)) {
115+
if (!isOutsideClick(e, this.node)) {
114116
return
115117
}
116118

@@ -192,6 +194,7 @@ class DropdownTreeSelect extends Component {
192194

193195
return (
194196
<div
197+
id={this.clientId}
195198
className={cx(this.props.className, 'react-dropdown-tree-select')}
196199
ref={node => {
197200
this.node = node

0 commit comments

Comments
 (0)