@eccenca/gui-elements 22.0.1 → 22.1.0-rc.0

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 (269) hide show
  1. package/CHANGELOG.md +20 -4
  2. package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js +18 -14
  3. package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
  4. package/dist/cjs/cmem/ActivityControl/SilkActivityControl.js +58 -30
  5. package/dist/cjs/cmem/ActivityControl/SilkActivityControl.js.map +1 -1
  6. package/dist/cjs/cmem/ActivityControl/index.js +11 -0
  7. package/dist/cjs/cmem/ActivityControl/index.js.map +1 -0
  8. package/dist/cjs/cmem/ContentBlobToggler/index.js +8 -0
  9. package/dist/cjs/cmem/ContentBlobToggler/index.js.map +1 -0
  10. package/dist/cjs/cmem/index.js +14 -13
  11. package/dist/cjs/cmem/index.js.map +1 -1
  12. package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js +57 -0
  13. package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -0
  14. package/dist/cjs/cmem/react-flow/configuration/_colors-graph.module.scss +35 -0
  15. package/dist/cjs/cmem/react-flow/configuration/_colors-linking.module.scss +29 -0
  16. package/dist/cjs/cmem/react-flow/configuration/_colors-workflow.module.scss +22 -0
  17. package/dist/cjs/cmem/react-flow/configuration/graph.js +31 -0
  18. package/dist/cjs/cmem/react-flow/configuration/graph.js.map +1 -0
  19. package/dist/cjs/cmem/react-flow/configuration/linking.js +29 -0
  20. package/dist/cjs/cmem/react-flow/configuration/linking.js.map +1 -0
  21. package/dist/cjs/cmem/react-flow/configuration/unspecified.js +15 -0
  22. package/dist/cjs/cmem/react-flow/configuration/unspecified.js.map +1 -0
  23. package/dist/cjs/cmem/react-flow/configuration/workflow.js +27 -0
  24. package/dist/cjs/cmem/react-flow/configuration/workflow.js.map +1 -0
  25. package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js +285 -0
  26. package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js.map +1 -0
  27. package/dist/cjs/components/AutoSuggestion/AutoSuggestionList.js +81 -0
  28. package/dist/cjs/components/AutoSuggestion/AutoSuggestionList.js.map +1 -0
  29. package/dist/cjs/components/AutoSuggestion/SingleLineCodeEditor.js +46 -0
  30. package/dist/cjs/components/AutoSuggestion/SingleLineCodeEditor.js.map +1 -0
  31. package/dist/cjs/components/AutocompleteField/AutoCompleteField.js +8 -12
  32. package/dist/cjs/components/AutocompleteField/AutoCompleteField.js.map +1 -1
  33. package/dist/cjs/components/Button/Button.js.map +1 -1
  34. package/dist/cjs/components/ContextOverlay/ContextMenu.js +1 -1
  35. package/dist/cjs/components/ContextOverlay/ContextMenu.js.map +1 -1
  36. package/dist/cjs/components/Dialog/Modal.js +2 -2
  37. package/dist/cjs/components/Dialog/Modal.js.map +1 -1
  38. package/dist/cjs/components/Dialog/SimpleDialog.js.map +1 -1
  39. package/dist/cjs/components/Icon/Icon.js.map +1 -1
  40. package/dist/cjs/components/Icon/canonicalIconNames.js +30 -0
  41. package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
  42. package/dist/cjs/components/MultiSelect/MultiSelect.js +219 -0
  43. package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -0
  44. package/dist/cjs/components/Tabs/Tab.js +95 -0
  45. package/dist/cjs/components/Tabs/Tab.js.map +1 -0
  46. package/dist/cjs/components/Tabs/TabTitle.js +20 -0
  47. package/dist/cjs/components/Tabs/TabTitle.js.map +1 -0
  48. package/dist/cjs/components/Tabs/Tabs.js +29 -19
  49. package/dist/cjs/components/Tabs/Tabs.js.map +1 -1
  50. package/dist/cjs/components/Tag/Tag.js +7 -1
  51. package/dist/cjs/components/Tag/Tag.js.map +1 -1
  52. package/dist/cjs/extensions/react-flow/edges/utils.js +96 -4
  53. package/dist/cjs/extensions/react-flow/edges/utils.js.map +1 -1
  54. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js +5 -4
  55. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  56. package/dist/cjs/extensions/react-flow/nodes/NodeContentExtension.js +2 -2
  57. package/dist/cjs/extensions/react-flow/nodes/NodeContentExtension.js.map +1 -1
  58. package/dist/cjs/extensions/react-flow/nodes/NodeTools.js.map +1 -1
  59. package/dist/cjs/index.js +17 -2
  60. package/dist/cjs/index.js.map +1 -1
  61. package/dist/cjs/legacy-replacements/Button/AffirmativeButton.js +25 -0
  62. package/dist/cjs/legacy-replacements/Button/AffirmativeButton.js.map +1 -0
  63. package/dist/cjs/legacy-replacements/Button/Button.js +61 -0
  64. package/dist/cjs/legacy-replacements/Button/Button.js.map +1 -0
  65. package/dist/cjs/legacy-replacements/Button/DismissiveButton.js +25 -0
  66. package/dist/cjs/legacy-replacements/Button/DismissiveButton.js.map +1 -0
  67. package/dist/cjs/legacy-replacements/Button/DisruptiveButton.js +25 -0
  68. package/dist/cjs/legacy-replacements/Button/DisruptiveButton.js.map +1 -0
  69. package/dist/cjs/legacy-replacements/Checkbox/Checkbox.js +55 -0
  70. package/dist/cjs/legacy-replacements/Checkbox/Checkbox.js.map +1 -0
  71. package/dist/cjs/legacy-replacements/Radio/RadioButton.js +48 -0
  72. package/dist/cjs/legacy-replacements/Radio/RadioButton.js.map +1 -0
  73. package/dist/cjs/legacy-replacements/Tabs/Tabs.js +36 -0
  74. package/dist/cjs/legacy-replacements/Tabs/Tabs.js.map +1 -0
  75. package/dist/cjs/legacy-replacements/TextField/TextField.js +75 -0
  76. package/dist/cjs/legacy-replacements/TextField/TextField.js.map +1 -0
  77. package/dist/cjs/legacy-replacements/index.js +22 -0
  78. package/dist/cjs/legacy-replacements/index.js.map +1 -0
  79. package/dist/es5/cmem/ActivityControl/ActivityControlWidget.js +19 -15
  80. package/dist/es5/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
  81. package/dist/es5/cmem/ActivityControl/SilkActivityControl.js +56 -30
  82. package/dist/es5/cmem/ActivityControl/SilkActivityControl.js.map +1 -1
  83. package/dist/es5/cmem/ActivityControl/index.js +4 -0
  84. package/dist/es5/cmem/ActivityControl/index.js.map +1 -0
  85. package/dist/es5/cmem/ContentBlobToggler/index.js +3 -0
  86. package/dist/es5/cmem/ContentBlobToggler/index.js.map +1 -0
  87. package/dist/es5/cmem/index.js +6 -8
  88. package/dist/es5/cmem/index.js.map +1 -1
  89. package/dist/es5/cmem/react-flow/ReactFlow/ReactFlow.js +43 -0
  90. package/dist/es5/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -0
  91. package/dist/es5/cmem/react-flow/configuration/_colors-graph.module.scss +35 -0
  92. package/dist/es5/cmem/react-flow/configuration/_colors-linking.module.scss +29 -0
  93. package/dist/es5/cmem/react-flow/configuration/_colors-workflow.module.scss +22 -0
  94. package/dist/es5/cmem/react-flow/configuration/graph.js +23 -0
  95. package/dist/es5/cmem/react-flow/configuration/graph.js.map +1 -0
  96. package/dist/es5/cmem/react-flow/configuration/linking.js +21 -0
  97. package/dist/es5/cmem/react-flow/configuration/linking.js.map +1 -0
  98. package/dist/es5/cmem/react-flow/configuration/unspecified.js +12 -0
  99. package/dist/es5/cmem/react-flow/configuration/unspecified.js.map +1 -0
  100. package/dist/es5/cmem/react-flow/configuration/workflow.js +19 -0
  101. package/dist/es5/cmem/react-flow/configuration/workflow.js.map +1 -0
  102. package/dist/es5/components/AutoSuggestion/AutoSuggestion.js +347 -0
  103. package/dist/es5/components/AutoSuggestion/AutoSuggestion.js.map +1 -0
  104. package/dist/es5/components/AutoSuggestion/AutoSuggestionList.js +93 -0
  105. package/dist/es5/components/AutoSuggestion/AutoSuggestionList.js.map +1 -0
  106. package/dist/es5/components/AutoSuggestion/SingleLineCodeEditor.js +42 -0
  107. package/dist/es5/components/AutoSuggestion/SingleLineCodeEditor.js.map +1 -0
  108. package/dist/es5/components/AutocompleteField/AutoCompleteField.js +8 -12
  109. package/dist/es5/components/AutocompleteField/AutoCompleteField.js.map +1 -1
  110. package/dist/es5/components/Button/Button.js.map +1 -1
  111. package/dist/es5/components/ContextOverlay/ContextMenu.js +1 -1
  112. package/dist/es5/components/ContextOverlay/ContextMenu.js.map +1 -1
  113. package/dist/es5/components/Dialog/Modal.js +2 -2
  114. package/dist/es5/components/Dialog/Modal.js.map +1 -1
  115. package/dist/es5/components/Dialog/SimpleDialog.js.map +1 -1
  116. package/dist/es5/components/Icon/Icon.js.map +1 -1
  117. package/dist/es5/components/Icon/canonicalIconNames.js +30 -0
  118. package/dist/es5/components/Icon/canonicalIconNames.js.map +1 -1
  119. package/dist/es5/components/MultiSelect/MultiSelect.js +301 -0
  120. package/dist/es5/components/MultiSelect/MultiSelect.js.map +1 -0
  121. package/dist/es5/components/Tabs/Tab.js +98 -0
  122. package/dist/es5/components/Tabs/Tab.js.map +1 -0
  123. package/dist/es5/components/Tabs/TabTitle.js +16 -0
  124. package/dist/es5/components/Tabs/TabTitle.js.map +1 -0
  125. package/dist/es5/components/Tabs/Tabs.js +11 -21
  126. package/dist/es5/components/Tabs/Tabs.js.map +1 -1
  127. package/dist/es5/components/Tag/Tag.js +7 -1
  128. package/dist/es5/components/Tag/Tag.js.map +1 -1
  129. package/dist/es5/extensions/react-flow/edges/utils.js +99 -5
  130. package/dist/es5/extensions/react-flow/edges/utils.js.map +1 -1
  131. package/dist/es5/extensions/react-flow/nodes/NodeContent.js +21 -4
  132. package/dist/es5/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  133. package/dist/es5/extensions/react-flow/nodes/NodeContentExtension.js +2 -2
  134. package/dist/es5/extensions/react-flow/nodes/NodeContentExtension.js.map +1 -1
  135. package/dist/es5/extensions/react-flow/nodes/NodeTools.js.map +1 -1
  136. package/dist/es5/index.js +9 -2
  137. package/dist/es5/index.js.map +1 -1
  138. package/dist/es5/legacy-replacements/Button/AffirmativeButton.js +29 -0
  139. package/dist/es5/legacy-replacements/Button/AffirmativeButton.js.map +1 -0
  140. package/dist/es5/legacy-replacements/Button/Button.js +65 -0
  141. package/dist/es5/legacy-replacements/Button/Button.js.map +1 -0
  142. package/dist/es5/legacy-replacements/Button/DismissiveButton.js +29 -0
  143. package/dist/es5/legacy-replacements/Button/DismissiveButton.js.map +1 -0
  144. package/dist/es5/legacy-replacements/Button/DisruptiveButton.js +29 -0
  145. package/dist/es5/legacy-replacements/Button/DisruptiveButton.js.map +1 -0
  146. package/dist/es5/legacy-replacements/Checkbox/Checkbox.js +59 -0
  147. package/dist/es5/legacy-replacements/Checkbox/Checkbox.js.map +1 -0
  148. package/dist/es5/legacy-replacements/Radio/RadioButton.js +52 -0
  149. package/dist/es5/legacy-replacements/Radio/RadioButton.js.map +1 -0
  150. package/dist/es5/legacy-replacements/Tabs/Tabs.js +40 -0
  151. package/dist/es5/legacy-replacements/Tabs/Tabs.js.map +1 -0
  152. package/dist/es5/legacy-replacements/TextField/TextField.js +81 -0
  153. package/dist/es5/legacy-replacements/TextField/TextField.js.map +1 -0
  154. package/dist/es5/legacy-replacements/index.js +10 -0
  155. package/dist/es5/legacy-replacements/index.js.map +1 -0
  156. package/dist/types/cmem/ActivityControl/ActivityControlTypes.d.ts +2 -1
  157. package/dist/types/cmem/ActivityControl/ActivityControlWidget.d.ts +39 -2
  158. package/dist/types/cmem/ActivityControl/SilkActivityControl.d.ts +16 -3
  159. package/dist/types/cmem/ActivityControl/index.d.ts +3 -0
  160. package/dist/types/cmem/ContentBlobToggler/index.d.ts +2 -0
  161. package/dist/types/cmem/index.d.ts +8 -8
  162. package/dist/types/cmem/react-flow/ReactFlow/ReactFlow.d.ts +14 -0
  163. package/dist/types/cmem/react-flow/configuration/graph.d.ts +21 -0
  164. package/dist/types/cmem/react-flow/configuration/linking.d.ts +19 -0
  165. package/dist/types/cmem/react-flow/configuration/unspecified.d.ts +9 -0
  166. package/dist/types/cmem/react-flow/configuration/workflow.d.ts +17 -0
  167. package/dist/types/components/AutoSuggestion/AutoSuggestion.d.ts +67 -0
  168. package/dist/types/components/AutoSuggestion/AutoSuggestionList.d.ts +13 -0
  169. package/dist/types/components/AutoSuggestion/SingleLineCodeEditor.d.ts +25 -0
  170. package/dist/types/components/AutocompleteField/AutoCompleteField.d.ts +8 -7
  171. package/dist/types/components/Button/Button.d.ts +3 -2
  172. package/dist/types/components/ContextOverlay/ContextMenu.d.ts +6 -1
  173. package/dist/types/components/Dialog/Modal.d.ts +4 -3
  174. package/dist/types/components/Dialog/SimpleDialog.d.ts +2 -0
  175. package/dist/types/components/Icon/Icon.d.ts +2 -2
  176. package/dist/types/components/Icon/IconButton.d.ts +1 -1
  177. package/dist/types/components/Icon/canonicalIconNames.d.ts +1 -1
  178. package/dist/types/components/MultiSelect/MultiSelect.d.ts +79 -0
  179. package/dist/types/components/Tabs/Tab.d.ts +549 -0
  180. package/dist/types/components/Tabs/TabTitle.d.ts +38 -0
  181. package/dist/types/components/Tabs/Tabs.d.ts +14 -20
  182. package/dist/types/components/Tag/Tag.d.ts +1 -1
  183. package/dist/types/extensions/react-flow/edges/utils.d.ts +1 -1
  184. package/dist/types/extensions/react-flow/nodes/NodeContent.d.ts +8 -8
  185. package/dist/types/extensions/react-flow/nodes/NodeDefault.d.ts +2 -2
  186. package/dist/types/extensions/react-flow/nodes/NodeTools.d.ts +2 -1
  187. package/dist/types/extensions/react-flow/nodes/nodeTypes.d.ts +10 -10
  188. package/dist/types/index.d.ts +9 -2
  189. package/dist/types/legacy-replacements/Button/AffirmativeButton.d.ts +2 -0
  190. package/dist/types/legacy-replacements/Button/Button.d.ts +5 -0
  191. package/dist/types/legacy-replacements/Button/DismissiveButton.d.ts +2 -0
  192. package/dist/types/legacy-replacements/Button/DisruptiveButton.d.ts +2 -0
  193. package/dist/types/legacy-replacements/Checkbox/Checkbox.d.ts +2 -0
  194. package/dist/types/legacy-replacements/Radio/RadioButton.d.ts +2 -0
  195. package/dist/types/legacy-replacements/Tabs/Tabs.d.ts +22 -0
  196. package/dist/types/legacy-replacements/TextField/TextField.d.ts +2 -0
  197. package/dist/types/legacy-replacements/index.d.ts +10 -0
  198. package/package.json +16 -7
  199. package/src/cmem/ActivityControl/ActivityControlTypes.ts +3 -1
  200. package/src/cmem/ActivityControl/ActivityControlWidget.stories.tsx +98 -0
  201. package/src/cmem/ActivityControl/ActivityControlWidget.tsx +131 -89
  202. package/src/cmem/ActivityControl/SilkActivityControl.tsx +178 -120
  203. package/src/cmem/ActivityControl/index.ts +3 -0
  204. package/src/cmem/ContentBlobToggler/index.ts +2 -0
  205. package/src/cmem/_index.scss +6 -0
  206. package/src/cmem/index.ts +10 -23
  207. package/src/cmem/react-flow/ReactFlow/ReactFlow.stories.tsx +222 -0
  208. package/src/cmem/react-flow/ReactFlow/ReactFlow.tsx +40 -0
  209. package/src/cmem/react-flow/_edges.scss +23 -0
  210. package/src/cmem/react-flow/_handles.scss +34 -0
  211. package/src/cmem/react-flow/_index.scss +5 -0
  212. package/src/cmem/react-flow/_minimap.scss +33 -0
  213. package/src/cmem/react-flow/_nodes.scss +60 -0
  214. package/src/cmem/react-flow/configuration/_colors-graph.module.scss +35 -0
  215. package/src/cmem/react-flow/configuration/_colors-linking.module.scss +29 -0
  216. package/src/cmem/react-flow/configuration/_colors-workflow.module.scss +22 -0
  217. package/src/cmem/react-flow/configuration/_colors.scss +3 -0
  218. package/src/cmem/react-flow/configuration/graph.ts +29 -0
  219. package/src/cmem/react-flow/configuration/linking.ts +28 -0
  220. package/src/cmem/react-flow/configuration/unspecified.ts +13 -0
  221. package/src/cmem/react-flow/configuration/workflow.ts +25 -0
  222. package/src/components/AutoSuggestion/AutoSuggestion.scss +100 -0
  223. package/src/components/AutoSuggestion/AutoSuggestion.tsx +447 -0
  224. package/src/components/AutoSuggestion/AutoSuggestionList.tsx +170 -0
  225. package/src/components/AutoSuggestion/SingleLineCodeEditor.tsx +97 -0
  226. package/src/components/AutoSuggestion/tests/AutoSuggestion.test.tsx +37 -0
  227. package/src/components/AutoSuggestion/tests/AutoSuggestionList.test.tsx +124 -0
  228. package/src/components/AutoSuggestion/tests/SingleLineCodeEditor.test.tsx +55 -0
  229. package/src/components/AutocompleteField/AutoCompleteField.tsx +19 -19
  230. package/src/components/AutocompleteField/autoCompleteFieldUtils.tsx +2 -1
  231. package/src/components/Button/Button.tsx +3 -2
  232. package/src/components/ContextOverlay/ContextMenu.tsx +8 -2
  233. package/src/components/Dialog/Modal.tsx +9 -2
  234. package/src/components/Dialog/SimpleDialog.tsx +2 -0
  235. package/src/components/Icon/Icon.tsx +4 -4
  236. package/src/components/Icon/IconButton.tsx +1 -1
  237. package/src/components/Icon/canonicalIconNames.tsx +39 -2
  238. package/src/components/MultiSelect/MultiSelect.stories.tsx +63 -0
  239. package/src/components/MultiSelect/MultiSelect.tsx +370 -0
  240. package/src/components/Tabs/Tab.tsx +112 -0
  241. package/src/components/Tabs/TabTitle.tsx +71 -0
  242. package/src/components/Tabs/Tabs.tsx +26 -90
  243. package/src/components/Tabs/stories/Tab.stories.tsx +65 -0
  244. package/src/components/Tabs/stories/TabTitle.stories.tsx +35 -0
  245. package/src/components/Tabs/stories/Tabs.stories.tsx +98 -0
  246. package/src/components/Tabs/tabs.scss +11 -4
  247. package/src/components/Tag/Tag.tsx +10 -3
  248. package/src/components/Tag/tag.scss +1 -1
  249. package/src/components/TextField/TextField.tsx +1 -1
  250. package/src/configuration/_variables.scss +3 -3
  251. package/src/extensions/react-flow/_config.scss +2 -2
  252. package/src/extensions/react-flow/edges/_edges.scss +3 -28
  253. package/src/extensions/react-flow/edges/utils.ts +139 -4
  254. package/src/extensions/react-flow/handles/_handles.scss +4 -58
  255. package/src/extensions/react-flow/minimap/_minimap.scss +0 -45
  256. package/src/extensions/react-flow/nodes/NodeContent.tsx +134 -133
  257. package/src/extensions/react-flow/nodes/NodeContentExtension.tsx +11 -10
  258. package/src/extensions/react-flow/nodes/NodeDefault.tsx +2 -2
  259. package/src/extensions/react-flow/nodes/NodeTools.tsx +2 -1
  260. package/src/extensions/react-flow/nodes/_nodes.scss +31 -185
  261. package/src/extensions/react-flow/nodes/{NodeContent.stories.tsx → stories/NodeContent.stories.tsx} +4 -4
  262. package/src/extensions/react-flow/nodes/{NodeContentExtension.stories.tsx → stories/NodeContentExtension.stories.tsx} +4 -4
  263. package/src/extensions/react-flow/nodes/{NodeDefault.stories.tsx → stories/NodeDefault.stories.tsx} +5 -4
  264. package/src/index.scss +1 -0
  265. package/src/index.ts +16 -1
  266. package/src/legacy-replacements/Tabs/Tabs.stories.tsx +46 -0
  267. package/src/legacy-replacements/Tabs/Tabs.tsx +84 -0
  268. package/src/legacy-replacements/index.ts +11 -0
  269. package/src/test/setupTests.js +19 -0
