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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haya-select",
3
- "version": "1.0.15",
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",
@@ -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} = digs(this.props, "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} = digs(this.props, "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} = digs(this, "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} = digs(this.state, "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-${digg(currentOption, "value")}`}>
149
- {nameForComponentWithMultiple(this) &&
150
- <input
151
- id={idForComponent(this)}
152
- name={nameForComponentWithMultiple(this)}
153
- type="hidden"
154
- value={digg(currentOption, "value")}
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} = digs(this.props, "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
- const {currentOptions} = digs(this.state, "currentOptions")
212
- const selected = Boolean(currentOptions.find((currentOption) => currentOption.value == loadedOption.value))
228
+ if (loadedOption.type == "group") {
229
+ return <OptionGroup key={key} option={loadedOption} />
230
+ }
213
231
 
214
- return (
215
- <div
216
- className="haya-select-option"
217
- data-selected={selected}
218
- data-value={digg(loadedOption, "value")}
219
- key={key}
220
- onClick={(e) => this.onOptionClicked(e, loadedOption)}
221
- style={{cursor: "pointer"}}
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} = digs(this.state, "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} = digs(this, "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} = digs(this, "optionsContainerRef")
281
- const {opened} = digs(this.state, "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} = digs(this, "endOfSelectRef", "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-${digg(loadedOption.value)}`,
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} = digs(this.props, "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} = digs(this.state, "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-${toggleOptions[toggled[currentValue.value]].icon}`} />
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
+ }
@@ -1,15 +1,25 @@
1
- .haya-select-current-selected {
2
- background-color: #fff;
3
- border: 1px solid #999;
4
- cursor: pointer;
5
- padding: 5px;
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
- &[data-opened="false"] {
8
- border-radius: 4px;
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
- &[data-opened="true"] {
12
- border-radius: 4px 4px 0 0;
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
  }