superdesk-ui-framework 3.1.4 → 3.1.6

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 (273) hide show
  1. package/app/styles/_helpers.scss +317 -151
  2. package/app/styles/_sd-tag-input.scss +1 -1
  3. package/app/styles/design-tokens/_design-tokens-general.scss +18 -7
  4. package/app/styles/design-tokens/_new-colors.scss +6 -1
  5. package/app/styles/grids/_grid-layout.scss +1 -0
  6. package/app/styles/interface-elements/_side-panel.scss +4 -0
  7. package/app-typescript/components/IconPicker.tsx +1 -1
  8. package/app-typescript/components/TreeSelect/TreeSelect.tsx +118 -38
  9. package/app-typescript/components/TreeSelect/TreeSelectPill.tsx +20 -9
  10. package/{examples/pages/react → dist/components}/Index.tsx +81 -63
  11. package/dist/{react → components}/TreeSelect.tsx +61 -3
  12. package/dist/components/utilities/SpacingUtilities.tsx +774 -0
  13. package/dist/components/utilities/TextUtilities.tsx +428 -0
  14. package/dist/components.html +6 -27
  15. package/dist/{components → components_deprecated}/text.html +7 -7
  16. package/dist/components_deprecated.html +38 -0
  17. package/dist/design/buttons.html +1 -11
  18. package/dist/design/checkbox-and-radio.html +3 -3
  19. package/dist/design/layout-principles.html +0 -1
  20. package/dist/design/switch.html +0 -10
  21. package/dist/design-patterns/Index.tsx +86 -0
  22. package/dist/design-patterns/ThreePaneLayoutPattern.tsx +362 -0
  23. package/{examples/pages/react.html → dist/design-patterns.html} +3 -4
  24. package/dist/design.html +4 -4
  25. package/dist/examples.bundle.css +106 -20
  26. package/dist/examples.bundle.js +81289 -79455
  27. package/dist/main.html +17 -15
  28. package/dist/playgrounds/boxed-list.html +7 -7
  29. package/dist/playgrounds/master-desk.html +4 -4
  30. package/dist/playgrounds/photo-snippets/edit-photo-metadata.html +1 -1
  31. package/dist/playgrounds/planning-snippets/edit-planning.html +1 -1
  32. package/dist/playgrounds/planning.html +1 -1
  33. package/dist/playgrounds/publisher-content-analytics.html +25 -25
  34. package/dist/playgrounds/react-playgrounds/TestGround.tsx +3 -3
  35. package/dist/playgrounds/video-editor.html +1 -1
  36. package/dist/playgrounds.html +3 -6
  37. package/dist/superdesk-ui.bundle.css +315 -120
  38. package/dist/superdesk-ui.bundle.js +78250 -78174
  39. package/examples/css/docs-page.css +106 -20
  40. package/examples/index.js +89 -89
  41. package/examples/js/doc.js +16 -2
  42. package/examples/js/react.js +122 -19
  43. package/{dist/react → examples/pages/components}/Index.tsx +81 -63
  44. package/examples/pages/{react → components}/TreeSelect.tsx +61 -3
  45. package/examples/pages/components/utilities/SpacingUtilities.tsx +774 -0
  46. package/examples/pages/components/utilities/TextUtilities.tsx +428 -0
  47. package/examples/pages/components.html +6 -27
  48. package/examples/pages/{components → components_deprecated}/text.html +7 -7
  49. package/examples/pages/components_deprecated.html +38 -0
  50. package/examples/pages/design/buttons.html +1 -11
  51. package/examples/pages/design/checkbox-and-radio.html +3 -3
  52. package/examples/pages/design/layout-principles.html +0 -1
  53. package/examples/pages/design/switch.html +0 -10
  54. package/examples/pages/design-patterns/Index.tsx +86 -0
  55. package/examples/pages/design-patterns/ThreePaneLayoutPattern.tsx +362 -0
  56. package/{dist/react.html → examples/pages/design-patterns.html} +3 -4
  57. package/examples/pages/design.html +4 -4
  58. package/examples/pages/main.html +17 -15
  59. package/examples/pages/playgrounds/boxed-list.html +7 -7
  60. package/examples/pages/playgrounds/master-desk.html +4 -4
  61. package/examples/pages/playgrounds/photo-snippets/edit-photo-metadata.html +1 -1
  62. package/examples/pages/playgrounds/planning-snippets/edit-planning.html +1 -1
  63. package/examples/pages/playgrounds/planning.html +1 -1
  64. package/examples/pages/playgrounds/publisher-content-analytics.html +25 -25
  65. package/examples/pages/playgrounds/react-playgrounds/TestGround.tsx +3 -3
  66. package/examples/pages/playgrounds/video-editor.html +1 -1
  67. package/examples/pages/playgrounds.html +3 -6
  68. package/package.json +1 -1
  69. package/react/components/IconPicker.js +1 -1
  70. package/react/components/TreeSelect/TreeSelect.d.ts +5 -0
  71. package/react/components/TreeSelect/TreeSelect.js +80 -17
  72. package/react/components/TreeSelect/TreeSelectPill.d.ts +1 -0
  73. package/react/components/TreeSelect/TreeSelectPill.js +13 -4
  74. /package/dist/{react → components}/Alerts.tsx +0 -0
  75. /package/dist/{react → components}/Autocomplete.tsx +0 -0
  76. /package/dist/{react → components}/Avatar.tsx +0 -0
  77. /package/dist/{react → components}/Badges.tsx +0 -0
  78. /package/dist/{react → components}/BigIconFont.tsx +0 -0
  79. /package/dist/{react → components}/BoxedList.tsx +0 -0
  80. /package/dist/{react → components}/ButtonGroups.tsx +0 -0
  81. /package/dist/{react → components}/Buttons.tsx +0 -0
  82. /package/dist/{react → components}/Carousel.tsx +0 -0
  83. /package/dist/{react → components}/Checkboxs.tsx +0 -0
  84. /package/dist/{react → components}/Container.tsx +0 -0
  85. /package/dist/{react → components}/ContentDivider.tsx +0 -0
  86. /package/dist/{react → components}/ContentList.tsx +0 -0
  87. /package/dist/{react → components}/CreateButton.tsx +0 -0
  88. /package/dist/{react → components}/DatePicker.tsx +0 -0
  89. /package/dist/{react → components}/DragHandleDocs.tsx +0 -0
  90. /package/dist/{react → components}/DropZone.tsx +0 -0
  91. /package/dist/{react → components}/Dropdowns.tsx +0 -0
  92. /package/dist/{react → components}/DurationInput.tsx +0 -0
  93. /package/dist/{react → components}/EmptyStates.tsx +0 -0
  94. /package/dist/{react → components}/GridItem.tsx +0 -0
  95. /package/dist/{react → components}/GridList.tsx +0 -0
  96. /package/dist/{react → components}/Heading.tsx +0 -0
  97. /package/dist/{react → components}/IconButtons.tsx +0 -0
  98. /package/dist/{react → components}/IconFont.tsx +0 -0
  99. /package/dist/{react → components}/IconLabels.tsx +0 -0
  100. /package/dist/{react → components}/IconPicker.tsx +0 -0
  101. /package/dist/{react → components}/IllustrationButton.tsx +0 -0
  102. /package/dist/{react → components}/Inputs.tsx +0 -0
  103. /package/dist/{react → components}/Labels.tsx +0 -0
  104. /package/dist/{react → components}/LeftNavigations.tsx +0 -0
  105. /package/dist/{react → components}/ListItems.tsx +0 -0
  106. /package/dist/{react → components}/Menu.tsx +0 -0
  107. /package/dist/{react → components}/Modal.tsx +0 -0
  108. /package/dist/{react → components}/MultiSelect.tsx +0 -0
  109. /package/dist/{react → components}/NavButtons.tsx +0 -0
  110. /package/dist/{react → components}/Panel.tsx +0 -0
  111. /package/dist/{react → components}/Popover.tsx +0 -0
  112. /package/dist/{react → components}/QuickNavigationBar.tsx +0 -0
  113. /package/dist/{react → components}/RadioGroup.tsx +0 -0
  114. /package/dist/{react → components}/ResizablePanels.tsx +0 -0
  115. /package/dist/{react → components}/SelectGrid.tsx +0 -0
  116. /package/dist/{react → components}/SelectWithTemplate.tsx +0 -0
  117. /package/dist/{react → components}/Selects.tsx +0 -0
  118. /package/dist/{react → components}/SimpleList.tsx +0 -0
  119. /package/dist/{react → components}/SubNav.tsx +0 -0
  120. /package/dist/{react → components}/Switch.tsx +0 -0
  121. /package/dist/{react → components}/TableList.tsx +0 -0
  122. /package/dist/{react → components}/Tabs.tsx +0 -0
  123. /package/dist/{react → components}/TagInputDocs.tsx +0 -0
  124. /package/dist/{react → components}/Tags.tsx +0 -0
  125. /package/dist/{react → components}/Text.tsx +0 -0
  126. /package/dist/{react → components}/TimePicker.tsx +0 -0
  127. /package/dist/{react → components}/Toasts.tsx +0 -0
  128. /package/dist/{react → components}/Togglebox.tsx +0 -0
  129. /package/dist/{react → components}/Tooltips.tsx +0 -0
  130. /package/dist/{react → components}/TreeMenu.tsx +0 -0
  131. /package/dist/{react → components}/WithPaginationDocs.tsx +0 -0
  132. /package/dist/{react → components}/WithSizeObserver.tsx +0 -0
  133. /package/dist/{react → components}/tree-select/TreeSelect.tsx +0 -0
  134. /package/dist/{react → components}/tree-select/example-1.tsx +0 -0
  135. /package/dist/{react → components}/tree-select/example-2.tsx +0 -0
  136. /package/dist/{components → components_deprecated}/alerts.html +0 -0
  137. /package/dist/{components → components_deprecated}/badge.html +0 -0
  138. /package/dist/{components → components_deprecated}/basic-grid.html +0 -0
  139. /package/dist/{components → components_deprecated}/big-icons.html +0 -0
  140. /package/dist/{components → components_deprecated}/buttons.html +0 -0
  141. /package/dist/{components → components_deprecated}/carousel.html +0 -0
  142. /package/dist/{components → components_deprecated}/checkbox.html +0 -0
  143. /package/dist/{components → components_deprecated}/colors.html +0 -0
  144. /package/dist/{components → components_deprecated}/dropdown.html +0 -0
  145. /package/dist/{components → components_deprecated}/form-layout.html +0 -0
  146. /package/dist/{components → components_deprecated}/icon-labels.html +0 -0
  147. /package/dist/{components → components_deprecated}/icons.html +0 -0
  148. /package/dist/{components → components_deprecated}/input.html +0 -0
  149. /package/dist/{components → components_deprecated}/labels.html +0 -0
  150. /package/dist/{components → components_deprecated}/layout-grid.html +0 -0
  151. /package/dist/{components → components_deprecated}/left-nav.html +0 -0
  152. /package/dist/{components → components_deprecated}/list-item.html +0 -0
  153. /package/dist/{components → components_deprecated}/loader.html +0 -0
  154. /package/dist/{components → components_deprecated}/modal-template.html +0 -0
  155. /package/dist/{components → components_deprecated}/modals.html +0 -0
  156. /package/dist/{components → components_deprecated}/other-elements.html +0 -0
  157. /package/dist/{components → components_deprecated}/panel-info.html +0 -0
  158. /package/dist/{components → components_deprecated}/radio.html +0 -0
  159. /package/dist/{components → components_deprecated}/select.html +0 -0
  160. /package/dist/{components → components_deprecated}/shadows.html +0 -0
  161. /package/dist/{components → components_deprecated}/sidebar-menu.html +0 -0
  162. /package/dist/{components → components_deprecated}/simple-list.html +0 -0
  163. /package/dist/{components → components_deprecated}/slider.html +0 -0
  164. /package/dist/{components → components_deprecated}/spacing.html +0 -0
  165. /package/dist/{components → components_deprecated}/switch.html +0 -0
  166. /package/dist/{components → components_deprecated}/tables.html +0 -0
  167. /package/dist/{components → components_deprecated}/tabs.html +0 -0
  168. /package/dist/{components → components_deprecated}/tag-input.html +0 -0
  169. /package/dist/{components → components_deprecated}/tag-labels.html +0 -0
  170. /package/dist/{components → components_deprecated}/toggle.html +0 -0
  171. /package/dist/{components → components_deprecated}/tooltips.html +0 -0
  172. /package/dist/{components → components_deprecated}/vertical-tabs.html +0 -0
  173. /package/dist/{components → components_deprecated}/wizard.html +0 -0
  174. /package/examples/pages/{react → components}/Alerts.tsx +0 -0
  175. /package/examples/pages/{react → components}/Autocomplete.tsx +0 -0
  176. /package/examples/pages/{react → components}/Avatar.tsx +0 -0
  177. /package/examples/pages/{react → components}/Badges.tsx +0 -0
  178. /package/examples/pages/{react → components}/BigIconFont.tsx +0 -0
  179. /package/examples/pages/{react → components}/BoxedList.tsx +0 -0
  180. /package/examples/pages/{react → components}/ButtonGroups.tsx +0 -0
  181. /package/examples/pages/{react → components}/Buttons.tsx +0 -0
  182. /package/examples/pages/{react → components}/Carousel.tsx +0 -0
  183. /package/examples/pages/{react → components}/Checkboxs.tsx +0 -0
  184. /package/examples/pages/{react → components}/Container.tsx +0 -0
  185. /package/examples/pages/{react → components}/ContentDivider.tsx +0 -0
  186. /package/examples/pages/{react → components}/ContentList.tsx +0 -0
  187. /package/examples/pages/{react → components}/CreateButton.tsx +0 -0
  188. /package/examples/pages/{react → components}/DatePicker.tsx +0 -0
  189. /package/examples/pages/{react → components}/DragHandleDocs.tsx +0 -0
  190. /package/examples/pages/{react → components}/DropZone.tsx +0 -0
  191. /package/examples/pages/{react → components}/Dropdowns.tsx +0 -0
  192. /package/examples/pages/{react → components}/DurationInput.tsx +0 -0
  193. /package/examples/pages/{react → components}/EmptyStates.tsx +0 -0
  194. /package/examples/pages/{react → components}/GridItem.tsx +0 -0
  195. /package/examples/pages/{react → components}/GridList.tsx +0 -0
  196. /package/examples/pages/{react → components}/Heading.tsx +0 -0
  197. /package/examples/pages/{react → components}/IconButtons.tsx +0 -0
  198. /package/examples/pages/{react → components}/IconFont.tsx +0 -0
  199. /package/examples/pages/{react → components}/IconLabels.tsx +0 -0
  200. /package/examples/pages/{react → components}/IconPicker.tsx +0 -0
  201. /package/examples/pages/{react → components}/IllustrationButton.tsx +0 -0
  202. /package/examples/pages/{react → components}/Inputs.tsx +0 -0
  203. /package/examples/pages/{react → components}/Labels.tsx +0 -0
  204. /package/examples/pages/{react → components}/LeftNavigations.tsx +0 -0
  205. /package/examples/pages/{react → components}/ListItems.tsx +0 -0
  206. /package/examples/pages/{react → components}/Menu.tsx +0 -0
  207. /package/examples/pages/{react → components}/Modal.tsx +0 -0
  208. /package/examples/pages/{react → components}/MultiSelect.tsx +0 -0
  209. /package/examples/pages/{react → components}/NavButtons.tsx +0 -0
  210. /package/examples/pages/{react → components}/Panel.tsx +0 -0
  211. /package/examples/pages/{react → components}/Popover.tsx +0 -0
  212. /package/examples/pages/{react → components}/QuickNavigationBar.tsx +0 -0
  213. /package/examples/pages/{react → components}/RadioGroup.tsx +0 -0
  214. /package/examples/pages/{react → components}/ResizablePanels.tsx +0 -0
  215. /package/examples/pages/{react → components}/SelectGrid.tsx +0 -0
  216. /package/examples/pages/{react → components}/SelectWithTemplate.tsx +0 -0
  217. /package/examples/pages/{react → components}/Selects.tsx +0 -0
  218. /package/examples/pages/{react → components}/SimpleList.tsx +0 -0
  219. /package/examples/pages/{react → components}/SubNav.tsx +0 -0
  220. /package/examples/pages/{react → components}/Switch.tsx +0 -0
  221. /package/examples/pages/{react → components}/TableList.tsx +0 -0
  222. /package/examples/pages/{react → components}/Tabs.tsx +0 -0
  223. /package/examples/pages/{react → components}/TagInputDocs.tsx +0 -0
  224. /package/examples/pages/{react → components}/Tags.tsx +0 -0
  225. /package/examples/pages/{react → components}/Text.tsx +0 -0
  226. /package/examples/pages/{react → components}/TimePicker.tsx +0 -0
  227. /package/examples/pages/{react → components}/Toasts.tsx +0 -0
  228. /package/examples/pages/{react → components}/Togglebox.tsx +0 -0
  229. /package/examples/pages/{react → components}/Tooltips.tsx +0 -0
  230. /package/examples/pages/{react → components}/TreeMenu.tsx +0 -0
  231. /package/examples/pages/{react → components}/WithPaginationDocs.tsx +0 -0
  232. /package/examples/pages/{react → components}/WithSizeObserver.tsx +0 -0
  233. /package/examples/pages/{react → components}/tree-select/TreeSelect.tsx +0 -0
  234. /package/examples/pages/{react → components}/tree-select/example-1.tsx +0 -0
  235. /package/examples/pages/{react → components}/tree-select/example-2.tsx +0 -0
  236. /package/examples/pages/{components → components_deprecated}/alerts.html +0 -0
  237. /package/examples/pages/{components → components_deprecated}/badge.html +0 -0
  238. /package/examples/pages/{components → components_deprecated}/basic-grid.html +0 -0
  239. /package/examples/pages/{components → components_deprecated}/big-icons.html +0 -0
  240. /package/examples/pages/{components → components_deprecated}/buttons.html +0 -0
  241. /package/examples/pages/{components → components_deprecated}/carousel.html +0 -0
  242. /package/examples/pages/{components → components_deprecated}/checkbox.html +0 -0
  243. /package/examples/pages/{components → components_deprecated}/colors.html +0 -0
  244. /package/examples/pages/{components → components_deprecated}/dropdown.html +0 -0
  245. /package/examples/pages/{components → components_deprecated}/form-layout.html +0 -0
  246. /package/examples/pages/{components → components_deprecated}/icon-labels.html +0 -0
  247. /package/examples/pages/{components → components_deprecated}/icons.html +0 -0
  248. /package/examples/pages/{components → components_deprecated}/input.html +0 -0
  249. /package/examples/pages/{components → components_deprecated}/labels.html +0 -0
  250. /package/examples/pages/{components → components_deprecated}/layout-grid.html +0 -0
  251. /package/examples/pages/{components → components_deprecated}/left-nav.html +0 -0
  252. /package/examples/pages/{components → components_deprecated}/list-item.html +0 -0
  253. /package/examples/pages/{components → components_deprecated}/loader.html +0 -0
  254. /package/examples/pages/{components → components_deprecated}/modal-template.html +0 -0
  255. /package/examples/pages/{components → components_deprecated}/modals.html +0 -0
  256. /package/examples/pages/{components → components_deprecated}/other-elements.html +0 -0
  257. /package/examples/pages/{components → components_deprecated}/panel-info.html +0 -0
  258. /package/examples/pages/{components → components_deprecated}/radio.html +0 -0
  259. /package/examples/pages/{components → components_deprecated}/select.html +0 -0
  260. /package/examples/pages/{components → components_deprecated}/shadows.html +0 -0
  261. /package/examples/pages/{components → components_deprecated}/sidebar-menu.html +0 -0
  262. /package/examples/pages/{components → components_deprecated}/simple-list.html +0 -0
  263. /package/examples/pages/{components → components_deprecated}/slider.html +0 -0
  264. /package/examples/pages/{components → components_deprecated}/spacing.html +0 -0
  265. /package/examples/pages/{components → components_deprecated}/switch.html +0 -0
  266. /package/examples/pages/{components → components_deprecated}/tables.html +0 -0
  267. /package/examples/pages/{components → components_deprecated}/tabs.html +0 -0
  268. /package/examples/pages/{components → components_deprecated}/tag-input.html +0 -0
  269. /package/examples/pages/{components → components_deprecated}/tag-labels.html +0 -0
  270. /package/examples/pages/{components → components_deprecated}/toggle.html +0 -0
  271. /package/examples/pages/{components → components_deprecated}/tooltips.html +0 -0
  272. /package/examples/pages/{components → components_deprecated}/vertical-tabs.html +0 -0
  273. /package/examples/pages/{components → components_deprecated}/wizard.html +0 -0
