haya-select 1.0.15 → 1.0.17
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/package.json +3 -2
- package/src/select/index.jsx +65 -58
- package/src/select/option-group.jsx +16 -0
- package/src/select/option.jsx +34 -0
- package/src/select/style.scss +26 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haya-select",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"classnames": "^2.3.1",
|
|
13
13
|
"debounce": "^1.2.1",
|
|
14
|
-
"diggerize": "^1.0.4"
|
|
14
|
+
"diggerize": "^1.0.4",
|
|
15
|
+
"fetching-object": "^1.0.1"
|
|
15
16
|
},
|
|
16
17
|
"peerDependencies": {
|
|
17
18
|
"prop-types": ">= 15.7.2",
|
package/src/select/index.jsx
CHANGED
|
@@ -6,7 +6,10 @@ import debounce from "debounce"
|
|
|
6
6
|
import EventListener from "@kaspernj/api-maker/src/event-listener"
|
|
7
7
|
import idForComponent from "@kaspernj/api-maker/src/inputs/id-for-component.mjs"
|
|
8
8
|
import nameForComponent from "@kaspernj/api-maker/src/inputs/name-for-component.mjs"
|
|
9
|
+
import Option from "./option"
|
|
10
|
+
import OptionGroup from "./option-group"
|
|
9
11
|
import PropTypes from "prop-types"
|
|
12
|
+
import React from "react"
|
|
10
13
|
|
|
11
14
|
const nameForComponentWithMultiple = (component) => {
|
|
12
15
|
let name = nameForComponent(component)
|
|
@@ -44,6 +47,10 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
44
47
|
}))
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
p = fetchingObject(() => this.props)
|
|
51
|
+
s = fetchingObject(() => this.state)
|
|
52
|
+
t = fetchingObject(this)
|
|
53
|
+
|
|
47
54
|
endOfSelectRef = React.createRef()
|
|
48
55
|
optionsContainerRef = React.createRef()
|
|
49
56
|
searchTextInputRef = React.createRef()
|
|
@@ -62,7 +69,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
62
69
|
|
|
63
70
|
defaultCurrentOptions() {
|
|
64
71
|
const {defaultValue, defaultValues} = this.props
|
|
65
|
-
const {options} =
|
|
72
|
+
const {options} = this.p
|
|
66
73
|
|
|
67
74
|
if (!Array.isArray(options)) return []
|
|
68
75
|
|
|
@@ -73,7 +80,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
defaultLoadedOptions() {
|
|
76
|
-
const {options} =
|
|
83
|
+
const {options} = this.p
|
|
77
84
|
|
|
78
85
|
if (typeof options == "function") {
|
|
79
86
|
return undefined
|
|
@@ -93,7 +100,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
93
100
|
}
|
|
94
101
|
|
|
95
102
|
render() {
|
|
96
|
-
const {endOfSelectRef} =
|
|
103
|
+
const {endOfSelectRef} = this.t
|
|
97
104
|
const {
|
|
98
105
|
attribute,
|
|
99
106
|
className,
|
|
@@ -110,13 +117,14 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
110
117
|
toggleOptions,
|
|
111
118
|
...restProps
|
|
112
119
|
} = this.props
|
|
113
|
-
const {currentOptions, opened} =
|
|
120
|
+
const {currentOptions, opened} = this.s
|
|
114
121
|
const BodyPortal = config.getBodyPortal()
|
|
115
122
|
|
|
116
123
|
return (
|
|
117
124
|
<div
|
|
118
125
|
className={classNames("haya-select", className)}
|
|
119
126
|
data-id={idForComponent(this)}
|
|
127
|
+
data-toggles={Boolean(toggleOptions)}
|
|
120
128
|
{...restProps}
|
|
121
129
|
>
|
|
122
130
|
{opened &&
|
|
@@ -145,16 +153,25 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
145
153
|
</div>
|
|
146
154
|
}
|
|
147
155
|
{currentOptions.map((currentOption) =>
|
|
148
|
-
<div className="current-option" key={`current-value-${
|
|
149
|
-
{
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
<div className="current-option" key={currentOption.key || `current-value-${currentOption.value}`}>
|
|
157
|
+
{currentOption.type == "group" &&
|
|
158
|
+
<div style={{fontWeight: "bold"}}>
|
|
159
|
+
{currentOption.text}
|
|
160
|
+
</div>
|
|
161
|
+
}
|
|
162
|
+
{currentOption.type != "group" &&
|
|
163
|
+
<>
|
|
164
|
+
{nameForComponentWithMultiple(this) &&
|
|
165
|
+
<input
|
|
166
|
+
id={idForComponent(this)}
|
|
167
|
+
name={nameForComponentWithMultiple(this)}
|
|
168
|
+
type="hidden"
|
|
169
|
+
value={digg(currentOption, "value")}
|
|
170
|
+
/>
|
|
171
|
+
}
|
|
172
|
+
{this.presentOption(currentOption)}
|
|
173
|
+
</>
|
|
156
174
|
}
|
|
157
|
-
{this.presentOption(currentOption)}
|
|
158
175
|
</div>
|
|
159
176
|
)}
|
|
160
177
|
</>
|
|
@@ -195,7 +212,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
195
212
|
}
|
|
196
213
|
|
|
197
214
|
loadOptions = async () => {
|
|
198
|
-
const {options} =
|
|
215
|
+
const {options} = this.p
|
|
199
216
|
const searchValue = digg(this, "searchTextInputRef", "current")?.value
|
|
200
217
|
|
|
201
218
|
if (Array.isArray(options)) {
|
|
@@ -208,21 +225,18 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
208
225
|
}
|
|
209
226
|
|
|
210
227
|
hayaSelectOption({key, loadedOption}) {
|
|
211
|
-
|
|
212
|
-
|
|
228
|
+
if (loadedOption.type == "group") {
|
|
229
|
+
return <OptionGroup key={key} option={loadedOption} />
|
|
230
|
+
}
|
|
213
231
|
|
|
214
|
-
return
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
>
|
|
223
|
-
{this.presentOption(loadedOption)}
|
|
224
|
-
</div>
|
|
225
|
-
)
|
|
232
|
+
return <Option
|
|
233
|
+
currentOptions={this.state.currentOptions}
|
|
234
|
+
icon={this.iconForOption(loadedOption)}
|
|
235
|
+
key={key}
|
|
236
|
+
option={loadedOption}
|
|
237
|
+
onOptionClicked={this.onOptionClicked}
|
|
238
|
+
presentOption={this.presentOption}
|
|
239
|
+
/>
|
|
226
240
|
}
|
|
227
241
|
|
|
228
242
|
loadOptionsFromArray(options, searchValue) {
|
|
@@ -236,7 +250,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
236
250
|
e.preventDefault()
|
|
237
251
|
e.stopPropagation()
|
|
238
252
|
|
|
239
|
-
const {opened} =
|
|
253
|
+
const {opened} = this.s
|
|
240
254
|
|
|
241
255
|
if (opened) {
|
|
242
256
|
this.closeOptions()
|
|
@@ -255,7 +269,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
255
269
|
}
|
|
256
270
|
|
|
257
271
|
openOptions() {
|
|
258
|
-
const {endOfSelectRef} =
|
|
272
|
+
const {endOfSelectRef} = this.t
|
|
259
273
|
const position = endOfSelectRef.current.getBoundingClientRect()
|
|
260
274
|
const {left, top, width} = digs(position, "left", "top", "width")
|
|
261
275
|
|
|
@@ -270,15 +284,13 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
270
284
|
scrollLeft: document.documentElement.scrollLeft,
|
|
271
285
|
scrollTop: document.documentElement.scrollTop
|
|
272
286
|
},
|
|
273
|
-
() =>
|
|
274
|
-
digg(this, "searchTextInputRef", "current").focus()
|
|
275
|
-
}
|
|
287
|
+
() => digg(this, "searchTextInputRef", "current").focus()
|
|
276
288
|
)
|
|
277
289
|
}
|
|
278
290
|
|
|
279
291
|
onWindowClicked = (e) => {
|
|
280
|
-
const {optionsContainerRef} =
|
|
281
|
-
const {opened} =
|
|
292
|
+
const {optionsContainerRef} = this.t
|
|
293
|
+
const {opened} = this.s
|
|
282
294
|
|
|
283
295
|
// If options are open and a click is made outside of the options container
|
|
284
296
|
if (opened && optionsContainerRef.current && !optionsContainerRef.current?.contains(e.target)) {
|
|
@@ -287,25 +299,8 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
287
299
|
}
|
|
288
300
|
|
|
289
301
|
optionsContainer() {
|
|
290
|
-
const {optionsContainerRef} =
|
|
291
|
-
const {
|
|
292
|
-
loadedOptions,
|
|
293
|
-
optionsLeft,
|
|
294
|
-
optionsTop,
|
|
295
|
-
optionsWidth,
|
|
296
|
-
scrollLeft,
|
|
297
|
-
scrollTop
|
|
298
|
-
} = digs(
|
|
299
|
-
this.state,
|
|
300
|
-
"loadedOptions",
|
|
301
|
-
"currentOptions",
|
|
302
|
-
"opened",
|
|
303
|
-
"optionsLeft",
|
|
304
|
-
"optionsTop",
|
|
305
|
-
"optionsWidth",
|
|
306
|
-
"scrollLeft",
|
|
307
|
-
"scrollTop"
|
|
308
|
-
)
|
|
302
|
+
const {optionsContainerRef} = this.t
|
|
303
|
+
const {loadedOptions, optionsLeft, optionsTop, optionsWidth, scrollLeft, scrollTop} = this.s
|
|
309
304
|
|
|
310
305
|
return (
|
|
311
306
|
<div
|
|
@@ -321,7 +316,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
321
316
|
<EventListener event="click" onCalled={this.onWindowClicked} target={window} />
|
|
322
317
|
{loadedOptions?.map((loadedOption) =>
|
|
323
318
|
this.hayaSelectOption({
|
|
324
|
-
key: `loaded-option-${
|
|
319
|
+
key: loadedOption.key || `loaded-option-${loadedOption.value}`,
|
|
325
320
|
loadedOption
|
|
326
321
|
})
|
|
327
322
|
)}
|
|
@@ -339,7 +334,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
339
334
|
e.stopPropagation()
|
|
340
335
|
|
|
341
336
|
const {onChange, toggleOptions} = this.props
|
|
342
|
-
const {multiple} =
|
|
337
|
+
const {multiple} = this.p
|
|
343
338
|
|
|
344
339
|
this.setState(
|
|
345
340
|
(prevState) => {
|
|
@@ -401,9 +396,21 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
401
396
|
if (!multiple) this.closeOptions()
|
|
402
397
|
}
|
|
403
398
|
|
|
399
|
+
iconForOption(option) {
|
|
400
|
+
const {toggleOptions} = this.props || {}
|
|
401
|
+
const {toggled} = this.s
|
|
402
|
+
|
|
403
|
+
if (toggleOptions && (option.value in toggled)) {
|
|
404
|
+
const icon = toggleOptions[toggled[option.value]].icon
|
|
405
|
+
|
|
406
|
+
return icon
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
404
410
|
presentOption = (currentValue) => {
|
|
405
411
|
const {toggleOptions} = this.props || {}
|
|
406
|
-
const {toggled} =
|
|
412
|
+
const {toggled} = this.s
|
|
413
|
+
const icon = this.iconForOption(currentValue)
|
|
407
414
|
|
|
408
415
|
return (
|
|
409
416
|
<div
|
|
@@ -416,7 +423,7 @@ export default class HayaSelect extends React.PureComponent {
|
|
|
416
423
|
<i className="fa fa-fw" />
|
|
417
424
|
}
|
|
418
425
|
{toggleOptions && (currentValue.value in toggled) &&
|
|
419
|
-
<i className={`fa fa-fw fa-${
|
|
426
|
+
<i className={`fa fa-fw fa-${icon}`} />
|
|
420
427
|
}
|
|
421
428
|
{currentValue.text}
|
|
422
429
|
{("html" in currentValue) &&
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import PropTypes from "prop-types"
|
|
2
|
+
import React from "react"
|
|
3
|
+
|
|
4
|
+
export default class OptionGroup extends React.PureComponent {
|
|
5
|
+
static propTypes = {
|
|
6
|
+
option: PropTypes.object.isRequired
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
render() {
|
|
10
|
+
return (
|
|
11
|
+
<div className="haya-select--option-group">
|
|
12
|
+
{this.props.option.text}
|
|
13
|
+
</div>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {digs} from "diggerize"
|
|
2
|
+
import PropTypes from "prop-types"
|
|
3
|
+
import React from "react"
|
|
4
|
+
|
|
5
|
+
export default class Option extends React.PureComponent {
|
|
6
|
+
static propTypes = {
|
|
7
|
+
currentOptions: PropTypes.array.isRequired,
|
|
8
|
+
icon: PropTypes.string,
|
|
9
|
+
onOptionClicked: PropTypes.func.isRequired,
|
|
10
|
+
option: PropTypes.object.isRequired,
|
|
11
|
+
presentOption: PropTypes.func.isRequired
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
style = {cursor: "pointer"}
|
|
15
|
+
|
|
16
|
+
render() {
|
|
17
|
+
const {currentOptions, option} = digs(this.props, "currentOptions", "option")
|
|
18
|
+
const selected = Boolean(currentOptions.find((currentOption) => currentOption.value == option.value))
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div
|
|
22
|
+
className="haya-select-option"
|
|
23
|
+
data-selected={selected}
|
|
24
|
+
data-value={option.value}
|
|
25
|
+
onClick={this.onClick}
|
|
26
|
+
style={this.style}
|
|
27
|
+
>
|
|
28
|
+
{this.props.presentOption(option)}
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
onClick = (e) => this.props.onOptionClicked(e, this.props.option)
|
|
34
|
+
}
|
package/src/select/style.scss
CHANGED
|
@@ -1,15 +1,25 @@
|
|
|
1
|
-
.haya-select
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
.haya-select {
|
|
2
|
+
.haya-select-current-selected {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-wrap: wrap;
|
|
5
|
+
background-color: #fff;
|
|
6
|
+
border: 1px solid #999;
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
padding-top: 5px;
|
|
9
|
+
padding-bottom: 5px;
|
|
10
|
+
padding-left: 5px;
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
&[data-opened="false"] {
|
|
13
|
+
border-radius: 4px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&[data-opened="true"] {
|
|
17
|
+
border-radius: 4px 4px 0 0;
|
|
18
|
+
}
|
|
10
19
|
|
|
11
|
-
|
|
12
|
-
|
|
20
|
+
.current-option {
|
|
21
|
+
margin-right: 6px;
|
|
22
|
+
}
|
|
13
23
|
}
|
|
14
24
|
}
|
|
15
25
|
|
|
@@ -39,4 +49,10 @@
|
|
|
39
49
|
background-color: steelblue;
|
|
40
50
|
}
|
|
41
51
|
}
|
|
52
|
+
|
|
53
|
+
.haya-select--option-group {
|
|
54
|
+
padding: 4px 8px;
|
|
55
|
+
color: #000;
|
|
56
|
+
font-weight: bold;
|
|
57
|
+
}
|
|
42
58
|
}
|