@@ -4,10 +4,13 @@
4
4
  */
5
5
 
6
6
  import React from 'react';
7
- import {Classes as BlueprintClassNames, OverlayProps, Overlay as BlueprintOverlay,} from "@blueprintjs/core";
7
+ import {
8
+ Classes as BlueprintClassNames,
9
+ OverlayProps, Overlay as BlueprintOverlay,
10
+ IOverlayState,
11
+ } from "@blueprintjs/core";
8
12
  import {Card} from "./../Card";
9
13
  import {CLASSPREFIX as eccgui} from "../../configuration/constants";
10
- import { IOverlayState } from '@blueprintjs/core';
11
14
 
12
15
  export interface ModalProps extends OverlayProps, IOverlayState {
13
16
  children: React.ReactNode | React.ReactNode[];
@@ -23,6 +26,8 @@ export interface ModalProps extends OverlayProps, IOverlayState {
23
26
  * Prevents that a backdrop area is displayed behind the modal elements.
24
27
  */
25
28
  preventBackdrop?: boolean;
29
+ /** Optional props for the wrapper div element inside the modal overlay. */
30
+ wrapperDivProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
26
31
  }
27
32
 
28
33
  /**
@@ -38,6 +43,7 @@ function Modal({
38
43
  canOutsideClickClose=false,
39
44
  canEscapeKeyClose=false,
40
45
  preventBackdrop=false,
46
+ wrapperDivProps,
41
47
  ...otherProps
42
48
  }: ModalProps) {
43
49
 
@@ -65,6 +71,7 @@ function Modal({
65
71
  hasBackdrop={!preventBackdrop}
66
72
  >
67
73
  <div
74
+ {...wrapperDivProps}
68
75
  className={BlueprintClassNames.DIALOG_CONTAINER}
69
76
  // this is a workaround because data attribute on SimpleDialog is not correctly routed to the overlay by blueprint js
70
77
  data-test-id={(otherProps as any)["data-test-id"] ?? "simpleDialogWidget"}
@@ -47,6 +47,8 @@ export interface SimpleDialogProps extends ModalProps, TestableComponent {
47
47
  * Define purpose of the dialog, e.g. if it is a warning.
48
48
  */
49
49
  intent?: IntentTypes;
50
+ /** Optional props for the wrapper div element inside the modal. */
51
+ wrapperDivProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
50
52
  }