@@ -13,6 +13,15 @@ import {TreeSelectPill} from './TreeSelectPill';
13
13
  import {getPrefixedItemId, TreeSelectItem} from './TreeSelectItem';
14
14
  import {keyboardNavigation} from './KeyboardNavigation';
15
15
  import {WithPortal} from '../WithPortal';
16
+ import { DragDropContext, Droppable, Draggable, DropResult } from "react-beautiful-dnd";
17
+
18
+ const reorder = (list: Array<any>, startIndex: number, endIndex: number) => {
19
+ const result = Array.from(list);
20
+ const [removed] = result.splice(startIndex, 1);
21
+ result.splice(endIndex, 0, removed);
22
+
23
+ return result;
24
+ };
16
25
 
17
26
  interface IState<T> {
18
27
  value: Array<T>;
@@ -42,7 +51,10 @@ interface IPropsBase<T> extends IInputWrapper {
42
51
  singleLevelSearch?: boolean;
43
52
  placeholder?: string;
44
53
  searchPlaceholder?: string;
54
+ noResultsFoundMessage?: string;
55
+ dropdownInitiallyOpen?: boolean;
45
56
  zIndex?: number;
57
+ sortable?: boolean;
46
58
  'data-test-id'?: string;
47
59
  getLabel(item: T): string;
48
60
  getId(item: T): string;
@@ -112,7 +124,6 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
112
124
  this.onMouseDown = this.onMouseDown.bind(this);
113
125
  this.onKeyDown = this.onKeyDown.bind(this);
114
126
  this.onPressEsc = this.onPressEsc.bind(this);
115
-
116
127
  this.dropdownRef = React.createRef();
117
128
  this.ref = React.createRef();
118
129
  this.inputRef = React.createRef();
@@ -120,6 +131,7 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
120
131
  this.openDropdownRef = React.createRef();
121
132
  this.treeSelectRef = React.createRef();
122
133
  this.popperInstance = null;
134
+ this.onDragEnd = this.onDragEnd.bind(this);
123
135
  }
124
136
 
125
137
  inputFocus = () => {
@@ -185,6 +197,10 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
185
197
  document.addEventListener("mousedown", this.onMouseDown);
186
198
  document.addEventListener("keydown", this.onKeyDown);
187
199
  document.addEventListener("keydown", this.onPressEsc);
200
+
201
+ if (this.props.dropdownInitiallyOpen) {
202
+ this.setState({openDropdown: true});
203
+ }
188
204
  }
189
205
 
190
206
  componentWillUnmount(): void {
@@ -501,34 +517,39 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
501
517
  });
