haya-select 1.0.5 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +9 -0
- package/package.json +5 -1
- package/src/select/index.jsx +110 -61
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haya-select",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,5 +12,9 @@
|
|
|
12
12
|
"classnames": "^2.3.1",
|
|
13
13
|
"debounce": "^1.2.1",
|
|
14
14
|
"diggerize": "^1.0.4"
|
|
15
|
+
},
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"prop-types": ">= 15.7.2",
|
|
18
|
+
"react": ">= 16.0.0"
|
|
15
19
|
}
|
|
16
20
|
}
|
package/src/select/index.jsx
CHANGED
|
@@ -14,39 +14,6 @@ const nameForComponentWithMultiple = (component) => {
|
|
|
14
14
|
return name
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const presentOption = (currentValue) => {
|
|
18
|
-
if (currentValue.text) return currentValue.text
|
|
19
|
-
|
|
20
|
-
if (currentValue.html) {
|
|
21
|
-
return (
|
|
22
|
-
<div dangerouslySetInnerHTML={{__html: digg(currentValue, "html")}} />
|
|
23
|
-
)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
throw new Error(`Couldn't figure out how to present option from the given keys: ${Object.keys(currentValue, ", ")}`)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const LoadedOption = class LoadedOption extends BaseComponent {
|
|
30
|
-
render() {
|
|
31
|
-
const {currentOptions, loadedOption} = digs(this.props, "currentOptions", "loadedOption")
|
|
32
|
-
const selected = Boolean(currentOptions.find((currentOption) => currentOption.value == loadedOption.value))
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div
|
|
36
|
-
className="haya-select-option"
|
|
37
|
-
data-selected={selected}
|
|
38
|
-
data-value={digg(loadedOption, "value")}
|
|
39
|
-
onClick={this.onOptionClicked}
|
|
40
|
-
style={{cursor: "pointer"}}
|
|
41
|
-
>
|
|
42
|
-
{presentOption(loadedOption)}
|
|
43
|
-
</div>
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
onOptionClicked = (e) => this.props.onClick(e, this.props.loadedOption)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
17
|
export default class CustomSelect extends React.PureComponent {
|
|
51
18
|
static defaultProps = {
|
|
52
19
|
multiple: false,
|
|
@@ -63,7 +30,12 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
63
30
|
multiple: PropTypes.bool.isRequired,
|
|
64
31
|
onChange: PropTypes.func,
|
|
65
32
|
options: PropTypes.oneOfType([PropTypes.array, PropTypes.func]).isRequired,
|
|
66
|
-
search: PropTypes.bool.isRequired
|
|
33
|
+
search: PropTypes.bool.isRequired,
|
|
34
|
+
toggleOptions: PropTypes.arrayOf(PropTypes.shape({
|
|
35
|
+
icon: PropTypes.string.isRequired,
|
|
36
|
+
label: PropTypes.string.isRequired,
|
|
37
|
+
value: PropTypes.string.isRequired
|
|
38
|
+
}))
|
|
67
39
|
}
|
|
68
40
|
|
|
69
41
|
endOfSelectRef = React.createRef()
|
|
@@ -78,7 +50,8 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
78
50
|
optionsTop: undefined,
|
|
79
51
|
optionsWidth: undefined,
|
|
80
52
|
scrollLeft: undefined,
|
|
81
|
-
scrollTop: undefined
|
|
53
|
+
scrollTop: undefined,
|
|
54
|
+
toggled: {}
|
|
82
55
|
}
|
|
83
56
|
|
|
84
57
|
defaultCurrentOptions() {
|
|
@@ -106,16 +79,16 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
106
79
|
}
|
|
107
80
|
|
|
108
81
|
componentDidMount() {
|
|
109
|
-
const {attribute, defaultValuesFromOptions, model, options} = this.props
|
|
82
|
+
const {attribute, defaultValue, defaultValuesFromOptions, model, options} = this.props
|
|
110
83
|
|
|
111
|
-
if ((defaultValuesFromOptions || (attribute && model)) && typeof options == "function") {
|
|
84
|
+
if (((defaultValue || defaultValuesFromOptions) || (attribute && model)) && typeof options == "function") {
|
|
112
85
|
this.loadDefaultValuesFromOptionsCallback()
|
|
113
86
|
}
|
|
114
87
|
}
|
|
115
88
|
|
|
116
89
|
render() {
|
|
117
90
|
const {endOfSelectRef} = digs(this, "endOfSelectRef")
|
|
118
|
-
const {attribute, className, defaultValue, defaultValues, model, multiple, onChange, options, search, ...restProps} = this.props
|
|
91
|
+
const {attribute, className, defaultValue, defaultValues, model, multiple, onChange, options, search, toggleOptions, ...restProps} = this.props
|
|
119
92
|
const {currentOptions, opened} = digs(this.state, "currentOptions", "opened")
|
|
120
93
|
const BodyPortal = config.getBodyPortal()
|
|
121
94
|
|
|
@@ -158,7 +131,7 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
158
131
|
type="hidden"
|
|
159
132
|
value={digg(currentOption, "value")}
|
|
160
133
|
/>
|
|
161
|
-
{presentOption(currentOption)}
|
|
134
|
+
{this.presentOption(currentOption)}
|
|
162
135
|
</div>
|
|
163
136
|
)}
|
|
164
137
|
</>
|
|
@@ -170,9 +143,10 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
170
143
|
}
|
|
171
144
|
|
|
172
145
|
defaultValues () {
|
|
173
|
-
const {attribute, defaultValuesFromOptions, model} = this.props
|
|
146
|
+
const {attribute, defaultValue, defaultValuesFromOptions, model} = this.props
|
|
174
147
|
|
|
175
148
|
if (defaultValuesFromOptions) return defaultValuesFromOptions
|
|
149
|
+
if (defaultValue) return defaultValue
|
|
176
150
|
|
|
177
151
|
if (attribute && model) {
|
|
178
152
|
if (!(attribute in model)) throw new Error(`No such attribute on ${model.modelClassData().name}: ${attribute}`)
|
|
@@ -209,6 +183,24 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
209
183
|
this.setState({loadedOptions})
|
|
210
184
|
}
|
|
211
185
|
|
|
186
|
+
hayaSelectOption({key, loadedOption}) {
|
|
187
|
+
const {currentOptions} = digs(this.state, "currentOptions")
|
|
188
|
+
const selected = Boolean(currentOptions.find((currentOption) => currentOption.value == loadedOption.value))
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<div
|
|
192
|
+
className="haya-select-option"
|
|
193
|
+
data-selected={selected}
|
|
194
|
+
data-value={digg(loadedOption, "value")}
|
|
195
|
+
key={key}
|
|
196
|
+
onClick={(e) => this.onOptionClicked(e, loadedOption)}
|
|
197
|
+
style={{cursor: "pointer"}}
|
|
198
|
+
>
|
|
199
|
+
{this.presentOption(loadedOption)}
|
|
200
|
+
</div>
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
212
204
|
loadOptionsFromArray(options, searchValue) {
|
|
213
205
|
const lowerSearchValue = searchValue?.toLowerCase()
|
|
214
206
|
const loadedOptions = options.filter(({text}) => !lowerSearchValue || text.toLowerCase().includes(lowerSearchValue))
|
|
@@ -273,7 +265,6 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
273
265
|
optionsContainer() {
|
|
274
266
|
const {optionsContainerRef} = digs(this, "endOfSelectRef", "optionsContainerRef")
|
|
275
267
|
const {
|
|
276
|
-
currentOptions,
|
|
277
268
|
loadedOptions,
|
|
278
269
|
optionsLeft,
|
|
279
270
|
optionsTop,
|
|
@@ -282,7 +273,6 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
282
273
|
scrollTop
|
|
283
274
|
} = digs(
|
|
284
275
|
this.state,
|
|
285
|
-
"currentOptions",
|
|
286
276
|
"loadedOptions",
|
|
287
277
|
"currentOptions",
|
|
288
278
|
"opened",
|
|
@@ -306,12 +296,10 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
306
296
|
>
|
|
307
297
|
<EventListener event="click" onCalled={this.onWindowClicked} target={window} />
|
|
308
298
|
{loadedOptions?.map((loadedOption) =>
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
onClick={this.onOptionClicked}
|
|
314
|
-
/>
|
|
299
|
+
this.hayaSelectOption({
|
|
300
|
+
key: `loaded-option-${digg(loadedOption.value)}`,
|
|
301
|
+
loadedOption
|
|
302
|
+
})
|
|
315
303
|
)}
|
|
316
304
|
{loadedOptions?.length === 0 &&
|
|
317
305
|
<div className="haya-select-no-options-container">
|
|
@@ -326,26 +314,87 @@ export default class CustomSelect extends React.PureComponent {
|
|
|
326
314
|
e.preventDefault()
|
|
327
315
|
e.stopPropagation()
|
|
328
316
|
|
|
329
|
-
const {onChange} = this.props
|
|
317
|
+
const {onChange, toggleOptions} = this.props
|
|
330
318
|
const {multiple} = digs(this.props, "multiple")
|
|
331
319
|
|
|
332
|
-
this.setState(
|
|
333
|
-
|
|
320
|
+
this.setState(
|
|
321
|
+
(prevState) => {
|
|
322
|
+
const existingOption = prevState.currentOptions.find((currentOption) => currentOption.value == loadedOption.value)
|
|
323
|
+
const newState = {}
|
|
324
|
+
const {toggled} = digs(prevState, "toggled")
|
|
325
|
+
const newToggled = {...toggled}
|
|
326
|
+
|
|
327
|
+
if (existingOption) {
|
|
328
|
+
if (toggleOptions) {
|
|
329
|
+
const currentIndex = digg(toggled, loadedOption.value)
|
|
330
|
+
|
|
331
|
+
if (currentIndex >= (toggleOptions.length - 1)) {
|
|
332
|
+
delete newToggled[loadedOption.value]
|
|
333
|
+
|
|
334
|
+
newState.currentOptions = prevState.currentOptions.filter((currentOption) => currentOption.value != loadedOption.value)
|
|
335
|
+
} else {
|
|
336
|
+
newToggled[loadedOption.value] = toggled[loadedOption.value] + 1
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
newState.toggled = newToggled
|
|
340
|
+
} else {
|
|
341
|
+
newState.currentOptions = prevState.currentOptions.filter((currentOption) => currentOption.value != loadedOption.value)
|
|
342
|
+
}
|
|
343
|
+
} else {
|
|
344
|
+
if (toggleOptions) {
|
|
345
|
+
newToggled[loadedOption.value] = 0
|
|
346
|
+
newState.toggled = newToggled
|
|
347
|
+
}
|
|
334
348
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
349
|
+
if (multiple || toggleOptions) {
|
|
350
|
+
newState.currentOptions = prevState.currentOptions.concat([loadedOption])
|
|
351
|
+
} else {
|
|
352
|
+
newState.currentOptions = [loadedOption]
|
|
353
|
+
}
|
|
338
354
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
355
|
+
|
|
356
|
+
return newState
|
|
357
|
+
},
|
|
358
|
+
() => {
|
|
359
|
+
if (onChange) {
|
|
360
|
+
const toggles = {}
|
|
361
|
+
|
|
362
|
+
for(const toggleKey in this.state.toggled) {
|
|
363
|
+
const toggleValue = digg(this, "state", "toggled", toggleKey)
|
|
364
|
+
const toggleOption = digg(this, "props", "toggleOptions", toggleValue)
|
|
365
|
+
|
|
366
|
+
toggles[toggleKey] = toggleOption
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
onChange({
|
|
370
|
+
options: this.state.currentOptions,
|
|
371
|
+
toggles
|
|
372
|
+
})
|
|
344
373
|
}
|
|
345
374
|
}
|
|
346
|
-
|
|
375
|
+
)
|
|
347
376
|
|
|
348
377
|
if (!multiple) this.closeOptions()
|
|
349
|
-
|
|
378
|
+
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
presentOption = (currentValue) => {
|
|
382
|
+
const {toggleOptions} = this.props
|
|
383
|
+
const {toggled} = digs(this.state, "toggled")
|
|
384
|
+
|
|
385
|
+
return (
|
|
386
|
+
<div>
|
|
387
|
+
{toggleOptions && !(currentValue.value in toggled) &&
|
|
388
|
+
<i className="fa fa-fw" />
|
|
389
|
+
}
|
|
390
|
+
{toggleOptions && (currentValue.value in toggled) &&
|
|
391
|
+
<i className={`fa fa-fw fa-${toggleOptions[toggled[currentValue.value]].icon}`} />
|
|
392
|
+
}
|
|
393
|
+
{currentValue.text}
|
|
394
|
+
{("html" in currentValue) &&
|
|
395
|
+
<div dangerouslySetInnerHTML={{__html: digg(currentValue, "html")}} />
|
|
396
|
+
}
|
|
397
|
+
</div>
|
|
398
|
+
)
|
|
350
399
|
}
|
|
351
400
|
}
|