superdesk-ui-framework 3.0.1-beta.9 → 3.0.1

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 (160) hide show
  1. package/app/fonts/sd_icons.eot +0 -0
  2. package/app/fonts/sd_icons.svg +1 -0
  3. package/app/fonts/sd_icons.ttf +0 -0
  4. package/app/fonts/sd_icons.woff +0 -0
  5. package/app/scripts/toggleBoxNext.js +1 -1
  6. package/app/styles/_big-icon-font.scss +1 -1
  7. package/app/styles/_buttons.scss +11 -6
  8. package/app/styles/_content-divider.scss +63 -8
  9. package/app/styles/_helpers.scss +24 -1
  10. package/app/styles/_icon-font.scss +11 -10
  11. package/app/styles/_labels.scss +0 -1
  12. package/app/styles/_master-desk.scss +5 -4
  13. package/app/styles/_modals.scss +7 -3
  14. package/app/styles/_normalize.scss +4 -0
  15. package/app/styles/_sd-tag-input.scss +56 -2
  16. package/app/styles/_simple-list.scss +0 -2
  17. package/app/styles/_table-list.scss +116 -12
  18. package/app/styles/app.scss +3 -0
  19. package/app/styles/components/_list-item.scss +23 -16
  20. package/app/styles/components/_sd-collapse-box.scss +6 -6
  21. package/app/styles/components/_sd-comment-box.scss +8 -4
  22. package/app/styles/components/_sd-editor-popup.scss +4 -4
  23. package/app/styles/components/_sd-media-carousel.scss +37 -2
  24. package/app/styles/components/_sd-pagination.scss +41 -0
  25. package/app/styles/components/_sd-photo-preview.scss +2 -2
  26. package/app/styles/components/_subnav.scss +470 -470
  27. package/app/styles/design-tokens/_new-colors.scss +29 -12
  28. package/app/styles/dropdowns/_basic-dropdown.scss +6 -0
  29. package/app/styles/form-elements/_input-wrap.scss +138 -0
  30. package/app/styles/form-elements/_inputs.scss +230 -61
  31. package/app/styles/grids/_grid-layout.scss +13 -14
  32. package/app/styles/interface-elements/_side-panel.scss +1 -1
  33. package/app/styles/layout/_editor.scss +6 -0
  34. package/app/styles/menus/_sd-sidebar-menu.scss +1 -1
  35. package/app/styles/primereact/_pr-datepicker.scss +16 -2
  36. package/app/styles/primereact/_pr-dialog.scss +9 -0
  37. package/app/styles/primereact/_pr-menu.scss +6 -5
  38. package/app/styles/variables/_colors.scss +47 -47
  39. package/app/template/search-handler.html +2 -2
  40. package/app-typescript/components/ContentDivider.tsx +3 -0
  41. package/app-typescript/components/DatePicker.tsx +8 -9
  42. package/app-typescript/components/Dropdown.tsx +127 -82
  43. package/app-typescript/components/DurationInput.tsx +39 -14
  44. package/app-typescript/components/Form/FormLabel.tsx +8 -1
  45. package/app-typescript/components/Form/InputBase.tsx +12 -2
  46. package/app-typescript/components/Input.tsx +4 -4
  47. package/app-typescript/components/Label.tsx +17 -1
  48. package/app-typescript/components/Layouts/AuthoringFrame.tsx +2 -1
  49. package/app-typescript/components/Layouts/AuthoringFrameRightBar.tsx +21 -2
  50. package/app-typescript/components/Layouts/AuthoringInnerHeader.tsx +1 -1
  51. package/app-typescript/components/Layouts/AuthoringMain.tsx +4 -2
  52. package/app-typescript/components/Layouts/CoreLayout.tsx +3 -1
  53. package/app-typescript/components/Layouts/CoreLayoutMain.tsx +10 -1
  54. package/app-typescript/components/Lists/ContentList.tsx +64 -30
  55. package/app-typescript/components/Lists/TableList.tsx +255 -53
  56. package/app-typescript/components/Menu.tsx +2 -2
  57. package/app-typescript/components/Modal.tsx +6 -2
  58. package/app-typescript/components/MultiSelect.tsx +1 -1
  59. package/app-typescript/components/NavButton.tsx +2 -1
  60. package/app-typescript/components/Navigation/SideBarMenu.tsx +30 -4
  61. package/app-typescript/components/SearchBar.tsx +11 -3
  62. package/app-typescript/components/Spacer.tsx +87 -0
  63. package/app-typescript/components/TimePicker.tsx +2 -13
  64. package/app-typescript/components/TreeSelect.tsx +286 -180
  65. package/app-typescript/index.ts +1 -0
  66. package/dist/examples.bundle.css +110 -71
  67. package/dist/examples.bundle.js +23848 -21661
  68. package/dist/playgrounds/react-playgrounds/CoreLayout.tsx +505 -2
  69. package/dist/playgrounds/react-playgrounds/Index.tsx +1 -0
  70. package/dist/playgrounds/react-playgrounds/Multiedit.tsx +321 -0
  71. package/dist/playgrounds/react-playgrounds/RundownEditor.tsx +17 -19
  72. package/dist/playgrounds/react-playgrounds/Rundowns.tsx +22 -23
  73. package/dist/playgrounds/react-playgrounds/TestGround.tsx +226 -25
  74. package/dist/react/ContentDivider.tsx +22 -18
  75. package/dist/react/ContentList.tsx +188 -12
  76. package/dist/react/DatePicker.tsx +50 -2
  77. package/dist/react/Dropdowns.tsx +580 -48
  78. package/dist/react/DurationInput.tsx +7 -3
  79. package/dist/react/Inputs.tsx +1 -7
  80. package/dist/react/Modal.tsx +154 -22
  81. package/dist/react/MultiSelect.tsx +5 -5
  82. package/dist/react/NavButtons.tsx +31 -1
  83. package/dist/react/TableList.tsx +52 -139
  84. package/dist/react/Togglebox.tsx +1 -1
  85. package/dist/react/TreeSelect.tsx +167 -176
  86. package/dist/sd_icons.eot +0 -0
  87. package/dist/sd_icons.svg +1 -0
  88. package/dist/sd_icons.ttf +0 -0
  89. package/dist/sd_icons.woff +0 -0
  90. package/dist/superdesk-ui.bundle.css +1100 -407
  91. package/dist/superdesk-ui.bundle.js +6591 -4035
  92. package/dist/vendor.bundle.js +27 -27
  93. package/examples/css/docs-page.css +4 -4
  94. package/examples/index.js +4 -0
  95. package/examples/pages/playgrounds/react-playgrounds/CoreLayout.tsx +505 -2
  96. package/examples/pages/playgrounds/react-playgrounds/Index.tsx +1 -0
  97. package/examples/pages/playgrounds/react-playgrounds/Multiedit.tsx +321 -0
  98. package/examples/pages/playgrounds/react-playgrounds/RundownEditor.tsx +17 -19
  99. package/examples/pages/playgrounds/react-playgrounds/Rundowns.tsx +22 -23
  100. package/examples/pages/playgrounds/react-playgrounds/TestGround.tsx +226 -25
  101. package/examples/pages/react/ContentDivider.tsx +22 -18
  102. package/examples/pages/react/ContentList.tsx +188 -12
  103. package/examples/pages/react/DatePicker.tsx +50 -2
  104. package/examples/pages/react/Dropdowns.tsx +580 -48
  105. package/examples/pages/react/DurationInput.tsx +7 -3
  106. package/examples/pages/react/Inputs.tsx +1 -7
  107. package/examples/pages/react/Modal.tsx +154 -22
  108. package/examples/pages/react/MultiSelect.tsx +5 -5
  109. package/examples/pages/react/NavButtons.tsx +31 -1
  110. package/examples/pages/react/TableList.tsx +52 -139
  111. package/examples/pages/react/Togglebox.tsx +1 -1
  112. package/examples/pages/react/TreeSelect.tsx +167 -176
  113. package/package.json +3 -5
  114. package/react/components/ContentDivider.d.ts +1 -0
  115. package/react/components/ContentDivider.js +2 -0
  116. package/react/components/DatePicker.d.ts +2 -2
  117. package/react/components/DatePicker.js +3 -3
  118. package/react/components/Dropdown.d.ts +6 -5
  119. package/react/components/Dropdown.js +57 -30
  120. package/react/components/DurationInput.d.ts +1 -1
  121. package/react/components/DurationInput.js +46 -17
  122. package/react/components/Form/FormLabel.d.ts +4 -1
  123. package/react/components/Form/FormLabel.js +9 -3
  124. package/react/components/Form/InputBase.d.ts +0 -1
  125. package/react/components/Form/InputBase.js +15 -1
  126. package/react/components/Input.d.ts +3 -3
  127. package/react/components/Input.js +2 -1
  128. package/react/components/Label.d.ts +1 -0
  129. package/react/components/Label.js +17 -2
  130. package/react/components/Layouts/AuthoringFrame.d.ts +1 -0
  131. package/react/components/Layouts/AuthoringFrame.js +1 -1
  132. package/react/components/Layouts/AuthoringFrameRightBar.d.ts +9 -2
  133. package/react/components/Layouts/AuthoringFrameRightBar.js +14 -3
  134. package/react/components/Layouts/AuthoringInnerHeader.js +1 -1
  135. package/react/components/Layouts/AuthoringMain.js +1 -1
  136. package/react/components/Layouts/CoreLayout.d.ts +2 -0
  137. package/react/components/Layouts/CoreLayout.js +1 -1
  138. package/react/components/Layouts/CoreLayoutMain.d.ts +2 -0
  139. package/react/components/Layouts/CoreLayoutMain.js +8 -1
  140. package/react/components/Lists/ContentList.d.ts +6 -0
  141. package/react/components/Lists/ContentList.js +42 -16
  142. package/react/components/Lists/TableList.d.ts +30 -8
  143. package/react/components/Lists/TableList.js +127 -24
  144. package/react/components/Menu.js +1 -1
  145. package/react/components/Modal.d.ts +2 -0
  146. package/react/components/Modal.js +3 -3
  147. package/react/components/MultiSelect.d.ts +40 -0
  148. package/react/components/MultiSelect.js +70 -0
  149. package/react/components/NavButton.d.ts +1 -1
  150. package/react/components/Navigation/SideBarMenu.d.ts +6 -0
  151. package/react/components/Navigation/SideBarMenu.js +19 -2
  152. package/react/components/SearchBar.d.ts +1 -1
  153. package/react/components/SearchBar.js +15 -7
  154. package/react/components/TimePicker.d.ts +1 -5
  155. package/react/components/TimePicker.js +3 -7
  156. package/react/components/TreeSelect.d.ts +12 -5
  157. package/react/components/TreeSelect.js +189 -116
  158. package/react/index.d.ts +1 -0
  159. package/react/index.js +3 -0
  160. package/patches/@superdesk+primereact+5.0.2-4.patch +0 -66