502
518
  }
503
519
  } else if (this.props.kind === 'asynchronous') {
504
- return this.state.options.map((item, i) => {
505
- let selectedItem = this.state.value.some((obj) =>
506
- this.props.getId(obj) === this.props.getId(item.value),
507
- );
520
+ if (this.state.options.length > 0) {
521
+ return this.state.options.map((item, i) => {
522
+ let selectedItem = this.state.value.some((obj) =>
523
+ this.props.getId(obj) === this.props.getId(item.value),
524
+ );
508
525
 
509
- return (
510
- <li
511
- key={i}
512
- className='suggestion-item suggestion-item--multi-select'
513
- onClick={(event) => {
514
- this.handleValue(event, item);
515
- }}
516
- >
517
- <button className="suggestion-item--btn" data-test-id="option">
518
- {this.props.optionTemplate
519
- ? this.props.optionTemplate(item.value)
520
- : (
521
- <span
522
- className={selectedItem ? 'suggestion-item--selected' : undefined}
523
- >
524
- {this.props.getLabel(item.value)}
525
- </span>
526
- )
527
- }
528
- </button>
529
- </li>
530
- );
531
- });
526
+ return (
527
+ <li
528
+ key={i}
529
+ className='suggestion-item suggestion-item--multi-select'
530
+ onClick={(event) => {
531
+ this.handleValue(event, item);
532
+ }}
533
+ >
534
+ <button className="suggestion-item--btn" data-test-id="option">
535
+ {this.props.optionTemplate
536
+ ? this.props.optionTemplate(item.value)
537
+ : (
538
+ <span
539
+ className={selectedItem ? 'suggestion-item--selected' : undefined}
540
+ >
541
+ {this.props.getLabel(item.value)}
542
+ </span>
543
+ )
544
+ }
545
+ </button>
546
+ </li>
547
+ );
548
+ });
549
+
550
+ } else {
551
+ return <li className="suggestion-item--nothing-found">{this.props.noResultsFoundMessage ?? 'Nothing found'}</li>;
552
+ }
532
553
  } else {
533
554
  return;
534
555
  }
