@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
@@ -0,0 +1,170 @@
1
+ import React from "react";
2
+ import computeScrollIntoView from "compute-scroll-into-view";
3
+ import {
4
+ Menu,
5
+ MenuItem,
6
+ Highlighter,
7
+ OverviewItem,
8
+ OverviewItemDescription,
9
+ OverviewItemLine,
10
+ OverflowText,
11
+ Spinner,
12
+ Spacing,
13
+ Tooltip,
14
+ } from "./../../";
15
+ import { ISuggestionWithReplacementInfo } from "./AutoSuggestion";
16
+
17
+ export interface IDropdownProps {
18
+ // The options of the drop down
19
+ options: Array<ISuggestionWithReplacementInfo>;
20
+ // Called when an item has been selected from the drop down
21
+ onItemSelectionChange: (item: ISuggestionWithReplacementInfo) => any;
22
+ // If the drop down is visible
23
+ isOpen: boolean;
24
+ // If the drop down should show a loading state
25
+ loading?: boolean;
26
+ left?: number;
27
+ // The item from the drop down that is active
28
+ currentlyFocusedIndex: number;
29
+ // Callback indicating what item should currently being highlighted, i.e. is either active or is hovered over
30
+ itemToHighlight: (item: ISuggestionWithReplacementInfo | undefined) => any;
31
+ }
32
+
33
+ const ListItem = ({ item }: any, ref: any) => {
34
+ const listItem = (
35
+ <OverviewItem densityHigh={true}>
36
+ <OverviewItemDescription>
37
+ <OverviewItemLine>
38
+ <OverflowText ellipsis="reverse">
39
+ <Highlighter
40
+ label={item.value}
41
+ searchValue={item.query}
42
+ />
43
+ </OverflowText>
44
+ </OverviewItemLine>
45
+ {item.description ? (
46
+ <OverviewItemLine small={true}>
47
+ <OverflowText>
48
+ <Highlighter
49
+ label={item.description}
50
+ searchValue={item.query}
51
+ />
52
+ </OverflowText>
53
+ </OverviewItemLine>
54
+ ) : null}
55
+ </OverviewItemDescription>
56
+ </OverviewItem>
57
+ );
58
+
59
+ return (
60
+ <div ref={ref}>
61
+ {!!item.description && item.description.length > 50 ? (
62
+ <Tooltip content={item.description}>{listItem}</Tooltip>
63
+ ) : (
64
+ <>{listItem}</>
65
+ )}
66
+ </div>
67
+ );
68
+ };
69
+
70
+ const Item = React.forwardRef(ListItem);
71
+
72
+ /** A drop-down-like list that can be used in combination with other components to show and select items. */
73
+ export const AutoSuggestionList = ({
74
+ isOpen,
75
+ options,
76
+ loading,
77
+ onItemSelectionChange,
78
+ left,
79
+ currentlyFocusedIndex,
80
+ itemToHighlight,
81
+ }: IDropdownProps) => {
82
+ const [hoveredItem, setHoveredItem] = React.useState<
83
+ ISuggestionWithReplacementInfo | undefined
84
+ >(undefined);
85
+ // Refs of list items
86
+ const [refs] = React.useState<React.RefObject<Element>[]>([])
87
+ const dropdownRef = React.useRef<HTMLDivElement>(null);
88
+ const generateRef = (index: number) => {
89
+ if (!refs[index]) {
90
+ refs[index] = React.createRef();
91
+ }
92
+ return refs[index];
93
+ };
94
+
95
+ React.useEffect(() => {
96
+ const listIndexNode = refs[currentlyFocusedIndex];
97
+ if (dropdownRef?.current && listIndexNode?.current) {
98
+ const actions = computeScrollIntoView(listIndexNode.current, {
99
+ boundary: dropdownRef.current,
100
+ block: "nearest",
101
+ scrollMode: "if-needed",
102
+ });
103
+ actions.forEach(({ el, top, left }) => {
104
+ el.scrollTop = top;
105
+ el.scrollLeft = left;
106
+ });
107
+ }
108
+ }, [currentlyFocusedIndex, refs]);
109
+
110
+ const focusedItem = options[currentlyFocusedIndex]
111
+
112
+ // Decide which item to highlight
113
+ React.useEffect(() => {
114
+ itemToHighlight(!isOpen ? undefined : hoveredItem || focusedItem);
115
+ }, [
116
+ currentlyFocusedIndex,
117
+ itemToHighlight,
118
+ focusedItem,
119
+ isOpen,
120
+ hoveredItem,
121
+ ]);
122
+
123
+ const Loader = (
124
+ <OverviewItem hasSpacing>
125
+ <OverviewItemLine>Fetching suggestions</OverviewItemLine>
126
+ <Spacing size="tiny" vertical={true} />
127
+ <Spinner position="inline" description="" />
128
+ </OverviewItem>
129
+ );
130
+
131
+ const loadingOrHasSuggestions = loading || options.length;
132
+ if (!loadingOrHasSuggestions || !isOpen) return null;
133
+ return (
134
+ <div
135
+ className="ecc-auto-suggestion-box__dropdown"
136
+ style={{ left }}
137
+ ref={dropdownRef}
138
+ >
139
+ {loading ? (
140
+ Loader
141
+ ) : (
142
+ <Menu>
143
+ {options.map((item, index) => (
144
+ <MenuItem
145
+ key={index}
146
+ internalProps={{
147
+ active: currentlyFocusedIndex === index,
148
+ onMouseDown: (e) => e.preventDefault(),
149
+ onClick: () => onItemSelectionChange(item),
150
+ text: (
151
+ <Item
152
+ ref={generateRef(index)}
153
+ item={item}
154
+ />
155
+ ),
156
+ onMouseEnter: () => setHoveredItem(item),
157
+ onMouseLeave: () => setHoveredItem(undefined),
158
+ onMouseOver: () => {
159
+ if (item.value !== hoveredItem?.value) {
160
+ setHoveredItem(item);
161
+ }
162
+ },
163
+ }}
164
+ />
165
+ ))}
166
+ </Menu>
167
+ )}
168
+ </div>
169
+ );
170
+ };
@@ -0,0 +1,97 @@
1
+ import "codemirror/addon/display/placeholder"
2
+ import "codemirror/mode/sparql/sparql.js";
3
+ import React from "react";
4
+ import { Controlled as ControlledEditor } from "react-codemirror2";
5
+ import { Classes as BlueprintClassNames } from "@blueprintjs/core";
6
+ import {Editor as CodeMirrorEditor} from "codemirror";
7
+
8
+ export interface IEditorProps {
9
+ // Is called with the editor instance that allows access via the CodeMirror API
10
+ setEditorInstance: (editor: CodeMirrorEditor) => any
11
+ // Called whenever the editor content changes
12
+ onChange: (value: string) => any
13
+ // Called when the cursor position changes
14
+ onCursorChange: (pos: any, coords: any) => any
15
+ // The editor theme, e.g. "sparql"
16
+ mode?: string
17
+ // The initial value of the editor
18
+ initialValue: string
19
+ // Called when the focus status changes
20
+ onFocusChange: (focused: boolean) => any
21
+ // Called when the user presses a key
22
+ onKeyDown: (event: KeyboardEvent) => any
23
+ // Called when the user selects text
24
+ onSelection: (ranges: IRange[]) => any
25
+ // If the <Tab> key is enabled as normal input, i.e. it won't have the behavior of changing to the next input element, expected in a web app.
26
+ enableTab?: boolean
27
+ /** Placeholder tobe shown when no text has been entered, yet. */
28
+ placeholder?: string
29
+ showScrollBar?: boolean
30
+ }
31
+
32
+ export interface IRange {
33
+ from: number
34
+ to: number
35
+ }
36
+
37
+ /** A single-line code editor. */
38
+ const SingleLineCodeEditor = ({
39
+ setEditorInstance,
40
+ onChange,
41
+ onCursorChange,
42
+ mode,
43
+ initialValue,
44
+ onFocusChange,
45
+ onKeyDown,
46
+ onSelection,
47
+ enableTab = false,
48
+ placeholder,
49
+ showScrollBar = true
50
+ }: IEditorProps) => {
51
+ return (
52
+ <div className={"ecc-input-editor " + BlueprintClassNames.INPUT}>
53
+ <ControlledEditor
54
+ editorDidMount={(editor) => {
55
+ editor.on("beforeChange", (_, change) => {
56
+ // Prevent the user from entering new-line characters, since this is supposed to be a one-line editor.
57
+ const newText = change.text.join("").replace(/\n/g, "");
58
+ //failing unexpectedly during undo and redo
59
+ if (change.update && typeof change.update === "function") {
60
+ change.update(change.from, change.to, [newText]);
61
+ }
62
+ return true;
63
+ });
64
+ setEditorInstance(editor);
65
+ }}
66
+ value={initialValue}
67
+ onFocus={() => onFocusChange(true)}
68
+ onBlur={() => onFocusChange(false)}
69
+ options={{
70
+ mode: mode,
71
+ lineNumbers: false,
72
+ theme: "xq-light",
73
+ extraKeys: enableTab ? undefined : {Tab: false},
74
+ placeholder,
75
+ scrollbarStyle: showScrollBar ? "native" : "null"
76
+ }}
77
+ onSelection={(editor, data) => {
78
+ if(Array.isArray(data?.ranges)) {
79
+ onSelection(data.ranges
80
+ .map((r: any) => ({from: r.from().ch, to: r.to().ch}))
81
+ .filter((r: any) => r.from !== r.to))
82
+ }
83
+ }}
84
+ onCursor={(editor, data) => {
85
+ onCursorChange(data, editor.cursorCoords(true, "div"));
86
+ }}
87
+ onBeforeChange={(editor, data, value) => {
88
+ const trimmedValue = value.replace(/\n/g, "");
89
+ onChange(trimmedValue);
90
+ }}
91
+ onKeyDown={(_, event) => onKeyDown(event)}
92
+ />
93
+ </div>
94
+ );
95
+ };
96
+
97
+ export default SingleLineCodeEditor;
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+ import "@testing-library/jest-dom";
3
+ import {render} from "@testing-library/react";
4
+ import AutoSuggestion, {IProps} from "../AutoSuggestion"
5
+
6
+ describe("AutoSuggestion", () => {
7
+ let props: IProps
8
+ beforeEach(() => {
9
+ props = {
10
+ label: "test value path",
11
+ initialValue: "",
12
+ onChange: jest.fn((value) => {
13
+ }),
14
+ fetchSuggestions: jest.fn((inputString, cursorPosition) => undefined),
15
+ checkInput: jest.fn(inputString => ({
16
+ valid: true
17
+ })),
18
+ onInputChecked: jest.fn(validInput => {
19
+ }),
20
+ validationErrorText: "",
21
+ clearIconText: "",
22
+ onFocusChange: jest.fn(hasFocus => {
23
+ }),
24
+ id: "test-auto-suggestion"
25
+ }
26
+ })
27
+
28
+ it("should render properly", () => {
29
+ const {container} = render(<AutoSuggestion {...props} />)
30
+ expect(container).not.toBeEmptyDOMElement()
31
+ })
32
+
33
+ it("should set label prop properly", () => {
34
+ const {getByText} = render(<AutoSuggestion {...props}/>)
35
+ expect(getByText(props.label!!)).toBeTruthy()
36
+ })
37
+ })
@@ -0,0 +1,124 @@
1
+ import React from 'react';
2
+ import '@testing-library/jest-dom'
3
+ import {fireEvent, render} from '@testing-library/react'
4
+ import {CLASSPREFIX as eccgui} from "../../../configuration/constants";
5
+ import {AutoSuggestionList, IDropdownProps} from '../AutoSuggestionList'
6
+
7
+ describe("Dropdown list", () => {
8
+ let props:IDropdownProps, mockOptions
9
+ beforeEach(() => {
10
+ props = {
11
+ currentlyFocusedIndex: 0,
12
+ loading: false,
13
+ left:0,
14
+ isOpen: false,
15
+ options: [],
16
+ itemToHighlight: () => {},
17
+ onItemSelectionChange: () => {}
18
+ }
19
+
20
+ mockOptions = [
21
+ {
22
+ query:"organizations",
23
+ from: 0,
24
+ length: 13,
25
+ value:"organizations/name"
26
+ },
27
+ {
28
+ query:"",
29
+ from: 13,
30
+ length:0,
31
+ value:"/"
32
+ }
33
+ ]
34
+ })
35
+
36
+
37
+ it("doesn't render when not focused", () => {
38
+ const {container} = render(<AutoSuggestionList {...props} />)
39
+ expect(container).toBeEmptyDOMElement()
40
+ })
41
+
42
+ it("should be able to display loading state, when fetching suggestions", () => {
43
+ props = {
44
+ ...props,
45
+ loading: true,
46
+ isOpen: true
47
+ }
48
+ const {getByText} = render(<AutoSuggestionList {...props} />)
49
+ expect(getByText("Fetching suggestions")).toBeTruthy()
50
+ })
51
+
52
+ it("should render list when suggestions are fetched", () => {
53
+ props = {
54
+ ...props,
55
+ loading: false,
56
+ isOpen:true,
57
+ options: mockOptions
58
+ }
59
+ const {container} = render(<AutoSuggestionList {...props} />)
60
+ const dropdownItems = container.getElementsByTagName("li")
61
+ expect(container).not.toBeEmptyDOMElement()
62
+ expect(dropdownItems.length).toBe(2)
63
+ })
64
+
65
+ it("should move horizontally for every cursor movement", () => {
66
+ props = {
67
+ ...props,
68
+ options: mockOptions,
69
+ loading: false,
70
+ isOpen: true,
71
+ left: 10
72
+ }
73
+ const {container} = render(<AutoSuggestionList {...props} />)
74
+ const parentDiv:HTMLElement = container.querySelector(".ecc-auto-suggestion-box__dropdown")!!
75
+ const leftOffset = Number(parentDiv.style.left.replace(/px$/,""));
76
+ expect(leftOffset).toBe(props.left)
77
+ })
78
+
79
+ it("should have one active item at a time", () => {
80
+ props = {
81
+ ...props,
82
+ loading: false,
83
+ isOpen:true,
84
+ options: mockOptions
85
+ }
86
+ const {container} = render(<AutoSuggestionList {...props} />)
87
+ const activeListItems = Array.from(container.querySelectorAll("li .bp3-menu-item.bp3-active"))
88
+ expect(activeListItems.length).toBe(1)
89
+ })
90
+
91
+ it("should respond to click on each item and pass the clicked item to autosuggestion", () => {
92
+ const mockOnItemSelection = jest.fn((item) => {})
93
+ props = {
94
+ ...props,
95
+ loading: false,
96
+ isOpen:true,
97
+ options: mockOptions,
98
+ onItemSelectionChange: mockOnItemSelection
99
+ }
100
+ const {getByText} = render(<AutoSuggestionList {...props}/>)
101
+ const dropdownListItem = getByText(props.options[0].query).closest(`.${eccgui}-menu__item`);
102
+ fireEvent.click(dropdownListItem!!)
103
+ expect(mockOnItemSelection).toHaveBeenCalledTimes(1)
104
+ expect(mockOnItemSelection).toHaveBeenCalledWith(props.options[0])
105
+ })
106
+
107
+ it("should call highlight function when list item is mouse hovered",() => {
108
+ const mockItemToHighlight = jest.fn((item) => {})
109
+ props = {
110
+ ...props,
111
+ loading: false,
112
+ isOpen:true,
113
+ options: mockOptions,
114
+ itemToHighlight: mockItemToHighlight
115
+ }
116
+ const {container} = render(<AutoSuggestionList {...props}/>)
117
+ const firstItem = container.querySelector("li");
118
+ fireEvent.mouseEnter(firstItem!!)
119
+ expect(mockItemToHighlight).toHaveBeenCalledWith(props.options[0])
120
+ expect(mockItemToHighlight).toHaveBeenCalledTimes(1)
121
+ fireEvent.mouseLeave(firstItem!!)
122
+ expect(mockItemToHighlight).toHaveBeenCalledTimes(1)
123
+ })
124
+ })
@@ -0,0 +1,55 @@
1
+ import React from "react";
2
+ import "@testing-library/jest-dom";
3
+ import { render } from "@testing-library/react";
4
+ import SingleLineEditor, {
5
+ IEditorProps,
6
+ } from "../SingleLineCodeEditor";
7
+ import CodeMirror from "codemirror";
8
+
9
+ describe("SingleLineCodeEditor", () => {
10
+ let props: IEditorProps,
11
+ codeMirrorEditorInstance: CodeMirror.Editor = null as any;
12
+ beforeEach(() => {
13
+ props = {
14
+ setEditorInstance: jest.fn((editor) => {
15
+ codeMirrorEditorInstance = editor;
16
+ }),
17
+ onChange: jest.fn((value) => {}),
18
+ onCursorChange: jest.fn((pos, coords) => {}),
19
+ mode: null,
20
+ initialValue: "",
21
+ onFocusChange: jest.fn((focused) => {}),
22
+ onKeyDown: jest.fn((event) => {}),
23
+ onSelection: jest.fn((ranges) => {}),
24
+ };
25
+ });
26
+
27
+ it("should render properly", () => {
28
+ const { container } = render(<SingleLineEditor {...props} />);
29
+ expect(container.querySelector(".ecc-input-editor")).not.toBeNull();
30
+ });
31
+
32
+ it("should set the editorInstance immediately it's mounted", () => {
33
+ render(<SingleLineEditor {...props} />);
34
+ expect(props.setEditorInstance).toHaveBeenCalledTimes(1);
35
+ expect(codeMirrorEditorInstance).not.toBeNull();
36
+ });
37
+
38
+ it("should set the default value on the editor input", () => {
39
+ props = {
40
+ ...props,
41
+ initialValue: "This is the initial input",
42
+ };
43
+ const { getByText } = render(<SingleLineEditor {...props} />);
44
+ expect(codeMirrorEditorInstance.getValue()).toBe(props.initialValue);
45
+ expect(getByText(props.initialValue)).toBeTruthy();
46
+ });
47
+
48
+ it("should not allow user to create new lines", () => {
49
+ render(<SingleLineEditor {...props} />);
50
+ codeMirrorEditorInstance
51
+ .getDoc()
52
+ .setValue("I'm entering a new line \n character");
53
+ expect(codeMirrorEditorInstance.lineCount()).toBe(1);
54
+ });
55
+ });
@@ -17,10 +17,9 @@ export interface IRenderModifiers {
17
17
  /**
18
18
  * Parameters for the auto-complete field parameterized by T and U.
19
19
  * @param T is the input data structure/type of the items that can be selected.
20
- * @param U is the output data structure/type that is output on changes of the selected item, i.e. it may get converted first
21
- * before onChange is called.
20
+ * @param UPDATE_VALUE The value type that will be pushed into the onChange callback.
22
21
  */
23
- export interface IAutoCompleteFieldProps<T extends any, U extends any> {
22
+ export interface IAutoCompleteFieldProps<T extends any, UPDATE_VALUE extends any> {
24
23
  /**
25
24
  * Fired when text is typed into the input field. Returns a list of items of type T.
26
25
  */
@@ -31,7 +30,7 @@ export interface IAutoCompleteFieldProps<T extends any, U extends any> {
31
30
  * @param value The value that has been converted with itemValueSelector.
32
31
  * @param e The event
33
32
  */
34
- onChange?(value: U, e?: React.SyntheticEvent<HTMLElement>): any;
33
+ onChange?(value: UPDATE_VALUE, e?: React.SyntheticEvent<HTMLElement>): any;
35
34
 
36
35
  /**
37
36
  * The initial value for the auto-complete input field
@@ -58,7 +57,10 @@ export interface IAutoCompleteFieldProps<T extends any, U extends any> {
58
57
  * Selects the part from the auto-completion item that is called with the onChange callback.
59
58
  * @param item The selected item that should be converted to the value that onChange is called with.
60
59
  */
61
- itemValueSelector(item: T): U;
60
+ itemValueSelector(item: T): UPDATE_VALUE;
61
+
62
+ /** The string representation of the actual value, i.e. without meta data etc. This will be used to compare if values are equal. */
63
+ itemValueString(item: T): string
62
64
 
63
65
  /** The text that should be displayed when no search result has been found and no custom entry can be created. */
64
66
  noResultText: string
@@ -84,7 +86,7 @@ export interface IAutoCompleteFieldProps<T extends any, U extends any> {
84
86
  resettableValue(value: T): boolean;
85
87
 
86
88
  /** The value onChange is called with when a reset action is triggered. */
87
- resetValue: U;
89
+ resetValue: UPDATE_VALUE;
88
90
 
89
91
  /** The reset button text that is shown on hovering over the reset icon. */
90
92
  resetButtonText: string
@@ -143,7 +145,7 @@ const elementWidth = (elRef: IRefObject<HTMLInputElement> | null): IElementWidth
143
145
  }
144
146
 
145
147
  /** Auto-complete input widget. */
146
- export function AutoCompleteField<T extends any, U extends any>(props: IAutoCompleteFieldProps<T, U>) {
148
+ export function AutoCompleteField<T extends any, UPDATE_VALUE extends any>(props: IAutoCompleteFieldProps<T, UPDATE_VALUE>) {
147
149
  const {
148
150
  reset,
149
151
  noResultText,
@@ -157,6 +159,7 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
157
159
  createNewItem,
158
160
  itemValueRenderer,
159
161
  resetQueryToValue,
162
+ itemValueString,
160
163
  ...otherProps
161
164
  } = props;
162
165
  const [selectedItem, setSelectedItem] = useState<T | undefined>(initialValue);
@@ -177,8 +180,8 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
177
180
  if (item) {
178
181
  // If new values can be created, always reset the query value to the actual value of the selected item.
179
182
  // This e.g. prevents that the "create new" option will be shown, since an item with the same value already exists.
180
- const defaultResetValue: string = createNewItem && typeof itemValueSelector(item) === "string" ? (
181
- itemValueSelector(item) as string
183
+ const defaultResetValue: string = createNewItem ? (
184
+ itemValueString(item) as string
182
185
  ) : itemValueRenderer(item)
183
186
  const resetVal = resetQueryToValue ? resetQueryToValue(item) : defaultResetValue
184
187
  setQuery(resetVal)
@@ -189,11 +192,7 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
189
192
 
190
193
  // The key for the option elements
191
194
  const itemKey = (item: T): string => {
192
- let itemValue: U | string = itemValueSelector(item);
193
- if (typeof itemValue !== "string") {
194
- itemValue = itemValueRenderer(item);
195
- }
196
- return itemValue;
195
+ return itemValueString(item);
197
196
  };
198
197
 
199
198
  useEffect(() => {
@@ -250,9 +249,9 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
250
249
  // Return the index of the item in the array based on the itemValueRenderer value
251
250
  const itemIndexOf = (arr: T[], searchItem: T): number => {
252
251
  let idx = -1;
253
- const searchItemString = itemValueSelector(searchItem);
252
+ const searchItemString = itemValueString(searchItem);
254
253
  arr.forEach((v, i) => {
255
- if (itemValueSelector(v) === searchItemString) {
254
+ if (itemValueString(v) === searchItemString) {
256
255
  idx = i;
257
256
  }
258
257
  });
@@ -265,7 +264,7 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
265
264
  try {
266
265
  let result = await onSearch(input);
267
266
  const onlySelectItemReturned = result.length <= 1 && selectedItem && input.length > 0 &&
268
- (itemValueRenderer(selectedItem) === input || itemValueSelector(selectedItem) === input)
267
+ (itemValueRenderer(selectedItem) === input || itemValueString(selectedItem) === input)
269
268
  let enableHighlighting = true;
270
269
  if (onlySelectItemReturned) {
271
270
  // If the auto-completion only returns no suggestion or the selected item itself, query with empty string.
@@ -319,7 +318,7 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
319
318
  }
320
319
  };
321
320
  // Resets the selection
322
- const clearSelection = (resetValue: U) => () => {
321
+ const clearSelection = (resetValue: UPDATE_VALUE) => () => {
323
322
  setSelectedItem(undefined);
324
323
  onChange?.(resetValue);
325
324
  setQuery("");
@@ -350,6 +349,7 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
350
349
  position: "bottom",
351
350
  popoverClassName: `${eccgui}-autocompletefield__options`,
352
351
  wrapperTagName: "div",
352
+ boundary: "window",
353
353
  onClosed: onPopoverClose,
354
354
  ...otherProps.popoverProps,
355
355
  }
@@ -362,7 +362,7 @@ export function AutoCompleteField<T extends any, U extends any>(props: IAutoComp
362
362
  const createNewItemProps = createNewItem ? {
363
363
  createNewItemFromQuery: createNewItem.itemFromQuery,
364
364
  createNewItemRenderer: (query: string, active: boolean, handleClick: React.MouseEventHandler<HTMLElement>) => {
365
- if(selectedItem && query === itemValueSelector(selectedItem)) {
365
+ if(selectedItem && query === itemValueString(selectedItem)) {
366
366
  // Never show create new item option if the same item is already selected
367
367
  return undefined
368
368
  } else {
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import {IElementWidth, IRenderModifiers} from "./AutoCompleteField";
3
3
  import OverflowText from "../Typography/OverflowText";
4
4
  import MenuItem from "../Menu/MenuItem";
5
+ import {ValidIconName} from "../Icon/canonicalIconNames";
5
6
 
6
7
  /** Returns a function to be used in an AutoComplete widget for rendering custom elements based on the query string.
7
8
  *
@@ -10,7 +11,7 @@ import MenuItem from "../Menu/MenuItem";
10
11
  */
11
12
  export const createNewItemRendererFactory = (
12
13
  itemTextRenderer: (query: string, styleWidth: IElementWidth) => string | JSX.Element,
13
- iconName?: string) => {
14
+ iconName?: ValidIconName) => {
14
15
  // Return custom render function
15
16
  return (query: string, modifiers: IRenderModifiers, handleClick: React.MouseEventHandler<HTMLElement>) => {
16
17
  let textElement = itemTextRenderer(query, modifiers.styleWidth)
@@ -9,6 +9,7 @@ import {
9
9
  import Icon from "../Icon/Icon";
10
10
  import Tooltip, { TooltipProps } from "./../Tooltip/Tooltip";
11
11
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
12
+ import {ValidIconName} from "../Icon/canonicalIconNames";
12
13
 
13
14
  export type AnchorOrButtonProps = Omit<BlueprintButtonProps, "elementRef" | "icon" | "rightIcon"> | Omit<BlueprintAnchorButtonProps, "elementRef" | "icon" | "rightIcon">;
14
15
 
@@ -56,8 +57,8 @@ export interface ButtonProps extends React.HTMLAttributes<HTMLElement> {
56
57
  * If an URL is set then the button is included as HTML anchor element instead of a button form element.
57
58
  */
58
59
  href?: string;
59
- icon?: string | JSX.Element;
60
- rightIcon?: string | JSX.Element;
60
+ icon?: ValidIconName | JSX.Element;
61
+ rightIcon?: ValidIconName | JSX.Element;
61
62
  target?: string;
62
63
  }
63
64
 
@@ -3,6 +3,12 @@ import { CLASSPREFIX as eccgui } from "../../configuration/constants";
3
3
  import ContextOverlay from "./ContextOverlay";
4
4
  import Menu from "../Menu/Menu";
5
5
  import IconButton from "../Icon/IconButton";
6
+ import {ValidIconName} from "../Icon/canonicalIconNames";
7
+
8
+ interface ContextMenuProps {
9
+ togglerElement?: ValidIconName | JSX.Element
10
+ [key: string]: any
11
+ }
6
12
 
7
13
  function ContextMenu({
8
14
  children,
@@ -14,13 +20,13 @@ function ContextMenu({
14
20
  so by default we use the title attribute instead of Tooltip. */
15
21
  tooltipAsTitle = true,
16
22
  ...restProps
17
- }: any) {
23
+ }: ContextMenuProps) {
18
24
  return (
19
25
  <ContextOverlay {...restProps} className={`${eccgui}-contextmenu ` + className}>
20
26
  {typeof togglerElement === "string" ? (
21
27
  <IconButton
22
28
  tooltipAsTitle={tooltipAsTitle}
23
- name={togglerElement}
29
+ name={[togglerElement]}
24
30
  text={togglerText}
25
31
  large={togglerLarge}
26
32
  data-test-id={restProps["data-test-id"]}