@@ -1,22 +1,26 @@
1
1
  import * as React from "react";
2
2
  import { Icon } from "./Icon";
3
3
  import { Loader } from "./Loader";
4
- import classNames from 'classnames';
5
4
  import nextId from "react-id-generator";
5
+ import _debounce from 'lodash/debounce';
6
+ import { InputWrapper } from "./Form";
7
+ import { createPopper } from '@popperjs/core';
8
+ import {isEqual} from 'lodash';
9
+ import {getTextColor} from './Label';
6
10
 
7
11
  interface IState<T> {
8
12
  value: Array<T>;
9
13
  options: Array<ITreeNode<T>>;
10
- firstBranchOptions: Array<any>; // to return on first branch in dropdown
11
- openDropdown: boolean; // open/close dropdown
12
- activeTree: Array<any>; // for filtered array
13
- filterArr: Array<any>; // for filtered array
14
- searchFieldValue: string; // filter value of input
15
- buttonTree: Array<any>; // array of button (for backButton)
16
- buttonValue: any; // button for name of category
17
- buttonMouseEvent: boolean; // valueButton hover
14
+ firstBranchOptions: Array<any>;
15
+ openDropdown: boolean;
16
+ activeTree: Array<any>;
17
+ filterArr: Array<any>;
18
+ searchFieldValue: string;
19
+ buttonTree: Array<any>;
20
+ buttonValue: any;
21
+ buttonMouseEvent: boolean;
18
22
  loading: boolean;
19
- invalid: boolean;
23
+ // provera: boolean;
20
24
  }