@@ -591,18 +612,31 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
591
612
 
592
613
  if (this.props.kind === 'asynchronous') {
593
614
  if (this.state.searchFieldValue) {
594
- this.setState({
595
- loading: true,
596
- });
597
-
598
615
  this.ICancelFn = this.props.searchOptions(this.state.searchFieldValue, (items) => {
599
616
  this.setState({options: items, loading: false});
600
617
  this.popperInstance?.update();
601
618
  });
619
+ } else {
620
+ this.setState({options: this.state.firstBranchOptions, loading: false});
602
621
  }
603
622
  }
604
623
  }
605
624
 
625
+ onDragEnd(result: DropResult) {
626
+ if (!result.destination) {
627
+ return;
628
+ }
629
+
630
+ const value = reorder(
631
+ this.state.value,
632
+ result.source.index,
633
+ result.destination.index,
634
+ );
635
+ this.setState({
636
+ value: value,
637
+ });
638
+ }
639
+
606
640
  render() {
607
641
  if (this.props.preview) {
608
642
  return (
@@ -624,6 +658,43 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
624
658
  );
625
659
  }
626
660
 
661
+ const ListWrapper = this.props.sortable
662
+ ? ({children}: {children: React.ReactNode}) => (
663
+ <DragDropContext onDragEnd={this.onDragEnd}>
664
+ <Droppable droppableId="droppable" direction="horizontal">
665
+ {(provided, _snapshot) => (
666
+ <ul
667
+ className="tags-input__tag-list"
668
+ ref={provided.innerRef}
669
+ {...provided.droppableProps}
670
+ >
671
+ {children}
672
+ {provided.placeholder}
673
+ </ul>
674
+ )}
675
+ </Droppable>
676
+ </DragDropContext>
677
+ )
678
+ : ({children}: {children: React.ReactNode}) => <ul className="tags-input__tag-list">{children}</ul>;
679
+
680
+ const ItemWrapper = this.props.sortable
681
+ ? ({children, itemId, i}: {children: React.ReactNode, itemId: string, i: number}) => {
682
+ return (
683
+ <Draggable draggableId={itemId} index={i}>
684
+ {(provided2) => (
685
+ <div
686
+ ref={provided2.innerRef}
687
+ {...provided2.draggableProps}
688
+ {...provided2.dragHandleProps}
689
+ >
690
+ {children}
691
+ </div>
692
+ )}
693
+ </Draggable>
694
+ );
695
+ }
696
+ : ({children}: {children: React.ReactNode}) => <React.Fragment>{children}</React.Fragment>;
697
+
627
698
  return (
628
699
  <InputWrapper
629
700
  label={this.props.label}
@@ -672,7 +743,7 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
672
743
  </button>
673
744
  }
674
745
 
675
- <ul className="tags-input__tag-list">
746
+ <ListWrapper>
676
747
  {this.state.value.map((item, i: number) => {
677
748
  const Wrapper: React.ComponentType<{backgroundColor?: string}>
678
749
  = ({backgroundColor, children}) => (
@@ -684,25 +755,30 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
684
755
  backgroundColor={backgroundColor}
685
756
  onRemove={() => this.removeClick(i)}
686
757
  getBackgroundColor={this.props.getBackgroundColor}
758
+ draggable={this.props.sortable}
687
759
  >
688
760
  {children}
689
761
  </TreeSelectPill>
690
762
  );
691
763
 
764
+ const itemId = this.props.getId(item);
765
+
692
766
  return (
693
- <React.Fragment key={i}>
767
+ <ItemWrapper itemId={itemId} key={itemId} i={i}>
694
768
  {this.props.valueTemplate
695
769
  ? this.props.valueTemplate(item, Wrapper)
696
770
  : (
697
771
  <Wrapper>
698
- <span>{this.props.getLabel(item)}</span>
772
+ <span>
773
+ {this.props.getLabel(item)}
774
+ </span>
699
775
  </Wrapper>
700
776
  )
701
777
  }
702
- </React.Fragment>
778
+ </ItemWrapper>
703
779
  );
704
780
  })}
705
- </ul>
781
+ </ListWrapper>
706
782
 
707
783
  {this.state.value.length > 0
708
784
  ? (this.props.readOnly || this.props.disabled)
@@ -842,7 +918,11 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
842
918
  this.ICancelFn();
843
919
  }
844
920
 
845
- this.setState({searchFieldValue: event.target.value, options: []});
921
+ this.setState({
922
+ searchFieldValue: event.target.value,
923
+ options: [],
924
+ loading: true,
925
+ });
846
926
  this.popperInstance?.update();
847
927
  this.debounceFn();
848
928
  } else {
@@ -1,4 +1,6 @@
1
+ import classNames from 'classnames';
1
2
  import * as React from "react";
3
+ import {DragHandle} from '../DragHandle';
2
4
  import {Icon} from "../Icon";
3
5
  import {getTextColor} from '../Label';
4
6
 
@@ -10,19 +12,19 @@ interface IProps<T> {
10
12
  onRemove(): void;
11
13
  valueTemplate?(item: T, Wrapper: React.ElementType): React.ComponentType<T> | JSX.Element;
12
14
  getBackgroundColor?(item: T): string;
15
+ draggable?: boolean;
13
16
  }
14
17
 
15
18
  export class TreeSelectPill<T> extends React.Component<IProps<T>> {
16
19
  render() {
20
+ const classes = classNames('tags-input__tag-item tags-input__tag-item--multi-select', {
21
+ 'tags-input__tag-item--readonly': this.props.readOnly,
22
+ 'tags-input__tag-item--draggable': this.props.draggable,
23
+ });
24
+
17
25
  return (
18
26
  <li
19
- className={
20
- "tags-input__tag-item tags-input__tag-item--multi-select"
21
- + (this.props.readOnly ? ' tags-input__tag-item--readonly' : '')
22
- }
23
- onClick={() => (!this.props.readOnly && !this.props.disabled)
24
- && this.props.onRemove()
25
- }
27
+ className={classes}
26
28
  style={
27
29
  this.props.valueTemplate
28
30
  ? {backgroundColor: this.props.backgroundColor}
@@ -31,6 +33,9 @@ export class TreeSelectPill<T> extends React.Component<IProps<T>> {
31
33
  }
32
34
  data-test-id="item"
33
35
  >
36
+ {this.props.draggable && (
37
+ <DragHandle blank={true} dotsInRow='3' dotRows='4' />
38
+ )}
34
39
  <span
35
40
  className="tags-input__helper-box"
36
41
  style={{
@@ -43,9 +48,15 @@ export class TreeSelectPill<T> extends React.Component<IProps<T>> {
43
48
  {this.props.children}
44
49
 
45
50
  {!this.props.readOnly
46
- && <span className="tags-input__remove-button" data-test-id="remove">
51
+ && <button
52
+ className="tags-input__remove-button"
53
+ data-test-id="remove"
54
+ onClick={() => (!this.props.readOnly && !this.props.disabled)
55
+ && this.props.onRemove()
56
+ }
57
+ >
47
58
  <Icon name="close-small"></Icon>
48
- </span>
59
+ </button>
49
60
  }
50
61
  </span>
51
62
  </li>
@@ -64,13 +64,17 @@ import { MultiselectDocs } from './MultiSelect';
64
64
  import { TreeSelectDocs } from './TreeSelect';
65
65
  import { TreeMenuDocs } from './TreeMenu';
66
66
  import DurationInputDoc from './DurationInput';
67
- import {WithPaginationDocs} from './WithPaginationDocs';
67
+ import { WithPaginationDocs } from './WithPaginationDocs';
68
68
  import { PopoverDoc } from './Popover';
69
69
  import { MenuDocs } from './Menu';
70
- import {WithSizeObserverDocs} from './WithSizeObserver';
71
- import {ResizablePanelsDoc} from './ResizablePanels';
70
+ import { WithSizeObserverDocs } from './WithSizeObserver';
71
+ import { ResizablePanelsDoc } from './ResizablePanels';
72
72
  import { IllustrationButtonDoc } from './IllustrationButton';
73
73
 
74
+ // Utilities
75
+ import {SpacingUtilitiesDoc} from './utilities/SpacingUtilities';
76
+ import {TextUtilitiesDoc} from './utilities/TextUtilities';
77
+
74
78
  const pages = {
75
79
  basicComponents: {
76
80
  name: 'Basic Components',
@@ -291,6 +295,17 @@ const pages = {
291
295
  name: 'Big icon font'
292
296
  }
293
297
  }
298
+ },
299
+ utilityClasses: {
300
+ name: "Utility classes",
301
+ items: {
302
+ 'spacing-utilities': {
303
+ name: 'Spacing Utilities',
304
+ },
305
+ 'text-utilities': {
306
+ name: 'Text utilities'
307
+ }
308
+ }
294
309
  }
295
310
  }
296
311
  interface IProps {
@@ -344,66 +359,69 @@ class ReactDoc extends React.Component<IProps, IState> {
344
359
  </Dropdown>
345
360
  </div>
346
361
  <Switch>
347
- <Route path="/react/buttons" component={ButtonsDoc} />
348
- <Route path="/react/icon-buttons" component={IconButtonDoc} />
349
- <Route path="/react/button-groups" component={ButtonGroupsDoc} />
350
- <Route path="/react/labels" component={LabelsDoc} />
351
- <Route path="/react/icon-labels" component={IconLabelDoc} />
352
- <Route path="/react/badges" component={BadgesDoc} />
353
- <Route path="/react/alerts" component={AlertDoc} />
354
- <Route path="/react/avatar" component={AvatarDoc} />
355
- <Route path="/react/tooltips" component={TooltipDoc} />
356
- <Route path="/react/tags" component={TagDoc} />
357
- <Route path="/react/inputs" component={InputsDoc} />
358
- <Route path="/react/autocomplete" component={AutocompleteDoc} />
359
- <Route path="/react/select" component={SelectsDoc} />
360
- <Route path="/react/select-with-template" component={SelectWithTemplateDocs} />
361
- <Route path="/react/with-size-observer" component={WithSizeObserverDocs} />
362
- <Route path="/react/multiselect" component={MultiselectDocs} />
363
- <Route path="/react/treeselect" component={TreeSelectDocs} />
364
- <Route path="/react/treemenu" component={TreeMenuDocs} />
365
- <Route path="/react/duration-input" component={DurationInputDoc} />
366
- <Route path="/react/with-pagination" component={WithPaginationDocs} />
367
- <Route path="/react/popover" component={PopoverDoc} />
368
- <Route path="/react/date-picker" component={DatePickerDoc} />
369
- <Route path="/react/time-picker" component={TimePickerDoc} />
370
- <Route path="/react/switch" component={SwitchDoc} />
371
- <Route path="/react/radiogroup" component={RadioGroupDoc} />
372
- <Route path="/react/checkbox" component={CheckboxsDoc} />
373
- <Route path="/react/tab" component={TabsDoc} />
374
- <Route path="/react/left-navigation" component={LeftNavigationsDoc} />
375
- <Route path="/react/Quick-navigation-bar" component={QuickNavBarDoc} />
376
- <Route path="/react/nav-buttons" component={NavButtonsDoc} />
377
- <Route path="/react/icon-font" component={IconFontDoc} />
378
- <Route path="/react/big-icon-font" component={BigIconFontDoc} />
379
- <Route path="/react/sub-navigation" component={SubNavDoc} />
380
- <Route path="/react/dropdowns" component={DropdownDoc} />
381
- <Route path="/react/toast" component={ToastsDoc} />
382
- <Route path="/react/drag-handle" component={DragHandleDocs} />
383
- <Route path="/react/tag-input" component={TagInputDocs} />
384
- <Route path="/react/empty-states" component={EmptyStateDoc} />
385
- <Route path="/react/grid-list" component={GridListDoc} />
386
- <Route path="/react/grid-item" component={GridItemDoc} />
387
- <Route path="/react/modal" component={ModalDoc} />
388
- <Route path="/react/carousel" component={CarouselDoc} />
389
- <Route path="/react/content-divider" component={ContentDividerDoc} />
390
- <Route path="/react/menu" component={MenuDocs} />
391
- <Route path="/react/togglebox" component={ToggleboxDocs} />
392
- <Route path="/react/list-items" component={ListItemsDoc} />
393
- <Route path="/react/panel" component={PanelDoc} />
394
- <Route path="/react/select-grid" component={SelectGridDocs} />
395
- <Route path="/react/icon-picker" component={IconPickerDocs} />
396
- <Route path="/react/simple-list" component={SimpleListDoc} />
397
- <Route path="/react/boxed-list" component={BoxedListDoc} />
398
- <Route path="/react/table-list" component={TableListDoc} />
399
- <Route path="/react/content-list" component={ContentListDoc} />
400
- <Route path="/react/heading" component={HeadingDoc} />
401
- <Route path="/react/text" component={TextDoc} />
402
- <Route path="/react/container" component={ContainerDoc} />
403
- <Route path="/react/dropzone" component={DropZoneDoc} />
404
- <Route path="/react/create-button" component={CreateButtonDoc} />
405
- <Route path="/react/resizable-panels" component={ResizablePanelsDoc} />
406
- <Route path="/react/illustration-button" component={IllustrationButtonDoc} />
362
+ <Route path="/components/buttons" component={ButtonsDoc} />
363
+ <Route path="/components/icon-buttons" component={IconButtonDoc} />
364
+ <Route path="/components/button-groups" component={ButtonGroupsDoc} />
365
+ <Route path="/components/labels" component={LabelsDoc} />
366
+ <Route path="/components/icon-labels" component={IconLabelDoc} />
367
+ <Route path="/components/badges" component={BadgesDoc} />
368
+ <Route path="/components/alerts" component={AlertDoc} />
369
+ <Route path="/components/avatar" component={AvatarDoc} />
370
+ <Route path="/components/tooltips" component={TooltipDoc} />
371
+ <Route path="/components/tags" component={TagDoc} />
372
+ <Route path="/components/inputs" component={InputsDoc} />
373
+ <Route path="/components/autocomplete" component={AutocompleteDoc} />
374
+ <Route path="/components/select" component={SelectsDoc} />
375
+ <Route path="/components/select-with-template" component={SelectWithTemplateDocs} />
376
+ <Route path="/components/with-size-observer" component={WithSizeObserverDocs} />
377
+ <Route path="/components/multiselect" component={MultiselectDocs} />
378
+ <Route path="/components/treeselect" component={TreeSelectDocs} />
379
+ <Route path="/components/treemenu" component={TreeMenuDocs} />
380
+ <Route path="/components/duration-input" component={DurationInputDoc} />
381
+ <Route path="/components/with-pagination" component={WithPaginationDocs} />
382
+ <Route path="/components/popover" component={PopoverDoc} />
383
+ <Route path="/components/date-picker" component={DatePickerDoc} />
384
+ <Route path="/components/time-picker" component={TimePickerDoc} />
385
+ <Route path="/components/switch" component={SwitchDoc} />
386
+ <Route path="/components/radiogroup" component={RadioGroupDoc} />
387
+ <Route path="/components/checkbox" component={CheckboxsDoc} />
388
+ <Route path="/components/tab" component={TabsDoc} />
389
+ <Route path="/components/left-navigation" component={LeftNavigationsDoc} />
390
+ <Route path="/components/Quick-navigation-bar" component={QuickNavBarDoc} />
391
+ <Route path="/components/nav-buttons" component={NavButtonsDoc} />
392
+ <Route path="/components/icon-font" component={IconFontDoc} />
393
+ <Route path="/components/big-icon-font" component={BigIconFontDoc} />
394
+ <Route path="/components/sub-navigation" component={SubNavDoc} />
395
+ <Route path="/components/dropdowns" component={DropdownDoc} />
396
+ <Route path="/components/toast" component={ToastsDoc} />
397
+ <Route path="/components/drag-handle" component={DragHandleDocs} />
398
+ <Route path="/components/tag-input" component={TagInputDocs} />
399
+ <Route path="/components/empty-states" component={EmptyStateDoc} />
400
+ <Route path="/components/grid-list" component={GridListDoc} />
401
+ <Route path="/components/grid-item" component={GridItemDoc} />
402
+ <Route path="/components/modal" component={ModalDoc} />
403
+ <Route path="/components/carousel" component={CarouselDoc} />
404
+ <Route path="/components/content-divider" component={ContentDividerDoc} />
405
+ <Route path="/components/menu" component={MenuDocs} />
406
+ <Route path="/components/togglebox" component={ToggleboxDocs} />
407
+ <Route path="/components/list-items" component={ListItemsDoc} />
408
+ <Route path="/components/panel" component={PanelDoc} />
409
+ <Route path="/components/select-grid" component={SelectGridDocs} />
410
+ <Route path="/components/icon-picker" component={IconPickerDocs} />
411
+ <Route path="/components/simple-list" component={SimpleListDoc} />
412
+ <Route path="/components/boxed-list" component={BoxedListDoc} />
413
+ <Route path="/components/table-list" component={TableListDoc} />
414
+ <Route path="/components/content-list" component={ContentListDoc} />
415
+ <Route path="/components/heading" component={HeadingDoc} />
416
+ <Route path="/components/text" component={TextDoc} />
417
+ <Route path="/components/container" component={ContainerDoc} />
418
+ <Route path="/components/dropzone" component={DropZoneDoc} />
419
+ <Route path="/components/create-button" component={CreateButtonDoc} />
420
+ <Route path="/components/resizable-panels" component={ResizablePanelsDoc} />
421
+ <Route path="/components/illustration-button" component={IllustrationButtonDoc} />
422
+ {/* Utilities */}
423
+ <Route path="/components/spacing-utilities" component={SpacingUtilitiesDoc} />
424
+ <Route path="/components/text-utilities" component={TextUtilitiesDoc} />
407
425
  <Route path="/" component={ReactDefault} />
408
426
  </Switch>
409
427
  </main>
@@ -252,7 +252,7 @@ export class TreeSelectDocs extends React.Component<{}, IState> {
252
252
  label='TreeSelect Label'
253
253
  info='Info Message'
254
254
  searchPlaceholder='Search...'
255
- getBackgroundColor={(item: any) => item.bgColor}
255
+ getBackgroundColor={(item: any) => item.bgColor}
256
256
  valueTemplate={(item, Wrapper) => {
257
257
  return (
258
258
  <Wrapper backgroundColor={item.bgColor}>
@@ -278,7 +278,65 @@ export class TreeSelectDocs extends React.Component<{}, IState> {
278
278
  label='TreeSelect Label'
279
279
  info='Info Message'
280
280
  searchPlaceholder='Search...'
281
- getBackgroundColor={(item: any) => item.bgColor}
281
+ getBackgroundColor={(item: any) => item.bgColor}
282
+ valueTemplate={(item, Wrapper) => {
283
+ return (
284
+ <Wrapper backgroundColor={item.bgColor}>
285
+ <span>{item.name}</span>
286
+ </Wrapper>
287
+ );
288
+ }}
289
+ onChange={(e) => false}
290
+ />
291
+ `}</Markup.ReactMarkupCode>
292
+
293
+ </Markup.ReactMarkup>
294
+
295
+ <p className='docs-page__paragraph'>Sortable mode in TreeSelect.</p>
296
+ <Markup.ReactMarkup>
297
+ <Markup.ReactMarkupPreview>
298
+ <div className='docs-page__content-row docs-page__content-row--no-margin'>
299
+ <div className='form__row'>
300
+ <TreeSelect
301
+ kind='synchronous'
302
+ value={[{name: 'Category1'}, {name: 'Category2'}, {name: 'Category3'}]}
303
+ getOptions={() => options}
304
+ getId={(item) => item.name}
305
+ getLabel={(item) => item.name}
306
+ selectBranchWithChildren
307
+ allowMultiple
308
+ sortable
309
+ label='TreeSelect Label'
310
+ info='Info Message'
311
+ searchPlaceholder='Search...'
312
+ getBackgroundColor={(item: any) => item.bgColor}
313
+ valueTemplate={(item, Wrapper) => {
314
+ return (
315
+ <Wrapper backgroundColor={item.bgColor}>
316
+ <span>{item.name}</span>
317
+ </Wrapper>
318
+ );
319
+ }}
320
+ onChange={(e) => false}
321
+ />
322
+ </div>
323
+ </div>
324
+ </Markup.ReactMarkupPreview>
325
+
326
+ <Markup.ReactMarkupCode>{`
327
+ <TreeSelect
328
+ kind='synchronous'
329
+ value={[{name: 'Category1'}]}
330
+ getOptions={() => options}
331
+ getId={(item) => item.name}
332
+ getLabel={(item) => item.name}
333
+ selectBranchWithChildren
334
+ allowMultiple
335
+ sortable
336
+ label='TreeSelect Label'
337
+ info='Info Message'
338
+ searchPlaceholder='Search...'
339
+ getBackgroundColor={(item: any) => item.bgColor}
282
340
  valueTemplate={(item, Wrapper) => {
283
341
  return (
284
342
  <Wrapper backgroundColor={item.bgColor}>
@@ -401,6 +459,7 @@ export class TreeSelectDocs extends React.Component<{}, IState> {
401
459
  <Prop name='loading' isRequired={false} type='boolean' default='false' description='Adds a loading indicator in dropdown.'/>
402
460
  <Prop name='allowMultiple' isRequired={false} type='boolean' default='/' description='Enable multi-select mode.'/>
403
461
  <Prop name='singleLevelSearch' isRequired={false} type='boolean' default='/' description='Limit search to only the level that is displayed.'/>
462
+ <Prop name='sortable' isRequired={false} type='boolean' default='/' description='Enable drag & drop functionality.'/>
404
463
  <Prop name='placeholder' isRequired={false} type='string' default='/' description='Placeholder of component in single select mode.'/>
405
464
  <Prop name='searchPlaceholder' isRequired={false} type='string' default='/' description='Filter input placeholder.'/>
406
465
  <Prop name='getLabel' isRequired={true} type='Function' default='/' description='Callback to invoke when value changes.'/>
@@ -409,7 +468,6 @@ export class TreeSelectDocs extends React.Component<{}, IState> {
409
468
  <Prop name='getBorderColor' isRequired={true} type='Function' default='/' description='Function to return border color of individual item in options in single-select mode.'/>
410
469
  <Prop name='valueTemplate' isRequired={false} type='Function(item, Wrapper)' default='/' description='Function that gets an item in the value and returns the content for it.'/>
411
470
  <Prop name='optionTemplate' isRequired={false} type='Function(item)' default='/' description='Function that gets the option and returns the content for it.'/>
412
- <Prop name='searchOptions' isRequired={false} type='Function' default='/' description='The function will be called when a search is initiated from UI in asynchronous mode.'/>
413
471
  <Prop name='onChange' isRequired={true} type='Function' default='/' description='Callback to invoke when value changes.'/>
414
472
  <Prop name='label' isRequired={false} type='string' default='/' description='Label of component.' />
415
473
  <Prop name='inlineLabel' isRequired={false} type='boolean' default='false' description='Position labels as inline.' />