51
53
 
52
54
  /**
@@ -5,7 +5,7 @@ import { IntentTypes } from "../../common/Intent";
5
5
  import Tooltip, { TooltipProps } from "./../Tooltip/Tooltip";
6
6
  import canonicalIcons, {IconSized, ValidIconName} from "./canonicalIconNames"
7
7
 
8
- interface IconProps extends Omit<CarbonIconProps, "icon" | "description" | "name"> {
8
+ export interface IconProps extends Omit<CarbonIconProps, "icon" | "description" | "name"> {
9
9
  // The CSS class name.
10
10
  className?: string,
11
11
  // Canonical icon name
@@ -38,16 +38,16 @@ const findExistingIcon = (iconName: ValidIconName | string[],
38
38
 
39
39
  /** Returns the first icon name that exists or the fallback icon name. */
40
40
  export const findExistingIconName = (iconNames: string[],
41
- fallbackIconName: string = "Undefined"): string => {
41
+ fallbackIconName: ValidIconName = "Undefined"): ValidIconName => {
42
42
  let foundIconName: string = fallbackIconName;
43
43
  const iconNameStack = [...iconNames]
44
44
  while (foundIconName === fallbackIconName && iconNameStack.length > 0) {
45
45
  let iconNameToTest = iconNameStack.shift();
46
- if (iconNameToTest && canonicalIcons[iconNameToTest] != null) {
46
+ if (iconNameToTest && (canonicalIcons as any)[iconNameToTest] != null) {
47
47
  foundIconName = iconNameToTest
48
48
  }
49
49
  }
50
- return foundIconName
50
+ return foundIconName as ValidIconName
51
51
  }
52
52
 
53
53
  function Icon({
@@ -6,7 +6,7 @@ import {ValidIconName} from "./canonicalIconNames";
6
6
 
7
7
  interface IconButtonProps extends ButtonProps {
8
8
  // Canonical icon name
9
- name: ValidIconName
9
+ name: ValidIconName | string[]
10
10
  className?: string
11
11
  // Tooltip text
12
12
  text?: string,
@@ -1,8 +1,7 @@
1
1
  import * as icons from "@carbon/icons-react"
2
2
 
3
3
  /** Valid icon names. */
4
- export type ValidIconName = string // allow also dynamic string parameter (in intermediate elements that insert Icon elements)
5
- | "application-dataintegration"
4
+ export type ValidIconName = "application-dataintegration"
6
5
  | "application-homepage"
7
6
  | "application-useraccount"
8
7
  | "application-warning"
@@ -65,6 +64,11 @@ export type ValidIconName = string // allow also dynamic string parameter (in in
65
64
  | "operation-logout"
66
65
  | "operation-filter"
67
66
  | "operation-filteredit"
67
+ | "operation-comparison"
68
+ | "operation-transform"
69
+ | "operation-aggregation"
70
+ | "data-sourcepath"
71
+ | "data-targetpath"
68
72
  | "list-sort"
69
73
  | "list-sortasc"
70
74
  | "list-sortdesc"
@@ -106,6 +110,7 @@ export type ValidIconName = string // allow also dynamic string parameter (in in
106
110
  | "linked-item"
107
111
  | "operation-auto-graph-layout"
108
112
  | "unlinked-item"
113
+ | "write-protected"
109
114
  | "undefined"
110
115
  | "Undefined";
111
116
 
@@ -433,6 +438,32 @@ const canonicalIconNames: Record<ValidIconName, IconSized> = {
433
438
  normal: icons.FilterEdit20,
434
439
  large: icons.FilterEdit32
435
440
  },
441
+ "operation-transform": {
442
+ small: icons.Calculation16,
443
+ normal: icons.Calculation20,
444
+ large: icons.Calculation32
445
+ },
446
+ "operation-comparison": {
447
+ small: icons.Compare16,
448
+ normal: icons.Compare20,
449
+ large: icons.Compare32
450
+ },
451
+ "operation-aggregation": {
452
+ small: icons.DataCollection16,
453
+ normal: icons.DataCollection20,
454
+ large: icons.DataCollection32
455
+ },
456
+
457
+ "data-sourcepath": {
458
+ small: icons.Data_216,
459
+ normal: icons.Data_220,
460
+ large: icons.Data_232
461
+ },
462
+ "data-targetpath": {
463
+ small: icons.Data_116,
464
+ normal: icons.Data_120,
465
+ large: icons.Data_132
466
+ },
436
467
 
437
468
  "list-sort": {
438
469
  small: icons.ArrowsVertical16,
@@ -646,6 +677,12 @@ const canonicalIconNames: Record<ValidIconName, IconSized> = {
646
677
  large: icons.ChartNetwork32
647
678
  },
648
679
 
680
+ "write-protected": {
681
+ small: icons.DocumentProtected16,
682
+ normal: icons.DocumentProtected20,
683
+ large: icons.DocumentProtected32
684
+ },
685
+
649
686
  "undefined": {
650
687
  small: icons.Undefined16,
651
688
  normal: icons.Undefined20,
@@ -0,0 +1,63 @@
1
+ import React from "react";
2
+ import { ComponentStory, ComponentMeta } from "@storybook/react";
3
+ import { name } from "react-lorem-ipsum";
4
+
5
+ import MultiSelectExample from "./MultiSelect";
6
+
7
+ export default {
8
+ title: "Components/MultiSelect",
9
+ component: MultiSelectExample,
10
+ argTypes: {
11
+ placeholder: {
12
+ description: "Input placeholder text",
13
+ control: "text",
14
+ table: {
15
+ type: { summary: "string" },
16
+ },
17
+ },
18
+ openOnKeyDown: {
19
+ description:
20
+ "If true, the component waits until a keydown event in the TagInput before opening its popover. If false, the popover opens immediately after a mouse click focuses the component's TagInput ",
21
+ control: "boolean",
22
+ defaultValue: false,
23
+ table: {
24
+ type: { summary: "boolean" },
25
+ defaultValue: { summary: false },
26
+ },
27
+ },
28
+ items: {
29
+ description: "Array of items in the list",
30
+ control: "none",
31
+ },
32
+ },
33
+ } as ComponentMeta<typeof MultiSelectExample>;
34
+
35
+ const Template: ComponentStory<typeof MultiSelectExample> = (args) => <MultiSelectExample {...args} />;
36
+
37
+ export const Default = Template.bind({});
38
+
39
+ const items = new Array(5).fill(undefined).map((_) => {
40
+ const testLabel = name();
41
+ return { testLabel, testId: `${testLabel}-id` };
42
+ });
43
+
44
+ Default.args = {
45
+ items,
46
+ canCreateNewItem: true,
47
+ prePopulateWithItems: false,
48
+ equalityProp: "testId",
49
+ labelProp: "testLabel",
50
+ openOnKeyDown: true,
51
+ };
52
+
53
+ const TemplateWithOpenDropdown: ComponentStory<typeof MultiSelectExample> = (args) => <MultiSelectExample {...args} />;
54
+
55
+ export const openDropdownWhenFocused = TemplateWithOpenDropdown.bind({});
56
+
57
+ openDropdownWhenFocused.args = {
58
+ items,
59
+ canCreateNewItem: true,
60
+ prePopulateWithItems: false,
61
+ equalityProp: "testId",
62
+ labelProp: "testLabel",
63
+ };
@@ -0,0 +1,370 @@
1
+ import React from "react";
2
+ import { Intent as BlueprintIntent } from "@blueprintjs/core";
3
+ import { MultiSelect as BlueprintMultiSelect, MultiSelectProps, IItemRendererProps } from "@blueprintjs/select";
4
+ import MenuItem from "../Menu/MenuItem";
5
+ import Highlighter from "../Typography/Highlighter";
6
+ import Button from "../Button/Button";
7
+ import OverflowText from "../Typography/OverflowText";
8
+
9
+ interface SelectedParamsType<T> {
10
+ newlySelected: T;
11
+ selectedItems: T[];
12
+ createdItems: Partial<T>[];
13
+ }
14
+
15
+ interface IProps<T> extends Pick<MultiSelectProps<T>, "items" | "placeholder" | "openOnKeyDown"> {
16
+ /**
17
+ * field in an item, that differentiates on item from the other.
18
+ */
19
+ equalityProp: string;
20
+ /**
21
+ * field in the item object that would be used to describe the item.
22
+ * this would be used in the item selection list as well as the multi-select input
23
+ */
24
+ labelProp: string;
25
+ /**
26
+ * if new items that are not in the original item list can be created and appended
27
+ */
28
+ canCreateNewItem?: boolean;
29
+ /**
30
+ * When set to true will set the multi-select value with all the items provided
31
+ */
32
+ prePopulateWithItems?: boolean;
33
+ /**
34
+ * function handler that would be called anytime an item is selected/deselected or an item is created/removed
35
+ */
36
+ onSelection?: (params: SelectedParamsType<T>) => void;
37
+ /**
38
+ * Props to spread to `Popover`. Note that `content` cannot be changed.
39
+ */
40
+ popoverProps?: MultiSelectProps<T>["popoverProps"];
41
+ /**
42
+ * Props to spread to `TagInput`. Use `query` and `onQueryChange` to control the input.
43
+ */
44
+ tagInputProps?: MultiSelectProps<T>["tagInputProps"];
45
+
46
+ /**
47
+ * prop to listen for query changes, when text is entered in the multi-select input
48
+ */
49
+ runOnQueryChange?: (query: string) => Promise<T[] | undefined>;
50
+ /**
51
+ * Whether the component should take up the full width of its container.
52
+ * This overrides `popoverProps.fill` and `tagInputProps.fill`.
53
+ */
54
+ fullWidth?: boolean;
55
+ /**
56
+ * text content to render when filtering items returns zero results.
57
+ * If omitted, "No results." will be rendered in this case.
58
+ */
59
+ noResultText?: string;
60
+ /**
61
+ * text content to render when a new item non-existing in filtered items is about to be created .
62
+ * If omitted, "No results." will be rendered in this case.
63
+ */
64
+ newItemCreationText?: string;
65
+ /**
66
+ * The input element is displayed with primary color scheme.
67
+ */
68
+ hasStatePrimary?: boolean;
69
+ /**
70
+ * The input element is displayed with success (some type of green) color scheme.
71
+ */
72
+ hasStateSuccess?: boolean;
73
+ /**
74
+ * The input element is displayed with success (some type of orange) color scheme.
75
+ */
76
+ hasStateWarning?: boolean;
77
+ /**
78
+ * The input element is displayed with success (some type of red) color scheme.
79
+ */
80
+ hasStateDanger?: boolean;
81
+ /**
82
+ * Disables the input element
83
+ */
84
+ disabled?: boolean;
85
+ }
86
+
87
+ function MultiSelect<T>({
88
+ items,
89
+ prePopulateWithItems,
90
+ equalityProp,
91
+ labelProp,
92
+ onSelection,
93
+ canCreateNewItem,
94
+ popoverProps,
95
+ tagInputProps,
96
+ runOnQueryChange,
97
+ fullWidth = true,
98
+ noResultText = "No results.",
99
+ newItemCreationText = "Add new tag",
100
+ hasStatePrimary,
101
+ hasStateDanger,
102
+ hasStateSuccess,
103
+ hasStateWarning,
104
+ disabled,
105
+ ...otherProps
106
+ }: IProps<T>) {
107
+ const [createdItems, setCreatedItems] = React.useState<T[]>([]);
108
+ const [itemsCopy, setItemsCopy] = React.useState<T[]>([...items]);
109
+ const [filteredItemList, setFilteredItemList] = React.useState<T[]>([]);
110
+ const [selectedItems, setSelectedItems] = React.useState<T[]>(() => (prePopulateWithItems ? [...items] : []));
111
+ const [query, setQuery] = React.useState<string | undefined>(undefined);
112
+ //currently focused element in popover list
113
+ const [focusedItem, setFocusedItem] = React.useState<T | null>(null);
114
+ const tagInputRef = React.useRef<any>();
115
+
116
+ let intent;
117
+ switch (true) {
118
+ case hasStatePrimary:
119
+ intent = BlueprintIntent.PRIMARY;
120
+ break;
121
+ case hasStateSuccess:
122
+ intent = BlueprintIntent.SUCCESS;
123
+ break;
124
+ case hasStateWarning:
125
+ intent = BlueprintIntent.WARNING;
126
+ break;
127
+ case hasStateDanger:
128
+ intent = BlueprintIntent.DANGER;
129
+ break;
130
+ default:
131
+ break;
132
+ }
133
+
134
+ /** update items copy when the items change
135
+ * e.g for auto-complete when query change
136
+ */
137
+ React.useEffect(() => {
138
+ setItemsCopy([...items, ...createdItems]);
139
+ setFilteredItemList([...items, ...createdItems]);
140
+ /* eslint-disable react-hooks/exhaustive-deps */
141
+ }, [items.map((item) => item[equalityProp as keyof T]).join("|")]);
142
+
143
+ React.useEffect(() => {
144
+ onSelection &&
145
+ onSelection({
146
+ newlySelected: selectedItems.slice(-1)[0],
147
+ createdItems,
148
+ selectedItems,
149
+ });
150
+ /* eslint-disable react-hooks/exhaustive-deps */
151
+ }, [
152
+ onSelection,
153
+ selectedItems.map((item) => item[equalityProp as keyof T]).join("|"),
154
+ createdItems.map((item) => item[equalityProp as keyof T]).join("|"),
155
+ ]);
156
+
157
+ /**
158
+ * using the equality prop specified checks if an item has already been selected
159
+ * @param matcher
160
+ * @returns
161
+ */
162
+ const itemHasBeenSelectedAlready = (matcher: string) => {
163
+ return !!selectedItems.find((item) => String(item[equalityProp as keyof typeof item]).toString() === matcher);
164
+ };
165
+
166
+ /**
167
+ * removes already selected item from the selectedItems
168
+ * @param matcher
169
+ */
170
+ const removeItemSelection = (matcher: string) => {
171
+ setSelectedItems((items) => items.filter((t) => String(t[equalityProp as keyof typeof t]).toString() !== matcher));
172
+ };
173
+
174
+ /**
175
+ * selects and deselects an item from selection list
176
+ * if the item exists it removes it instead
177
+ * @param item
178
+ */
179
+ const onItemSelect = (item: T) => {
180
+ if (itemHasBeenSelectedAlready(String(item[equalityProp as keyof T]).toString())) {
181
+ removeItemSelection(String(item[equalityProp as keyof T]).toString());
182
+ } else {
183
+ setSelectedItems((items) => [...items, item]);
184
+ }
185
+ setQuery("");
186
+ };
187
+
188
+ /**
189
+ * search through item list using "label prop" and update the items popover
190
+ * @param query
191
+ */
192
+ const onQueryChange = async (query: string) => {
193
+ if (query.length) {
194
+ setQuery(query);
195
+ const resultFromQuery = runOnQueryChange && (await runOnQueryChange(removeExtraSpaces(query)));
196
+ setFilteredItemList(() =>
197
+ [...(resultFromQuery ?? itemsCopy), ...createdItems].filter((t) =>
198
+ String(t[labelProp as keyof typeof t]).toLowerCase().includes(query.toLowerCase())
199
+ )
200
+ );
201
+ }
202
+ };
203
+
204
+ // Renders the entries of the (search) options list
205
+ const optionRenderer = (label: string) => {
206
+ return <Highlighter label={label} searchValue={query} />;
207
+ };
208
+
209
+ /**
210
+ * defines how an item in the item list is displayed
211
+ * @param tag
212
+ * @param param
213
+ * @returns
214
+ */
215
+ const onItemRenderer = (item: T, { handleClick, modifiers }: IItemRendererProps) => {
216
+ if (!modifiers.matchesPredicate) {
217
+ return null;
218
+ }
219
+ const label = createdItems.find((createdItem) => createdItem[labelProp as keyof T] === item[labelProp as keyof T])
220
+ ? `${item[labelProp as keyof T]} (new tag)`
221
+ : item[labelProp as keyof T];
222
+ return (
223
+ <MenuItem
224
+ active={modifiers.active}
225
+ key={String(item[equalityProp as keyof T]).toString()}
226
+ icon={itemHasBeenSelectedAlready(String(item[equalityProp as keyof T]).toString()) ? "state-checked" : "state-unchecked"}
227
+ onClick={handleClick}
228
+ text={optionRenderer(String(label).toString())}
229
+ shouldDismissPopover={false}
230
+ />
231
+ );
232
+ };
233
+
234
+ /**
235
+ * clear all selected items in the multi-select input
236
+ */
237
+ const handleClear = () => {
238
+ setSelectedItems([]);
239
+ setFilteredItemList(itemsCopy);
240
+ };
241
+
242
+ /**
243
+ * remove a specific item from the multi-select input
244
+ * @param label
245
+ * @param index
246
+ */
247
+ const removeTagFromSelectionViaIndex = (label: string, index: number) => {
248
+ setSelectedItems([...selectedItems.slice(0, index), ...selectedItems.slice(index + 1)]);
249
+ setCreatedItems((items) => items.filter((t) => String(t[labelProp as keyof typeof t]).toString() !== label));
250
+ };
251
+
252
+ const removeExtraSpaces = (text: string) => text.replace(/\s+/g, " ").trim();
253
+
254
+ /**
255
+ * utility function to create a new Item
256
+ * @param event
257
+ * @param label
258
+ */
259
+ const createNewItem = (event: React.KeyboardEvent<HTMLElement> | React.MouseEvent<HTMLElement>, label: string): T => {
260
+ const newItem = { [labelProp]: removeExtraSpaces(label), [equalityProp]: removeExtraSpaces(label) } as any;
261
+ //set new items
262
+ setCreatedItems((items) => [...items, newItem]);
263
+ setQuery("");
264
+ itemsCopy.push(newItem);
265
+ return newItem;
266
+ };
267
+
268
+ /**
269
+ * added functionality to create new item when there are no matching items on enter keypress
270
+ * @param event
271
+ */
272
+ const handleOnKeyUp = (event: React.KeyboardEvent<HTMLElement>) => {
273
+ if (event.key === "Enter" && !filteredItemList.length && !!query) {
274
+ createNewItem(event, query);
275
+ }
276
+ tagInputRef.current?.focus();
277
+ };
278
+
279
+ /**
280
+ * added functionality to either create new item
281
+ * when there are no matching items or select an item on tab keypress
282
+ * @param event
283
+ */
284
+ const handleOnKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
285
+ if (event.key === "Tab" && !!query) {
286
+ event.preventDefault();
287
+ focusedItem ? onItemSelect(focusedItem) : onItemSelect(createNewItem(event, query));
288
+ setTimeout(() => tagInputRef.current?.focus());
289
+ }
290
+ };
291
+
292
+ /**
293
+ * create new item handler, displays the new item selector and creates a new item when selected
294
+ * @param label '
295
+ * @param active
296
+ * @param handleClick
297
+ * @returns
298
+ */
299
+ const newItemRenderer = (label: string, active: boolean, handleClick: React.MouseEventHandler<HTMLElement>) => {
300
+ if (!canCreateNewItem) return undefined;
301
+ const clickHandler = (e: React.MouseEvent<HTMLElement>) => {
302
+ createNewItem(e, label);
303
+ handleClick(e);
304
+ };
305
+ return (
306
+ <MenuItem
307
+ id={"new-tag"}
308
+ icon="item-add-artefact"
309
+ active={active}
310
+ key={label}
311
+ onClick={clickHandler}
312
+ text={<OverflowText>{`${newItemCreationText} '${label}'`}</OverflowText>}
313
+ />
314
+ );
315
+ };
316
+
317
+ const clearButton =
318
+ selectedItems.length > 0 ? (
319
+ <Button icon="operation-clear" data-test-id="clear-all-items" minimal={true} onClick={handleClear} />
320
+ ) : undefined;
321
+
322
+ return (
323
+ <BlueprintMultiSelect
324
+ {...otherProps}
325
+ query={query}
326
+ onQueryChange={onQueryChange}
327
+ items={filteredItemList}
328
+ onItemSelect={onItemSelect}
329
+ itemRenderer={onItemRenderer}
330
+ itemsEqual={(a: T, b: T) => a[labelProp as keyof T] === b[labelProp as keyof T]}
331
+ selectedItems={selectedItems}
332
+ noResults={<MenuItem disabled={true} text={noResultText} />}
333
+ tagRenderer={(tag) => tag[labelProp as keyof typeof tag]}
334
+ createNewItemRenderer={newItemRenderer}
335
+ onActiveItemChange={(activeItem) => setFocusedItem(activeItem)}
336
+ fill={fullWidth}
337
+ createNewItemFromQuery={(query) =>
338
+ ({
339
+ [labelProp]: removeExtraSpaces(query),
340
+ [equalityProp]: removeExtraSpaces(query),
341
+ } as any)
342
+ }
343
+ tagInputProps={{
344
+ inputProps: {
345
+ id: "item",
346
+ autoComplete: "off",
347
+ },
348
+ inputRef: tagInputRef,
349
+ intent,
350
+ addOnBlur: true,
351
+ onKeyDown: handleOnKeyDown,
352
+ onKeyUp: handleOnKeyUp,
353
+ onRemove: removeTagFromSelectionViaIndex,
354
+ rightElement: disabled ? undefined : clearButton,
355
+ tagProps: { minimal: true },
356
+ disabled,
357
+ ...tagInputProps,
358
+ }}
359
+ popoverProps={{
360
+ minimal: true,
361
+ position: "bottom-left",
362
+ hasBackdrop: true,
363
+ ...popoverProps,
364
+ defaultIsOpen: true,
365
+ }}
366
+ />
367
+ );
368
+ }
369
+
370
+ export default MultiSelect;