21
25
 
22
26
  interface IPropsBase<T> {
@@ -28,6 +32,7 @@ interface IPropsBase<T> {
28
32
  loading?: boolean;
29
33
  singleLevelSearch?: boolean;
30
34
  placeholder?: string;
35
+ searchPlaceholder?: string;
31
36
  invalid?: boolean;
32
37
  inlineLabel?: boolean;
33
38
  labelHidden?: boolean;
@@ -40,8 +45,10 @@ interface IPropsBase<T> {
40
45
  disabled?: boolean;
41
46
  getLabel(item: T): string;
42
47
  getId(item: T): string;
48
+ getBackgroundColor?(item: T): string;
49
+ getBorderColor?(item: T): string;
43
50
  optionTemplate?(item: T): React.ComponentType<T> | JSX.Element;
44
- valueTemplate?(item: T): React.ComponentType<T> | JSX.Element;
51
+ valueTemplate?(item: T, Wrapper: any): React.ComponentType<T> | JSX.Element;
45
52
  onChange(e: Array<T>): void;
46
53
  }
47
54
 
@@ -67,6 +74,7 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
67
74
  private dropdownRef: React.RefObject<HTMLInputElement>;
68
75
  private openDropdownRef: React.RefObject<HTMLButtonElement>;
69
76
  private htmlId: string = nextId();
77
+ private popperInstance: any;
70
78
 
71
79
  constructor(props: IProps<T>) {
72
80
  super(props);
@@ -81,8 +89,8 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
81
89
  buttonValue: [],
82
90
  buttonMouseEvent: false,
83
91
  openDropdown: false,
84
- loading: this.props.loading ? this.props.loading : false,
85
- invalid: this.props.invalid ? this.props.invalid : false,
92
+ loading: false,
93
+ // provera: false
86
94
  };
87
95
 
88
96
  this.removeClick = this.removeClick.bind(this);
@@ -93,10 +101,58 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
93
101
  this.handleTree = this.handleTree.bind(this);
94
102
  this.filteredItem = this.filteredItem.bind(this);
95
103
  this.banchButton = this.banchButton.bind(this);
104
+ this.handleDebounce = this.handleDebounce.bind(this);
105
+ this.toggleMenu = this.toggleMenu.bind(this);
96
106
  this.dropdownRef = React.createRef();
97
107
  this.openDropdownRef = React.createRef();
98
108
  }
99
109
 
110
+ componentDidMount = () => {
111
+ this.recursion(this.state.options);
112
+ document.addEventListener("mousedown", (event: any) => {
113
+ if ((this.dropdownRef.current && !this.dropdownRef.current.contains(event.target))
114
+ && (this.openDropdownRef.current && !this.openDropdownRef.current.contains(event.target))) {
115
+ this.setState({openDropdown: false});
116
+ }
117
+ });
118
+ }
119
+
120
+ componentDidUpdate(prevProps: Readonly<IProps<T>>, prevState: Readonly<IState<T>>): void {
121
+ if (!isEqual(prevState.value, this.state.value)) {
122
+ this.props.onChange(this.state.value);
123
+ } else if (!isEqual(prevProps.value, this.props.value)) {
124
+ this.props.onChange(this.state.value);
125
+ }
126
+ if (prevState.openDropdown !== this.state.openDropdown) {
127
+ this.toggleMenu();
128
+ }
129
+ if (this.props.kind === 'synchronous') {
130
+ if ((prevState.activeTree !== this.state.activeTree)
131
+ || (prevState.filterArr !== this.state.filterArr)
132
+ || (prevState.options !== this.state.options)) {
133
+ this.popperInstance.update();
134
+ }
135
+ }
136
+ }
137
+
138
+ toggleMenu() {
139
+ if (this.state.openDropdown) {
140
+ if (this.openDropdownRef.current && this.dropdownRef.current) {
141
+ this.popperInstance = createPopper(this.openDropdownRef.current, this.dropdownRef.current, {
142
+ placement: 'bottom-start',
143
+ modifiers: [
144
+ {
145
+ name: 'offset',
146
+ options: {
147
+ offset: [-4, 4],
148
+ },
149
+ },
150
+ ],
151
+ });
152
+ }
153
+ }
154
+ }
155
+
100
156
  removeClick(i: number) {
101
157
  let newTags = this.state.value;
102
158
  newTags?.splice(i, 1);
@@ -253,27 +309,9 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
253
309
  });
