haya-select 1.0.4 → 1.0.7

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/select/index.jsx +106 -58
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haya-select",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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")
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() {
@@ -115,7 +88,7 @@ export default class CustomSelect extends React.PureComponent {
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
  </>
@@ -209,6 +182,24 @@ export default class CustomSelect extends React.PureComponent {
209
182
  this.setState({loadedOptions})
210
183
  }
211
184
 
185
+ hayaSelectOption({key, loadedOption}) {
186
+ const {currentOptions} = digs(this.state, "currentOptions")
187
+ const selected = Boolean(currentOptions.find((currentOption) => currentOption.value == loadedOption.value))
188
+
189
+ return (
190
+ <div
191
+ className="haya-select-option"
192
+ data-selected={selected}
193
+ data-value={digg(loadedOption, "value")}
194
+ key={key}
195
+ onClick={(e) => this.onOptionClicked(e, loadedOption)}
196
+ style={{cursor: "pointer"}}
197
+ >
198
+ {this.presentOption(loadedOption)}
199
+ </div>
200
+ )
201
+ }
202
+
212
203
  loadOptionsFromArray(options, searchValue) {
213
204
  const lowerSearchValue = searchValue?.toLowerCase()
214
205
  const loadedOptions = options.filter(({text}) => !lowerSearchValue || text.toLowerCase().includes(lowerSearchValue))
@@ -273,7 +264,6 @@ export default class CustomSelect extends React.PureComponent {
273
264
  optionsContainer() {
274
265
  const {optionsContainerRef} = digs(this, "endOfSelectRef", "optionsContainerRef")
275
266
  const {
276
- currentOptions,
277
267
  loadedOptions,
278
268
  optionsLeft,
279
269
  optionsTop,
@@ -282,7 +272,6 @@ export default class CustomSelect extends React.PureComponent {
282
272
  scrollTop
283
273
  } = digs(
284
274
  this.state,
285
- "currentOptions",
286
275
  "loadedOptions",
287
276
  "currentOptions",
288
277
  "opened",
@@ -306,12 +295,10 @@ export default class CustomSelect extends React.PureComponent {
306
295
  >
307
296
  <EventListener event="click" onCalled={this.onWindowClicked} target={window} />
308
297
  {loadedOptions?.map((loadedOption) =>
309
- <LoadedOption
310
- currentOptions={currentOptions}
311
- key={`loaded-option-${digg(loadedOption.value)}`}
312
- loadedOption={loadedOption}
313
- onClick={this.onOptionClicked}
314
- />
298
+ this.hayaSelectOption({
299
+ key: `loaded-option-${digg(loadedOption.value)}`,
300
+ loadedOption
301
+ })
315
302
  )}
316
303
  {loadedOptions?.length === 0 &&
317
304
  <div className="haya-select-no-options-container">
@@ -326,26 +313,87 @@ export default class CustomSelect extends React.PureComponent {
326
313
  e.preventDefault()
327
314
  e.stopPropagation()
328
315
 
329
- const {onChange} = this.props
316
+ const {onChange, toggleOptions} = this.props
330
317
  const {multiple} = digs(this.props, "multiple")
331
318
 
332
- this.setState((prevState) => {
333
- const existingOption = prevState.currentOptions.find((currentOption) => currentOption.value == loadedOption.value)
319
+ this.setState(
320
+ (prevState) => {
321
+ const existingOption = prevState.currentOptions.find((currentOption) => currentOption.value == loadedOption.value)
322
+ const newState = {}
323
+ const {toggled} = digs(prevState, "toggled")
324
+ const newToggled = {...toggled}
325
+
326
+ if (existingOption) {
327
+ if (toggleOptions) {
328
+ const currentIndex = digg(toggled, loadedOption.value)
329
+
330
+ if (currentIndex >= (toggleOptions.length - 1)) {
331
+ delete newToggled[loadedOption.value]
332
+
333
+ newState.currentOptions = prevState.currentOptions.filter((currentOption) => currentOption.value != loadedOption.value)
334
+ } else {
335
+ newToggled[loadedOption.value] = toggled[loadedOption.value] + 1
336
+ }
337
+
338
+ newState.toggled = newToggled
339
+ } else {
340
+ newState.currentOptions = prevState.currentOptions.filter((currentOption) => currentOption.value != loadedOption.value)
341
+ }
342
+ } else {
343
+ if (toggleOptions) {
344
+ newToggled[loadedOption.value] = 0
345
+ newState.toggled = newToggled
346
+ }
334
347
 
335
- if (existingOption) {
336
- return {
337
- currentOptions: prevState.currentOptions.filter((currentOption) => currentOption.value != loadedOption.value)
348
+ if (multiple || toggleOptions) {
349
+ newState.currentOptions = prevState.currentOptions.concat([loadedOption])
350
+ } else {
351
+ newState.currentOptions = [loadedOption]
352
+ }
338
353
  }
339
- } else {
340
- if (multiple) {
341
- return {currentOptions: prevState.currentOptions.concat([loadedOption])}
342
- } else {
343
- return {currentOptions: [loadedOption]}
354
+
355
+ return newState
356
+ },
357
+ () => {
358
+ if (onChange) {
359
+ const toggles = {}
360
+
361
+ for(const toggleKey in this.state.toggled) {
362
+ const toggleValue = digg(this, "state", "toggled", toggleKey)
363
+ const toggleOption = digg(this, "props", "toggleOptions", toggleValue)
364
+
365
+ toggles[toggleKey] = toggleOption
366
+ }
367
+
368
+ onChange({
369
+ options: this.state.currentOptions,
370
+ toggles
371
+ })
344
372
  }
345
373
  }
346
- })
374
+ )
347
375
 
348
376
  if (!multiple) this.closeOptions()
349
- if (onChange) onChange(loadedOption)
377
+
378
+ }
379
+
380
+ presentOption = (currentValue) => {
381
+ const {toggleOptions} = this.props
382
+ const {toggled} = digs(this.state, "toggled")
383
+
384
+ return (
385
+ <div>
386
+ {toggleOptions && !(currentValue.value in toggled) &&
387
+ <i className="fa fa-fw" />
388
+ }
389
+ {toggleOptions && (currentValue.value in toggled) &&
390
+ <i className={`fa fa-fw fa-${toggleOptions[toggled[currentValue.value]].icon}`} />
391
+ }
392
+ {currentValue.text}
393
+ {("html" in currentValue) &&
394
+ <div dangerouslySetInnerHTML={{__html: digg(currentValue, "html")}} />
395
+ }
396
+ </div>
397
+ )
350
398
  }
351
399
  }