254
310
  }
255
311
 
256
- componentDidMount = () => {
257
- this.recursion(this.state.options);
258
- document.addEventListener("mousedown", (event: any) => {
259
- if ((this.dropdownRef.current && !this.dropdownRef.current.contains(event.target))
260
- && (this.openDropdownRef.current && !this.openDropdownRef.current.contains(event.target))) {
261
- this.setState({openDropdown: false});
262
- }
263
- });
264
- }
265
-
266
- componentDidUpdate(prevProps: Readonly<IProps<T>>, prevState: Readonly<IState<T>>): void {
267
- if (prevState.value !== this.state.value) {
268
- this.props.onChange(this.state.value);
269
- } else if (prevProps.value !== this.props.value) {
270
- this.props.onChange(this.state.value);
271
- }
272
- }
273
-
274
312
  filteredItem(arr: Array<ITreeNode<T>>) {
275
313
  if (this.props.kind === 'synchronous') {
276
- return arr.filter((item) => {
314
+ let filteredArr = arr.filter((item) => {
277
315
  if (this.state.searchFieldValue) {
278
316
  if (this.props.getLabel(item.value)
279
317
  .toLowerCase().includes(this.state.searchFieldValue.toLowerCase())) {
@@ -284,33 +322,46 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
284
322
  } else {
285
323
  return item.value;
286
324
  }
287
- }).map((option, i) => {
288
- let selectedItem = this.state.value.some((obj) =>
289
- this.props.getId(obj) === this.props.getId(option.value),
290
- );
291
- return <li key={i}
292
- className={`suggestion-item suggestion-item--multi-select`}
293
- onClick={(event) => {
294
- this.setState({
295
- searchFieldValue: '',
296
- }),
297
- event.preventDefault();
298
- event.stopPropagation();
299
- this.handleTree(event, option);
300
- }}>
301
- {this.props.optionTemplate
302
- ? this.props.optionTemplate(option.value)
303
- : <span
304
- className={selectedItem
305
- ? 'suggestion-item--disabled' : undefined}
325
+ });
326
+
327
+ if (filteredArr.length === 0) {
328
+ return <li className="suggestion-item--nothing-found">Nothing fonud</li>;
329
+ } else {
330
+ return filteredArr.map((option, i) => {
331
+ let selectedItem = this.state.value.some((obj) =>
332
+ this.props.getId(obj) === this.props.getId(option.value),
333
+ );
334
+ return <li key={i}
335
+ className={`suggestion-item suggestion-item--multi-select`}
336
+ onClick={(event) => {
337
+ this.setState({
338
+ searchFieldValue: '',
339
+ }),
340
+ event.preventDefault();
341
+ event.stopPropagation();
342
+ this.handleTree(event, option);
343
+ }}>
344
+ {this.props.getBorderColor
345
+ && <div className="item-border"
346
+ style={{backgroundColor: this.props.getBorderColor(option.value)}}></div>}
347
+ <span
348
+ style={this.props.getBackgroundColor
349
+ ? {backgroundColor: this.props.getBackgroundColor(option.value),
350
+ color: getTextColor(this.props.getBackgroundColor(option.value))}
351
+ : undefined}
352
+ className={'suggestion-item--bgcolor'
353
+ + (selectedItem ? ' suggestion-item--disabled' : '')}
306
354
  >
307
- {this.props.getLabel(option.value)}
308
- </span>}
355
+ {this.props.optionTemplate
356
+ ? this.props.optionTemplate(option.value)
357
+ : this.props.getLabel(option.value)}
358
+ </span>
309
359
  {option.children && <span className="suggestion-item__icon">
310
360
  <Icon name="chevron-right-thin"></Icon>
311
361
  </span>}
312
- </li>;
313
- });
362
+ </li>;
363
+ });
364
+ }
314
365
  } else if (this.props.kind === 'asynchronous') {
315
366
  return this.state.options.map((item, i) => {
316
367
  let selectedItem = this.state.value.some((obj) =>
@@ -345,147 +396,205 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
345
396
 
346
397
  if (!selectedButton) {
347
398
  return <button
348
- className={'autocomplete__button' + (this.props.selectBranchWithChildren ? ' autocomplete__button--multi-select' : '')}
349
- onMouseOver={() => this.setState({buttonMouseEvent: true})}
350
- onMouseOut={() => this.setState({buttonMouseEvent: false})}
351
- value={this.state.buttonValue}
352
- onClick={(event) => this.handleBranchValue(event, this.state.buttonValue)}>
353
- Choose entire category
354
- </button>;
399
+ className={'autocomplete__button' + (this.props.selectBranchWithChildren ? ' autocomplete__button--multi-select' : '')}
400
+ onMouseOver={() => this.setState({buttonMouseEvent: true})}
401
+ onMouseOut={() => this.setState({buttonMouseEvent: false})}
402
+ value={this.state.buttonValue}
403
+ onClick={(event) => this.handleBranchValue(event, this.state.buttonValue)}>
404
+ Choose entire category
405
+ </button>;
355
406
  } else {
356
407
  return <button
357
- className={'autocomplete__button' + (this.props.selectBranchWithChildren ? ' autocomplete__button--multi-select' : '') + ' autocomplete__button--disabled'}
358
- value={this.state.buttonValue}>
359
- Category selected
360
- </button>;
408
+ className={'autocomplete__button' + (this.props.selectBranchWithChildren ? ' autocomplete__button--multi-select' : '') + ' autocomplete__button--disabled'}
409
+ value={this.state.buttonValue}>
410
+ Category selected
411
+ </button>;
361
412
  }
362
413
  }
363
414
 
364
- render() {
365
-
366
- const labelClasses = classNames('sd-input__label', {
367
- 'a11y-only': this.props.labelHidden,
368
- });
415
+ private debounceFn = _debounce(this.handleDebounce, 500);
416
+ private ICancelFn: any;
369
417
 
370
- const classesLabel = classNames('sd-input', {
371
- 'sd-input--inline-label': this.props.inlineLabel,
372
- 'sd-input--required': this.props.required,
373
- 'sd-input--disabled': this.props.disabled,
374
- 'sd-input--full-width': this.props.fullWidth,
375
- 'sd-input--invalid': this.props.invalid || this.state.invalid,
376
- });
418
+ handleDebounce() {
419
+ this.setState({options: []});
420
+ if (this.props.kind === 'asynchronous') {
421
+ if (this.state.searchFieldValue) {
422
+ this.setState({
423
+ loading: true,
424
+ // provera: false
425
+ });
426
+ this.ICancelFn = this.props.searchOptions(this.state.searchFieldValue, (items) => {
427
+ // if (items.length === 0) {
428
+ // this.setState({provera: true, loading: false})
429
+ // } else {
430
+ this.setState({options: items, loading: false});
431
+ this.popperInstance.update();
432
+ // }
433
+ });
434
+ }
435
+ }
436
+ }
377
437
 
438
+ render() {
378
439
  return (
379
- <div className={classesLabel}>
380
- <label className={labelClasses} htmlFor={this.htmlId} id={this.htmlId + 'label'}
381
- tabIndex={this.props.tabindex === undefined ? undefined : -1}>
382
- {this.props.label}
383
- </label>
384
-
440
+ <InputWrapper
441
+ label={this.props.label}
442
+ error={this.props.error}
443
+ required={this.props.required}
444
+ disabled={this.props.disabled}
445
+ invalid={this.props.invalid}
446
+ info={this.props.info}
447
+ inlineLabel={this.props.inlineLabel}
448
+ labelHidden={this.props.labelHidden}
449
+ fullWidth={this.props.fullWidth}
450
+ htmlId={this.htmlId}
451
+ tabindex={this.props.tabindex}>
385
452
  <div className={`tags-input tags-input--${this.props.allowMultiple ? 'multi-select' : 'single-select'} sd-input__input`}>
386
453
  {this.props.allowMultiple
387
454
  ? <div className="tags-input__tags">
388
- {this.props.readOnly
389
- || <button ref={this.openDropdownRef}
390
- className="tags-input__add-button"
391
- onClick={() => this.setState({openDropdown: !this.state.openDropdown})}>
392
- <i className="icon-plus-large"></i>
393
- </button>}
455
+ {this.props.readOnly
456
+ || <button ref={this.openDropdownRef}
457
+ className="tags-input__add-button"
458
+ onClick={() => this.setState({openDropdown: !this.state.openDropdown})}>
459
+ <i className="icon-plus-large"></i>
460
+ </button>}
394
461
  <ul className="tags-input__tag-list">
395
462
  {this.state.value.map((item, i: number) => {
396
- return <React.Fragment key={i}>
463
+ const Wrapper: React.ComponentType<{backgroundColor?: string}>
464
+ = ({backgroundColor, children}) => (
397
465
  <li
398
466
  className={"tags-input__tag-item tags-input__tag-item--multi-select"
399
467
  + (this.props.readOnly ? ' tags-input__tag-item--readonly' : '')}
400
- onClick={() => this.props.readOnly || this.removeClick(i)}>
401
- <span className="tags-input__helper-box">
402
- {this.props.valueTemplate
403
- ? this.props.valueTemplate(item)
404
- : <span>{this.props.getLabel(item)}</span>}
405
- {this.props.readOnly
406
- || <span className="tags-input__remove-button">
468
+ onClick={() => !this.props.readOnly && this.removeClick(i)}
469
+ style={this.props.valueTemplate
470
+ ? {backgroundColor}
471
+ : this.props.getBackgroundColor
472
+ && {backgroundColor: this.props.getBackgroundColor(item)}}>
473
+ <span
474
+ style={{color: backgroundColor
475
+ ? getTextColor(backgroundColor)
476
+ : this.props.getBackgroundColor
477
+ && getTextColor(this.props.getBackgroundColor(item))}}
478
+ className="tags-input__helper-box">
479
+ {children}
480
+ {!this.props.readOnly && <span className="tags-input__remove-button">
407
481
  <Icon name="close-small"></Icon>
408
482
  </span>}
409
483
  </span>
410
484
  </li>
411
- </React.Fragment>;
485
+ );
486
+
487
+ return (
488
+ <React.Fragment key={i}>
489
+ {this.props.valueTemplate
490
+ ? this.props.valueTemplate(item, Wrapper)
491
+ : <Wrapper>
492
+ <span>{this.props.getLabel(item)}</span>
493
+ </Wrapper>
494
+ }
495
+ </React.Fragment>
496
+ );
412
497
  })}
413
498
  </ul>
414
- {this.state.value.length > 0 ?
415
- this.props.readOnly
499
+ {this.state.value.length > 0
500
+ ? this.props.readOnly
416
501
  || <button className="tags-input__remove-value"
502
+ style={{position: 'relative', bottom: '2px'}}
417
503
  onClick={() => this.setState({value: []})}>
418
504
  <Icon name='remove-sign'></Icon>
419
505
  </button> : null}
420
506
  </div>
421
507
  : <div className="tags-input__tags">
422
- <button
508
+ {this.props.readOnly
509
+ || <button
423
510
  className="tags-input__overlay-button"
424
511
  ref={this.openDropdownRef}
425
512
  onClick={() => this.setState({openDropdown: !this.state.openDropdown})}>
426
- </button>
513
+ </button>}
427
514
  {this.state.value.length < 1 && <span className={ 'tags-input__single-item'
428
515
  + (this.props.readOnly ? ' tags-input__tag-item--readonly' : '')}>
429
516
  <span className="tags-input__placeholder">
430
517
  {this.props.placeholder}
431
518
  </span>
432
519
  </span>}
433
- {this.state.value.map((item, i: number) => {
434
- return <React.Fragment key={i}>
520
+ {this.state.value.map((item, i: number) => {
521
+ const Wrapper: React.ComponentType<{backgroundColor?: string, borderColor?: string}>
522
+ = ({backgroundColor, borderColor, children}) => (
523
+ <span
524
+ className={ 'tags-input__single-item'
525
+ + (this.props.readOnly ? ' tags-input__tag-item--readonly' : '')}
526
+ onClick={() => this.props.readOnly || this.removeClick(i)}>
527
+ {this.props.getBorderColor
528
+ && <div className="item-border item-border-selected"
529
+ style={borderColor
530
+ ? {backgroundColor: borderColor}
531
+ : {backgroundColor: this.props.getBorderColor(item)}}></div>}
435
532
  <span
436
- className={ 'tags-input__single-item'
437
- + (this.props.readOnly ? ' tags-input__tag-item--readonly' : '')}
438
- onClick={() => this.props.readOnly || this.removeClick(i)}>
439
- <span className="tags-input__helper-box">
440
- {this.props.valueTemplate
441
- ? this.props.valueTemplate(item)
442
- : <span>{this.props.getLabel(item)}</span>}
443
- {this.props.readOnly
444
- || <span className="tags-input__remove-button">
445
- <Icon name='remove-sign'></Icon>
446
- </span>}
533
+ style={{color: backgroundColor && getTextColor(backgroundColor)}}
534
+ className="tags-input__helper-box">
535
+ <span
536
+ className={backgroundColor && `tags-input__tag-item`}
537
+ style={{backgroundColor, margin: 0}}>
538
+ {children}
447
539
  </span>
540
+ {this.props.readOnly
541
+ || <span className="tags-input__remove-button">
542
+ <Icon name='remove-sign'></Icon>
543
+ </span>}
448
544
  </span>
449
- </React.Fragment>;
450
- })}
545
+ </span>
546
+ );
547
+
548
+ return <React.Fragment key={i}>
549
+ {this.props.valueTemplate
550
+ ? this.props.valueTemplate(item, Wrapper)
551
+ : <Wrapper>
552
+ <span>{this.props.getLabel(item)}</span>
553
+ </Wrapper>
554
+ }
555
+ </React.Fragment>;
556
+ })}
451
557
  </div>
452
558
  }
453
559
 
454
- {this.state.openDropdown &&
455
- <div className={"autocomplete autocomplete--multi-select" + (this.props.width === 'medium' ? ' autocomplete--fixed-width' : '')} ref={this.dropdownRef}>
560
+ {this.state.openDropdown
561
+ && <div className={"autocomplete autocomplete--multi-select" + (this.props.width === 'medium' ? ' autocomplete--fixed-width' : '')} ref={this.dropdownRef}>
456
562
  <div className='autocomplete__header'>
457
563
  <div className="autocomplete__icon" onClick={() => {
458
564
  this.backButtonValue();
459
565
  this.backButton();
460
566
  }}>
461
- <Icon name="search" className="search"></Icon>
567
+ <Icon name="search" className="search"></Icon>
462
568
  </div>
463
569
  <div className='autocomplete__filter'>
464
570
  <input
465
- placeholder={this.props.singleLevelSearch ? 'Search this category...' : 'Search...'}
571
+ placeholder={this.props.searchPlaceholder}
466
572
  type="text"
467
573
  className="autocomplete__input"
468
574
  ref={(input) => input && input.focus()}
469
575
  value={this.state.searchFieldValue}
470
576
  onChange={(event) => {
471
- const value = event.target.value;
472
- if (this.props.kind === 'asynchronous') {
473
- this.setState({
474
- searchFieldValue: value,
475
- loading: true,
476
- }),
477
- this.props.searchOptions(value, (items) => {
478
- this.setState({options: items, loading: false});
479
- });
480
- } else if (this.props.kind === 'synchronous') {
481
- this.setState({searchFieldValue: value});
577
+ if (this.props.kind === 'synchronous') {
578
+ this.setState({searchFieldValue: event.target.value});
579
+ this.popperInstance.update();
580
+ } else if (this.props.kind === 'asynchronous') {
581
+ if (this.ICancelFn) {
582
+ this.ICancelFn();
583
+ }
584
+ this.setState({searchFieldValue: event.target.value, options: []});
585
+ this.popperInstance.update();
586
+ this.debounceFn();
587
+ } else {
588
+ return;
482
589
  }
483
- }}
484
- />
590
+ // if(!this.state.searchFieldValue) {
591
+ // this.setState({provera: false});
592
+ // }
593
+ }} />
485
594
  </div>
486
595
  </div>
487
- {this.state.activeTree.length > 0 &&
488
- <div className='autocomplete__category-header'>
596
+ {this.state.activeTree.length > 0
597
+ && <div className='autocomplete__category-header'>
489
598
  <div className="autocomplete__icon" onClick={() => {
490
599
  this.backButtonValue();
491
600
  this.backButton();
@@ -505,54 +614,51 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
505
614
  </div>}
506
615
  {this.state.loading
507
616
  ? <ul className="suggestion-list--loader"><Loader overlay={true}></Loader></ul>
508
- :
509
- this.state.searchFieldValue === ''
510
- ? this.props.getOptions ?
511
- <ul className="suggestion-list suggestion-list--multi-select">
512
- {this.state.options
513
- .map((option, i: React.Key | undefined) => {
514
- let selectedItem = this.state.value.some((obj) =>
515
- this.props.getId(obj) === this.props.getLabel(option.value),
516
- );
517
- return (
518
- <li key={i}
519
- className={`suggestion-item suggestion-item--multi-select`}
520
- onClick={(event) => {
521
- event.preventDefault();
522
- event.stopPropagation();
523
- this.handleTree(event, option);
524
- }}>
525
- {this.props.optionTemplate
526
- ? this.props.optionTemplate(option.value)
527
- : <span
528
- className={selectedItem
529
- ? 'suggestion-item--disabled' : undefined}
530
- >
531
- {this.props.getLabel(option.value)}
532
- </span>}
533
- {option.children && <span className="suggestion-item__icon">
534
- <Icon name="chevron-right-thin"></Icon>
535
- </span>}
536
- </li>
537
- );
538
- })}</ul> : null
539
- :
540
- <ul className="suggestion-list suggestion-list--multi-select">
617
+ : this.state.searchFieldValue === ''
618
+ ? this.props.getOptions
619
+ ? <ul className="suggestion-list suggestion-list--multi-select">
620
+ {this.state.options
621
+ .map((option, i: React.Key | undefined) => {
622
+ let selectedItem = this.state.value.some((obj) =>
623
+ this.props.getId(obj) === this.props.getLabel(option.value),
624
+ );
625
+ return (
626
+ <li key={i}
627
+ className={`suggestion-item suggestion-item--multi-select`}
628
+ onClick={(event) => {
629
+ event.preventDefault();
630
+ event.stopPropagation();
631
+ this.handleTree(event, option);
632
+ }}>
633
+ {(this.props.getBorderColor && !this.props.allowMultiple) && <div className="item-border" style={{backgroundColor: this.props.getBorderColor(option.value)}}></div>}
634
+ <span
635
+ style={(this.props.getBackgroundColor && option.value)
636
+ ? {backgroundColor: this.props.getBackgroundColor(option.value),
637
+ color: getTextColor(this.props.getBackgroundColor(option.value))}
638
+ : undefined}
639
+ className={'suggestion-item--bgcolor'
640
+ + (selectedItem ? ' suggestion-item--disabled' : '')}
641
+ >
642
+ {this.props.optionTemplate
643
+ ? this.props.optionTemplate(option.value)
644
+ : this.props.getLabel(option.value)}
645
+ </span>
646
+ {option.children && <span className="suggestion-item__icon">
647
+ <Icon name="chevron-right-thin"></Icon>
648
+ </span>}
649
+ </li>
650
+ );
651
+ })}</ul> : null
652
+ : <ul className="suggestion-list suggestion-list--multi-select">
541
653
  {this.filteredItem(this.props.singleLevelSearch
542
654
  ? this.state.options : this.state.filterArr)}
655
+ {/* {this.state.provera
656
+ && <li className="suggestion-item--nothing-found">Nothing fonud</li>} */}
543
657
  </ul>
544
- }
658
+ }
545
659
  </div>}
546
660
  </div>
547
-
548
- <div className='sd-input__message-box'>
549
- {this.props.info && !this.props.invalid && !this.state.invalid ?
550
- <div className='sd-input__hint'>{this.props.info}</div> : null}
551
- {this.props.invalid || this.state.invalid ?
552
- <div className='sd-input__message'>{this.props.error}</div>
553
- : null}
554
- </div>
555
- </div>
661
+ </InputWrapper>
556
662
  );
557
663
  }
558
664
  }
@@ -90,6 +90,7 @@ export { BottomNav } from './components/Navigation/BottomNav';
90
90
  export { TreeSelect } from './components/TreeSelect';
91
91
  export { TableList, TableListItem } from './components/Lists/TableList';
92
92
  export { ContentListItem } from './components/Lists/ContentList';
93
+ export { MultiSelect } from './components/MultiSelect';
93
94
 
94
95
  // declare non-typescript exports to prevent errors
95
96
  export declare const ToggleBoxNext: any;