@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.
- package/CHANGELOG.md +20 -4
- package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js +18 -14
- package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
- package/dist/cjs/cmem/ActivityControl/SilkActivityControl.js +58 -30
- package/dist/cjs/cmem/ActivityControl/SilkActivityControl.js.map +1 -1
- package/dist/cjs/cmem/ActivityControl/index.js +11 -0
- package/dist/cjs/cmem/ActivityControl/index.js.map +1 -0
- package/dist/cjs/cmem/ContentBlobToggler/index.js +8 -0
- package/dist/cjs/cmem/ContentBlobToggler/index.js.map +1 -0
- package/dist/cjs/cmem/index.js +14 -13
- package/dist/cjs/cmem/index.js.map +1 -1
- package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js +57 -0
- package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -0
- package/dist/cjs/cmem/react-flow/configuration/_colors-graph.module.scss +35 -0
- package/dist/cjs/cmem/react-flow/configuration/_colors-linking.module.scss +29 -0
- package/dist/cjs/cmem/react-flow/configuration/_colors-workflow.module.scss +22 -0
- package/dist/cjs/cmem/react-flow/configuration/graph.js +31 -0
- package/dist/cjs/cmem/react-flow/configuration/graph.js.map +1 -0
- package/dist/cjs/cmem/react-flow/configuration/linking.js +29 -0
- package/dist/cjs/cmem/react-flow/configuration/linking.js.map +1 -0
- package/dist/cjs/cmem/react-flow/configuration/unspecified.js +15 -0
- package/dist/cjs/cmem/react-flow/configuration/unspecified.js.map +1 -0
- package/dist/cjs/cmem/react-flow/configuration/workflow.js +27 -0
- package/dist/cjs/cmem/react-flow/configuration/workflow.js.map +1 -0
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js +285 -0
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js.map +1 -0
- package/dist/cjs/components/AutoSuggestion/AutoSuggestionList.js +81 -0
- package/dist/cjs/components/AutoSuggestion/AutoSuggestionList.js.map +1 -0
- package/dist/cjs/components/AutoSuggestion/SingleLineCodeEditor.js +46 -0
- package/dist/cjs/components/AutoSuggestion/SingleLineCodeEditor.js.map +1 -0
- package/dist/cjs/components/AutocompleteField/AutoCompleteField.js +8 -12
- package/dist/cjs/components/AutocompleteField/AutoCompleteField.js.map +1 -1
- package/dist/cjs/components/Button/Button.js.map +1 -1
- package/dist/cjs/components/ContextOverlay/ContextMenu.js +1 -1
- package/dist/cjs/components/ContextOverlay/ContextMenu.js.map +1 -1
- package/dist/cjs/components/Dialog/Modal.js +2 -2
- package/dist/cjs/components/Dialog/Modal.js.map +1 -1
- package/dist/cjs/components/Dialog/SimpleDialog.js.map +1 -1
- package/dist/cjs/components/Icon/Icon.js.map +1 -1
- package/dist/cjs/components/Icon/canonicalIconNames.js +30 -0
- package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/cjs/components/MultiSelect/MultiSelect.js +219 -0
- package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -0
- package/dist/cjs/components/Tabs/Tab.js +95 -0
- package/dist/cjs/components/Tabs/Tab.js.map +1 -0
- package/dist/cjs/components/Tabs/TabTitle.js +20 -0
- package/dist/cjs/components/Tabs/TabTitle.js.map +1 -0
- package/dist/cjs/components/Tabs/Tabs.js +29 -19
- package/dist/cjs/components/Tabs/Tabs.js.map +1 -1
- package/dist/cjs/components/Tag/Tag.js +7 -1
- package/dist/cjs/components/Tag/Tag.js.map +1 -1
- package/dist/cjs/extensions/react-flow/edges/utils.js +96 -4
- package/dist/cjs/extensions/react-flow/edges/utils.js.map +1 -1
- package/dist/cjs/extensions/react-flow/nodes/NodeContent.js +5 -4
- package/dist/cjs/extensions/react-flow/nodes/NodeContent.js.map +1 -1
- package/dist/cjs/extensions/react-flow/nodes/NodeContentExtension.js +2 -2
- package/dist/cjs/extensions/react-flow/nodes/NodeContentExtension.js.map +1 -1
- package/dist/cjs/extensions/react-flow/nodes/NodeTools.js.map +1 -1
- package/dist/cjs/index.js +17 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legacy-replacements/Button/AffirmativeButton.js +25 -0
- package/dist/cjs/legacy-replacements/Button/AffirmativeButton.js.map +1 -0
- package/dist/cjs/legacy-replacements/Button/Button.js +61 -0
- package/dist/cjs/legacy-replacements/Button/Button.js.map +1 -0
- package/dist/cjs/legacy-replacements/Button/DismissiveButton.js +25 -0
- package/dist/cjs/legacy-replacements/Button/DismissiveButton.js.map +1 -0
- package/dist/cjs/legacy-replacements/Button/DisruptiveButton.js +25 -0
- package/dist/cjs/legacy-replacements/Button/DisruptiveButton.js.map +1 -0
- package/dist/cjs/legacy-replacements/Checkbox/Checkbox.js +55 -0
- package/dist/cjs/legacy-replacements/Checkbox/Checkbox.js.map +1 -0
- package/dist/cjs/legacy-replacements/Radio/RadioButton.js +48 -0
- package/dist/cjs/legacy-replacements/Radio/RadioButton.js.map +1 -0
- package/dist/cjs/legacy-replacements/Tabs/Tabs.js +36 -0
- package/dist/cjs/legacy-replacements/Tabs/Tabs.js.map +1 -0
- package/dist/cjs/legacy-replacements/TextField/TextField.js +75 -0
- package/dist/cjs/legacy-replacements/TextField/TextField.js.map +1 -0
- package/dist/cjs/legacy-replacements/index.js +22 -0
- package/dist/cjs/legacy-replacements/index.js.map +1 -0
- package/dist/es5/cmem/ActivityControl/ActivityControlWidget.js +19 -15
- package/dist/es5/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
- package/dist/es5/cmem/ActivityControl/SilkActivityControl.js +56 -30
- package/dist/es5/cmem/ActivityControl/SilkActivityControl.js.map +1 -1
- package/dist/es5/cmem/ActivityControl/index.js +4 -0
- package/dist/es5/cmem/ActivityControl/index.js.map +1 -0
- package/dist/es5/cmem/ContentBlobToggler/index.js +3 -0
- package/dist/es5/cmem/ContentBlobToggler/index.js.map +1 -0
- package/dist/es5/cmem/index.js +6 -8
- package/dist/es5/cmem/index.js.map +1 -1
- package/dist/es5/cmem/react-flow/ReactFlow/ReactFlow.js +43 -0
- package/dist/es5/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -0
- package/dist/es5/cmem/react-flow/configuration/_colors-graph.module.scss +35 -0
- package/dist/es5/cmem/react-flow/configuration/_colors-linking.module.scss +29 -0
- package/dist/es5/cmem/react-flow/configuration/_colors-workflow.module.scss +22 -0
- package/dist/es5/cmem/react-flow/configuration/graph.js +23 -0
- package/dist/es5/cmem/react-flow/configuration/graph.js.map +1 -0
- package/dist/es5/cmem/react-flow/configuration/linking.js +21 -0
- package/dist/es5/cmem/react-flow/configuration/linking.js.map +1 -0
- package/dist/es5/cmem/react-flow/configuration/unspecified.js +12 -0
- package/dist/es5/cmem/react-flow/configuration/unspecified.js.map +1 -0
- package/dist/es5/cmem/react-flow/configuration/workflow.js +19 -0
- package/dist/es5/cmem/react-flow/configuration/workflow.js.map +1 -0
- package/dist/es5/components/AutoSuggestion/AutoSuggestion.js +347 -0
- package/dist/es5/components/AutoSuggestion/AutoSuggestion.js.map +1 -0
- package/dist/es5/components/AutoSuggestion/AutoSuggestionList.js +93 -0
- package/dist/es5/components/AutoSuggestion/AutoSuggestionList.js.map +1 -0
- package/dist/es5/components/AutoSuggestion/SingleLineCodeEditor.js +42 -0
- package/dist/es5/components/AutoSuggestion/SingleLineCodeEditor.js.map +1 -0
- package/dist/es5/components/AutocompleteField/AutoCompleteField.js +8 -12
- package/dist/es5/components/AutocompleteField/AutoCompleteField.js.map +1 -1
- package/dist/es5/components/Button/Button.js.map +1 -1
- package/dist/es5/components/ContextOverlay/ContextMenu.js +1 -1
- package/dist/es5/components/ContextOverlay/ContextMenu.js.map +1 -1
- package/dist/es5/components/Dialog/Modal.js +2 -2
- package/dist/es5/components/Dialog/Modal.js.map +1 -1
- package/dist/es5/components/Dialog/SimpleDialog.js.map +1 -1
- package/dist/es5/components/Icon/Icon.js.map +1 -1
- package/dist/es5/components/Icon/canonicalIconNames.js +30 -0
- package/dist/es5/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/es5/components/MultiSelect/MultiSelect.js +301 -0
- package/dist/es5/components/MultiSelect/MultiSelect.js.map +1 -0
- package/dist/es5/components/Tabs/Tab.js +98 -0
- package/dist/es5/components/Tabs/Tab.js.map +1 -0
- package/dist/es5/components/Tabs/TabTitle.js +16 -0
- package/dist/es5/components/Tabs/TabTitle.js.map +1 -0
- package/dist/es5/components/Tabs/Tabs.js +11 -21
- package/dist/es5/components/Tabs/Tabs.js.map +1 -1
- package/dist/es5/components/Tag/Tag.js +7 -1
- package/dist/es5/components/Tag/Tag.js.map +1 -1
- package/dist/es5/extensions/react-flow/edges/utils.js +99 -5
- package/dist/es5/extensions/react-flow/edges/utils.js.map +1 -1
- package/dist/es5/extensions/react-flow/nodes/NodeContent.js +21 -4
- package/dist/es5/extensions/react-flow/nodes/NodeContent.js.map +1 -1
- package/dist/es5/extensions/react-flow/nodes/NodeContentExtension.js +2 -2
- package/dist/es5/extensions/react-flow/nodes/NodeContentExtension.js.map +1 -1
- package/dist/es5/extensions/react-flow/nodes/NodeTools.js.map +1 -1
- package/dist/es5/index.js +9 -2
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/legacy-replacements/Button/AffirmativeButton.js +29 -0
- package/dist/es5/legacy-replacements/Button/AffirmativeButton.js.map +1 -0
- package/dist/es5/legacy-replacements/Button/Button.js +65 -0
- package/dist/es5/legacy-replacements/Button/Button.js.map +1 -0
- package/dist/es5/legacy-replacements/Button/DismissiveButton.js +29 -0
- package/dist/es5/legacy-replacements/Button/DismissiveButton.js.map +1 -0
- package/dist/es5/legacy-replacements/Button/DisruptiveButton.js +29 -0
- package/dist/es5/legacy-replacements/Button/DisruptiveButton.js.map +1 -0
- package/dist/es5/legacy-replacements/Checkbox/Checkbox.js +59 -0
- package/dist/es5/legacy-replacements/Checkbox/Checkbox.js.map +1 -0
- package/dist/es5/legacy-replacements/Radio/RadioButton.js +52 -0
- package/dist/es5/legacy-replacements/Radio/RadioButton.js.map +1 -0
- package/dist/es5/legacy-replacements/Tabs/Tabs.js +40 -0
- package/dist/es5/legacy-replacements/Tabs/Tabs.js.map +1 -0
- package/dist/es5/legacy-replacements/TextField/TextField.js +81 -0
- package/dist/es5/legacy-replacements/TextField/TextField.js.map +1 -0
- package/dist/es5/legacy-replacements/index.js +10 -0
- package/dist/es5/legacy-replacements/index.js.map +1 -0
- package/dist/types/cmem/ActivityControl/ActivityControlTypes.d.ts +2 -1
- package/dist/types/cmem/ActivityControl/ActivityControlWidget.d.ts +39 -2
- package/dist/types/cmem/ActivityControl/SilkActivityControl.d.ts +16 -3
- package/dist/types/cmem/ActivityControl/index.d.ts +3 -0
- package/dist/types/cmem/ContentBlobToggler/index.d.ts +2 -0
- package/dist/types/cmem/index.d.ts +8 -8
- package/dist/types/cmem/react-flow/ReactFlow/ReactFlow.d.ts +14 -0
- package/dist/types/cmem/react-flow/configuration/graph.d.ts +21 -0
- package/dist/types/cmem/react-flow/configuration/linking.d.ts +19 -0
- package/dist/types/cmem/react-flow/configuration/unspecified.d.ts +9 -0
- package/dist/types/cmem/react-flow/configuration/workflow.d.ts +17 -0
- package/dist/types/components/AutoSuggestion/AutoSuggestion.d.ts +67 -0
- package/dist/types/components/AutoSuggestion/AutoSuggestionList.d.ts +13 -0
- package/dist/types/components/AutoSuggestion/SingleLineCodeEditor.d.ts +25 -0
- package/dist/types/components/AutocompleteField/AutoCompleteField.d.ts +8 -7
- package/dist/types/components/Button/Button.d.ts +3 -2
- package/dist/types/components/ContextOverlay/ContextMenu.d.ts +6 -1
- package/dist/types/components/Dialog/Modal.d.ts +4 -3
- package/dist/types/components/Dialog/SimpleDialog.d.ts +2 -0
- package/dist/types/components/Icon/Icon.d.ts +2 -2
- package/dist/types/components/Icon/IconButton.d.ts +1 -1
- package/dist/types/components/Icon/canonicalIconNames.d.ts +1 -1
- package/dist/types/components/MultiSelect/MultiSelect.d.ts +79 -0
- package/dist/types/components/Tabs/Tab.d.ts +549 -0
- package/dist/types/components/Tabs/TabTitle.d.ts +38 -0
- package/dist/types/components/Tabs/Tabs.d.ts +14 -20
- package/dist/types/components/Tag/Tag.d.ts +1 -1
- package/dist/types/extensions/react-flow/edges/utils.d.ts +1 -1
- package/dist/types/extensions/react-flow/nodes/NodeContent.d.ts +8 -8
- package/dist/types/extensions/react-flow/nodes/NodeDefault.d.ts +2 -2
- package/dist/types/extensions/react-flow/nodes/NodeTools.d.ts +2 -1
- package/dist/types/extensions/react-flow/nodes/nodeTypes.d.ts +10 -10
- package/dist/types/index.d.ts +9 -2
- package/dist/types/legacy-replacements/Button/AffirmativeButton.d.ts +2 -0
- package/dist/types/legacy-replacements/Button/Button.d.ts +5 -0
- package/dist/types/legacy-replacements/Button/DismissiveButton.d.ts +2 -0
- package/dist/types/legacy-replacements/Button/DisruptiveButton.d.ts +2 -0
- package/dist/types/legacy-replacements/Checkbox/Checkbox.d.ts +2 -0
- package/dist/types/legacy-replacements/Radio/RadioButton.d.ts +2 -0
- package/dist/types/legacy-replacements/Tabs/Tabs.d.ts +22 -0
- package/dist/types/legacy-replacements/TextField/TextField.d.ts +2 -0
- package/dist/types/legacy-replacements/index.d.ts +10 -0
- package/package.json +16 -7
- package/src/cmem/ActivityControl/ActivityControlTypes.ts +3 -1
- package/src/cmem/ActivityControl/ActivityControlWidget.stories.tsx +98 -0
- package/src/cmem/ActivityControl/ActivityControlWidget.tsx +131 -89
- package/src/cmem/ActivityControl/SilkActivityControl.tsx +178 -120
- package/src/cmem/ActivityControl/index.ts +3 -0
- package/src/cmem/ContentBlobToggler/index.ts +2 -0
- package/src/cmem/_index.scss +6 -0
- package/src/cmem/index.ts +10 -23
- package/src/cmem/react-flow/ReactFlow/ReactFlow.stories.tsx +222 -0
- package/src/cmem/react-flow/ReactFlow/ReactFlow.tsx +40 -0
- package/src/cmem/react-flow/_edges.scss +23 -0
- package/src/cmem/react-flow/_handles.scss +34 -0
- package/src/cmem/react-flow/_index.scss +5 -0
- package/src/cmem/react-flow/_minimap.scss +33 -0
- package/src/cmem/react-flow/_nodes.scss +60 -0
- package/src/cmem/react-flow/configuration/_colors-graph.module.scss +35 -0
- package/src/cmem/react-flow/configuration/_colors-linking.module.scss +29 -0
- package/src/cmem/react-flow/configuration/_colors-workflow.module.scss +22 -0
- package/src/cmem/react-flow/configuration/_colors.scss +3 -0
- package/src/cmem/react-flow/configuration/graph.ts +29 -0
- package/src/cmem/react-flow/configuration/linking.ts +28 -0
- package/src/cmem/react-flow/configuration/unspecified.ts +13 -0
- package/src/cmem/react-flow/configuration/workflow.ts +25 -0
- package/src/components/AutoSuggestion/AutoSuggestion.scss +100 -0
- package/src/components/AutoSuggestion/AutoSuggestion.tsx +447 -0
- package/src/components/AutoSuggestion/AutoSuggestionList.tsx +170 -0
- package/src/components/AutoSuggestion/SingleLineCodeEditor.tsx +97 -0
- package/src/components/AutoSuggestion/tests/AutoSuggestion.test.tsx +37 -0
- package/src/components/AutoSuggestion/tests/AutoSuggestionList.test.tsx +124 -0
- package/src/components/AutoSuggestion/tests/SingleLineCodeEditor.test.tsx +55 -0
- package/src/components/AutocompleteField/AutoCompleteField.tsx +19 -19
- package/src/components/AutocompleteField/autoCompleteFieldUtils.tsx +2 -1
- package/src/components/Button/Button.tsx +3 -2
- package/src/components/ContextOverlay/ContextMenu.tsx +8 -2
- package/src/components/Dialog/Modal.tsx +9 -2
- package/src/components/Dialog/SimpleDialog.tsx +2 -0
- package/src/components/Icon/Icon.tsx +4 -4
- package/src/components/Icon/IconButton.tsx +1 -1
- package/src/components/Icon/canonicalIconNames.tsx +39 -2
- package/src/components/MultiSelect/MultiSelect.stories.tsx +63 -0
- package/src/components/MultiSelect/MultiSelect.tsx +370 -0
- package/src/components/Tabs/Tab.tsx +112 -0
- package/src/components/Tabs/TabTitle.tsx +71 -0
- package/src/components/Tabs/Tabs.tsx +26 -90
- package/src/components/Tabs/stories/Tab.stories.tsx +65 -0
- package/src/components/Tabs/stories/TabTitle.stories.tsx +35 -0
- package/src/components/Tabs/stories/Tabs.stories.tsx +98 -0
- package/src/components/Tabs/tabs.scss +11 -4
- package/src/components/Tag/Tag.tsx +10 -3
- package/src/components/Tag/tag.scss +1 -1
- package/src/components/TextField/TextField.tsx +1 -1
- package/src/configuration/_variables.scss +3 -3
- package/src/extensions/react-flow/_config.scss +2 -2
- package/src/extensions/react-flow/edges/_edges.scss +3 -28
- package/src/extensions/react-flow/edges/utils.ts +139 -4
- package/src/extensions/react-flow/handles/_handles.scss +4 -58
- package/src/extensions/react-flow/minimap/_minimap.scss +0 -45
- package/src/extensions/react-flow/nodes/NodeContent.tsx +134 -133
- package/src/extensions/react-flow/nodes/NodeContentExtension.tsx +11 -10
- package/src/extensions/react-flow/nodes/NodeDefault.tsx +2 -2
- package/src/extensions/react-flow/nodes/NodeTools.tsx +2 -1
- package/src/extensions/react-flow/nodes/_nodes.scss +31 -185
- package/src/extensions/react-flow/nodes/{NodeContent.stories.tsx → stories/NodeContent.stories.tsx} +4 -4
- package/src/extensions/react-flow/nodes/{NodeContentExtension.stories.tsx → stories/NodeContentExtension.stories.tsx} +4 -4
- package/src/extensions/react-flow/nodes/{NodeDefault.stories.tsx → stories/NodeDefault.stories.tsx} +5 -4
- package/src/index.scss +1 -0
- package/src/index.ts +16 -1
- package/src/legacy-replacements/Tabs/Tabs.stories.tsx +46 -0
- package/src/legacy-replacements/Tabs/Tabs.tsx +84 -0
- package/src/legacy-replacements/index.ts +11 -0
- package/src/test/setupTests.js +19 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
//@import "~@eccenca/gui-elements/src/configuration.default";
|
|
2
|
+
|
|
3
|
+
.ecc-auto-suggestion-box {
|
|
4
|
+
position: relative;
|
|
5
|
+
|
|
6
|
+
&__dropdown {
|
|
7
|
+
transition: all 300ms;
|
|
8
|
+
// TODO: Replace by variable
|
|
9
|
+
background-color: #fff;
|
|
10
|
+
position: absolute;
|
|
11
|
+
top: $eccgui-size-textfield-height-regular;
|
|
12
|
+
z-index:2;
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-flow: column wrap;
|
|
15
|
+
margin-top: 0;
|
|
16
|
+
max-width: 25rem;
|
|
17
|
+
max-height: 30rem;
|
|
18
|
+
// TODO: was: 1px solid $list-container-item-border-color
|
|
19
|
+
border: 1px solid;
|
|
20
|
+
border-radius: 0.3rem;
|
|
21
|
+
overflow-x:hidden;
|
|
22
|
+
overflow-y: auto;
|
|
23
|
+
|
|
24
|
+
.#{$ns}-menu, .#{$eccgui}-overviewitem__item {
|
|
25
|
+
max-width: 24rem;
|
|
26
|
+
box-sizing: border-box;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ecc-input-editor {
|
|
32
|
+
position: relative;
|
|
33
|
+
|
|
34
|
+
.CodeMirror {
|
|
35
|
+
height: calc(#{$eccgui-size-textfield-height-regular} - 4px);
|
|
36
|
+
margin: 0;
|
|
37
|
+
padding: 0;
|
|
38
|
+
top: 2px;
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.CodeMirror-scroll {
|
|
43
|
+
margin: 0;
|
|
44
|
+
padding: 0;
|
|
45
|
+
overflow-y: hidden !important;
|
|
46
|
+
overflow-x: auto !important;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.CodeMirror-vscrollbar {
|
|
50
|
+
display: none !important;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.CodeMirror-sizer {
|
|
54
|
+
border: none;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.CodeMirror-lines {
|
|
58
|
+
padding: 0;
|
|
59
|
+
line-height: calc(#{$eccgui-size-textfield-height-regular} - 4px - 6px);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
pre.CodeMirror-line {
|
|
63
|
+
font-family: $eccgui-font-family-monospace;
|
|
64
|
+
font-size: 0.9em;
|
|
65
|
+
padding: 3px 0;
|
|
66
|
+
height: calc(#{$eccgui-size-textfield-height-regular} - 4px - 6px);
|
|
67
|
+
box-sizing: content-box;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.CodeMirror-cursor {
|
|
71
|
+
border: none;
|
|
72
|
+
margin: 0;
|
|
73
|
+
width: 1px;
|
|
74
|
+
background-color: transparent;
|
|
75
|
+
|
|
76
|
+
&::after {
|
|
77
|
+
content: " ";
|
|
78
|
+
height: 1rem;
|
|
79
|
+
width: 1px;
|
|
80
|
+
overflow: hidden;
|
|
81
|
+
background-color: black;
|
|
82
|
+
position: absolute;
|
|
83
|
+
top: 50%;
|
|
84
|
+
right: 0;
|
|
85
|
+
margin-top: -0.5rem;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.ecc-text-highlighting {
|
|
91
|
+
display: inline-block;
|
|
92
|
+
background-color: $eccgui-color-warning-background;
|
|
93
|
+
color:$eccgui-color-warning-text;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.ecc-text-error-highlighting {
|
|
97
|
+
background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==");
|
|
98
|
+
background-position: left bottom;
|
|
99
|
+
background-repeat: repeat-x;
|
|
100
|
+
}
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import React, {useCallback, useEffect, useState} from "react";
|
|
2
|
+
import CodeMirror from "codemirror";
|
|
3
|
+
import {FieldItem, IconButton, Spinner, Toolbar, ToolbarSection} from "./../../";
|
|
4
|
+
import {Classes as BlueprintClassNames} from "@blueprintjs/core";
|
|
5
|
+
|
|
6
|
+
//custom components
|
|
7
|
+
import SingleLineCodeEditor, {IRange} from "./SingleLineCodeEditor";
|
|
8
|
+
import {AutoSuggestionList} from "./AutoSuggestionList";
|
|
9
|
+
import {debounce} from "lodash";
|
|
10
|
+
|
|
11
|
+
export enum OVERWRITTEN_KEYS {
|
|
12
|
+
ArrowUp = "ArrowUp",
|
|
13
|
+
ArrowDown = "ArrowDown",
|
|
14
|
+
Enter = "Enter",
|
|
15
|
+
Tab = "Tab",
|
|
16
|
+
}
|
|
17
|
+
export type OverwrittenKeyTypes = typeof OVERWRITTEN_KEYS[keyof typeof OVERWRITTEN_KEYS];
|
|
18
|
+
|
|
19
|
+
/** A single suggestion. */
|
|
20
|
+
export interface ISuggestionBase {
|
|
21
|
+
// The actual value
|
|
22
|
+
value: string
|
|
23
|
+
// Optional human-readable label
|
|
24
|
+
label?: string
|
|
25
|
+
// Optional description of the value.
|
|
26
|
+
description?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Same as ISuggestionBase, but with the query that was used to fetch this suggestion. */
|
|
30
|
+
export interface ISuggestionWithReplacementInfo extends ISuggestionBase {
|
|
31
|
+
// The query this result was filtered by
|
|
32
|
+
query: string
|
|
33
|
+
// The offset of the original string that should be replaced
|
|
34
|
+
from: number
|
|
35
|
+
// The length of the original string that should be replaced
|
|
36
|
+
length: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The suggestions for a specific substring of the given input string. */
|
|
40
|
+
export interface IReplacementResult {
|
|
41
|
+
// The range of the input string that should be replaced
|
|
42
|
+
replacementInterval: {
|
|
43
|
+
from: number
|
|
44
|
+
length: number
|
|
45
|
+
}
|
|
46
|
+
// The extracted query from the local value at the cursor position of the path that was used to retrieve the suggestions.
|
|
47
|
+
extractedQuery: string
|
|
48
|
+
// The suggested replacements for the substring that should be replaced.
|
|
49
|
+
replacements: ISuggestionBase[]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface IPartialAutoCompleteResult {
|
|
53
|
+
// Repeats the input string from the corresponding request
|
|
54
|
+
inputString: string
|
|
55
|
+
// Repeats the cursor position from the corresponding request
|
|
56
|
+
cursorPosition: number
|
|
57
|
+
replacementResults: IReplacementResult[]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Validation result */
|
|
61
|
+
export interface IValidationResult {
|
|
62
|
+
// If the input value is valid or not
|
|
63
|
+
valid: boolean,
|
|
64
|
+
parseError?: {
|
|
65
|
+
// Detail error message
|
|
66
|
+
message: string
|
|
67
|
+
// Start of the parse error in the input string
|
|
68
|
+
start: number
|
|
69
|
+
// End of the parse error in the input string
|
|
70
|
+
end: number
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface IProps {
|
|
75
|
+
// Optional label to be shown for the input (above). This will create a FieldItem around the input.
|
|
76
|
+
label?: string
|
|
77
|
+
// The value the component is initialized with, do not use this to control value changes.
|
|
78
|
+
initialValue: string
|
|
79
|
+
// Callback on value change
|
|
80
|
+
onChange: (currentValue: string) => any
|
|
81
|
+
// Fetches the suggestions
|
|
82
|
+
fetchSuggestions: (inputString: string, cursorPosition: number) => (IPartialAutoCompleteResult | undefined) | Promise<IPartialAutoCompleteResult | undefined>
|
|
83
|
+
// Checks if the input is valid
|
|
84
|
+
checkInput?: (inputString: string) => IValidationResult | Promise<IValidationResult | undefined>
|
|
85
|
+
// Called with the input validation result
|
|
86
|
+
onInputChecked?: (validInput: boolean) => any
|
|
87
|
+
// Text that should be shown if the input validation failed.
|
|
88
|
+
validationErrorText?: string
|
|
89
|
+
// Text that should be shown when hovering over the clear icon
|
|
90
|
+
clearIconText?: string
|
|
91
|
+
// Called when focus status changes
|
|
92
|
+
onFocusChange?: (hasFocus: boolean) => any
|
|
93
|
+
// Optional ID to attach to the outer element
|
|
94
|
+
id?: string
|
|
95
|
+
// If the <Tab> key should be used for auto-completing items. Else it will have its default behavior.
|
|
96
|
+
useTabForCompletions?: boolean
|
|
97
|
+
/** An additional element that is put to the left side of the input field */
|
|
98
|
+
leftElement?: JSX.Element | null
|
|
99
|
+
// An additional element that is put to the right side of the input field
|
|
100
|
+
rightElement?: JSX.Element | null
|
|
101
|
+
/** Placeholder tobe shown when no text has been entered, yet. */
|
|
102
|
+
placeholder?: string
|
|
103
|
+
/** If the horizontal scrollbars should be shown. */
|
|
104
|
+
showScrollBar?: boolean
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Input component that allows partial, fine-grained auto-completion, i.e. of sub-strings of the input string.
|
|
108
|
+
* This is comparable to a one line code editor. */
|
|
109
|
+
const AutoSuggestion = ({
|
|
110
|
+
label,
|
|
111
|
+
initialValue,
|
|
112
|
+
onChange,
|
|
113
|
+
fetchSuggestions,
|
|
114
|
+
checkInput,
|
|
115
|
+
validationErrorText = "Invalid value",
|
|
116
|
+
clearIconText = "Clear",
|
|
117
|
+
onFocusChange,
|
|
118
|
+
id,
|
|
119
|
+
onInputChecked,
|
|
120
|
+
leftElement,
|
|
121
|
+
rightElement,
|
|
122
|
+
useTabForCompletions = false,
|
|
123
|
+
placeholder,
|
|
124
|
+
showScrollBar = true
|
|
125
|
+
}: IProps) => {
|
|
126
|
+
const [value, setValue] = React.useState(initialValue);
|
|
127
|
+
const [cursorPosition, setCursorPosition] = React.useState(0);
|
|
128
|
+
const [coords, setCoords] = React.useState({left: 0});
|
|
129
|
+
const [shouldShowDropdown, setShouldShowDropdown] = React.useState(false);
|
|
130
|
+
const [suggestions, setSuggestions] = React.useState<ISuggestionWithReplacementInfo[]>([]);
|
|
131
|
+
const [suggestionsPending, setSuggestionsPending] = React.useState(false);
|
|
132
|
+
const [pathValidationPending, setPathValidationPending] = React.useState(false)
|
|
133
|
+
const [, setErrorMarkers] = React.useState<CodeMirror.TextMarker[]>([]);
|
|
134
|
+
const [validationResponse, setValidationResponse] = useState<IValidationResult | undefined>(undefined)
|
|
135
|
+
const [suggestionResponse, setSuggestionResponse] = useState<IPartialAutoCompleteResult | undefined>(undefined)
|
|
136
|
+
// The element that should be used for replacement highlighting
|
|
137
|
+
const [highlightedElement, setHighlightedElement] = useState<ISuggestionWithReplacementInfo | undefined>(undefined)
|
|
138
|
+
const [editorInstance, setEditorInstance] = React.useState<CodeMirror.Editor>();
|
|
139
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
140
|
+
/** Mutable editor state, since this needs to be current in scope of the SingleLineEditorComponent. */
|
|
141
|
+
const [editorState] = React.useState<{
|
|
142
|
+
index: number,
|
|
143
|
+
suggestions: ISuggestionWithReplacementInfo[],
|
|
144
|
+
editorInstance?: CodeMirror.Editor,
|
|
145
|
+
dropdownShown: boolean
|
|
146
|
+
}>({index: 0, suggestions: [], dropdownShown: false})
|
|
147
|
+
/** This is for the AutoSuggestionList component in order to re-render. */
|
|
148
|
+
const [focusedIndex, setFocusedIndex] = React.useState(0)
|
|
149
|
+
const [selectedTextRanges, setSelectedTextRanges] = useState<IRange[]>([])
|
|
150
|
+
|
|
151
|
+
const pathIsValid = validationResponse?.valid ?? true;
|
|
152
|
+
|
|
153
|
+
const setCurrentIndex = (newIndex: number) => {
|
|
154
|
+
editorState.index = newIndex
|
|
155
|
+
setFocusedIndex(newIndex)
|
|
156
|
+
}
|
|
157
|
+
const currentIndex = () => editorState.index
|
|
158
|
+
|
|
159
|
+
React.useEffect(() => {
|
|
160
|
+
editorState.editorInstance = editorInstance
|
|
161
|
+
}, [editorInstance, editorState])
|
|
162
|
+
|
|
163
|
+
React.useEffect(() => {
|
|
164
|
+
setValue(initialValue)
|
|
165
|
+
}, [initialValue])
|
|
166
|
+
|
|
167
|
+
React.useEffect(() => {
|
|
168
|
+
editorState.dropdownShown = shouldShowDropdown
|
|
169
|
+
}, [shouldShowDropdown, editorState])
|
|
170
|
+
|
|
171
|
+
// Handle replacement highlighting
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (highlightedElement && editorInstance) {
|
|
174
|
+
const { from, length } = highlightedElement;
|
|
175
|
+
if(length > 0 && selectedTextRanges.length === 0) {
|
|
176
|
+
const to = from + length;
|
|
177
|
+
const marker = editorInstance.markText(
|
|
178
|
+
{line: 0, ch: from},
|
|
179
|
+
{line: 0, ch: to},
|
|
180
|
+
{className: "ecc-text-highlighting"}
|
|
181
|
+
);
|
|
182
|
+
return () => marker.clear()
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}, [highlightedElement, selectedTextRanges, editorInstance])
|
|
186
|
+
|
|
187
|
+
//handle linting
|
|
188
|
+
React.useEffect(() => {
|
|
189
|
+
const parseError = validationResponse?.parseError;
|
|
190
|
+
if (parseError && editorInstance) {
|
|
191
|
+
const { message, start, end } = parseError;
|
|
192
|
+
// TODO: Display error message
|
|
193
|
+
editorInstance.getDoc().getEditor()
|
|
194
|
+
const marker = editorInstance.markText(
|
|
195
|
+
{ line: 0, ch: start },
|
|
196
|
+
{ line: 0, ch: end },
|
|
197
|
+
{ className: "ecc-text-error-highlighting", title: message }
|
|
198
|
+
);
|
|
199
|
+
setErrorMarkers((previousMarkers) => {
|
|
200
|
+
previousMarkers.forEach(marker => marker.clear())
|
|
201
|
+
return [marker]
|
|
202
|
+
});
|
|
203
|
+
} else {
|
|
204
|
+
// Valid, clear all error markers
|
|
205
|
+
setErrorMarkers((previous) => {
|
|
206
|
+
previous.forEach(marker => marker.clear())
|
|
207
|
+
return []
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
onInputChecked && onInputChecked(!!validationResponse?.valid)
|
|
211
|
+
}, [validationResponse?.valid, validationResponse?.parseError, editorInstance, onInputChecked]);
|
|
212
|
+
|
|
213
|
+
/** generate suggestions and also populate the replacement indexes dict */
|
|
214
|
+
React.useEffect(() => {
|
|
215
|
+
let newSuggestions: ISuggestionWithReplacementInfo[] = [];
|
|
216
|
+
if (
|
|
217
|
+
suggestionResponse?.replacementResults?.length === 1 &&
|
|
218
|
+
!suggestionResponse?.replacementResults[0]?.replacements?.length
|
|
219
|
+
) {
|
|
220
|
+
setShouldShowDropdown(false);
|
|
221
|
+
}
|
|
222
|
+
if (suggestionResponse?.replacementResults?.length) {
|
|
223
|
+
suggestionResponse.replacementResults.forEach(
|
|
224
|
+
({ replacements, replacementInterval: { from, length }, extractedQuery }) => {
|
|
225
|
+
const replacementsWithMetaData = replacements.map(r => ({...r, query: extractedQuery, from, length}))
|
|
226
|
+
newSuggestions = [...newSuggestions, ...replacementsWithMetaData];
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
editorState.suggestions = newSuggestions
|
|
230
|
+
setSuggestions(newSuggestions);
|
|
231
|
+
} else {
|
|
232
|
+
editorState.suggestions = []
|
|
233
|
+
setSuggestions([])
|
|
234
|
+
}
|
|
235
|
+
editorState.index = 0
|
|
236
|
+
}, [suggestionResponse, editorState]);
|
|
237
|
+
|
|
238
|
+
const asyncCheckInput = async (inputString: string) => {
|
|
239
|
+
if(!checkInput) {
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
setPathValidationPending(true)
|
|
243
|
+
try {
|
|
244
|
+
const result: IValidationResult | undefined = await checkInput(inputString)
|
|
245
|
+
setValidationResponse(result)
|
|
246
|
+
} catch(e) {
|
|
247
|
+
setValidationResponse(undefined)
|
|
248
|
+
// TODO: Error handling
|
|
249
|
+
} finally {
|
|
250
|
+
setPathValidationPending(false)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const checkValuePathValidity = useCallback(
|
|
255
|
+
debounce((inputString: string) => asyncCheckInput(inputString), 200),
|
|
256
|
+
[checkInput]
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
const handleEditorInputChange = useCallback(
|
|
260
|
+
debounce((inputString: string, cursorPosition: number) => asyncHandleEditorInputChange(inputString, cursorPosition), 200),
|
|
261
|
+
[fetchSuggestions]
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
React.useEffect(() => {
|
|
265
|
+
if (isFocused) {
|
|
266
|
+
setShouldShowDropdown(true);
|
|
267
|
+
handleEditorInputChange(value, cursorPosition)
|
|
268
|
+
return handleEditorInputChange.cancel
|
|
269
|
+
}
|
|
270
|
+
}, [cursorPosition, value, isFocused, handleEditorInputChange]);
|
|
271
|
+
|
|
272
|
+
// Trigger input validation
|
|
273
|
+
useEffect(() => {
|
|
274
|
+
checkValuePathValidity(value)
|
|
275
|
+
return checkValuePathValidity.cancel
|
|
276
|
+
}, [value, checkValuePathValidity])
|
|
277
|
+
|
|
278
|
+
const asyncHandleEditorInputChange = async (inputString: string, cursorPosition: number) => {
|
|
279
|
+
setSuggestionsPending(true)
|
|
280
|
+
try {
|
|
281
|
+
const result: IPartialAutoCompleteResult | undefined = await fetchSuggestions(inputString, cursorPosition)
|
|
282
|
+
setSuggestionResponse(result)
|
|
283
|
+
} catch(e) {
|
|
284
|
+
setSuggestionResponse(undefined)
|
|
285
|
+
// TODO: Error handling
|
|
286
|
+
} finally {
|
|
287
|
+
setSuggestionsPending(false)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const handleChange = (val: string) => {
|
|
292
|
+
setValue(val);
|
|
293
|
+
onChange(val)
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const handleCursorChange = (pos: any, coords: any) => {
|
|
297
|
+
setCursorPosition(pos.ch);
|
|
298
|
+
setCoords(() => coords);
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const handleInputEditorKeyPress = (event: KeyboardEvent) => {
|
|
302
|
+
const overWrittenKeys: Array<string> = Object.values(OVERWRITTEN_KEYS);
|
|
303
|
+
if (overWrittenKeys.includes(event.key) && (useTabForCompletions || event.key !== OVERWRITTEN_KEYS.Tab)) {
|
|
304
|
+
event.preventDefault();
|
|
305
|
+
makeDropDownRespondToKeyPress(OVERWRITTEN_KEYS[event.key as keyof typeof OVERWRITTEN_KEYS]);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const closeDropDown = () => {
|
|
310
|
+
setHighlightedElement(undefined)
|
|
311
|
+
setShouldShowDropdown(false)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const handleDropdownChange = (selectedSuggestion: ISuggestionWithReplacementInfo) => {
|
|
315
|
+
if (selectedSuggestion && editorState.editorInstance) {
|
|
316
|
+
const { from, length, value } = selectedSuggestion;
|
|
317
|
+
const to = from + length;
|
|
318
|
+
editorState.editorInstance.replaceRange(selectedSuggestion.value, {line: 0, ch: from}, {line: 0, ch: to})
|
|
319
|
+
closeDropDown()
|
|
320
|
+
editorState.editorInstance.setCursor({ line: 0, ch: from + value.length });
|
|
321
|
+
editorState.editorInstance.focus();
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const handleInputEditorClear = () => {
|
|
326
|
+
handleChange("");
|
|
327
|
+
setValue("")
|
|
328
|
+
editorInstance?.focus();
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const handleInputFocus = (focusState: boolean) => {
|
|
332
|
+
onFocusChange && onFocusChange(focusState)
|
|
333
|
+
setIsFocused(focusState)
|
|
334
|
+
focusState ? setShouldShowDropdown(true) : closeDropDown()
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
//keyboard handlers
|
|
338
|
+
const handleArrowDown = () => {
|
|
339
|
+
const lastSuggestionIndex = editorState.suggestions.length - 1;
|
|
340
|
+
setCurrentIndex(currentIndex() === lastSuggestionIndex ? 0 : currentIndex() + 1)
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
const handleArrowUp = () => {
|
|
344
|
+
const lastSuggestionIndex = editorState.suggestions.length - 1;
|
|
345
|
+
setCurrentIndex(currentIndex() === 0 ? lastSuggestionIndex : currentIndex() - 1)
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
const handleEnterPressed = () => {
|
|
349
|
+
handleDropdownChange(editorState.suggestions[currentIndex()]);
|
|
350
|
+
setCurrentIndex(0);
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const handleTabPressed = () => {
|
|
354
|
+
handleDropdownChange(editorState.suggestions[currentIndex()]);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const makeDropDownRespondToKeyPress = (keyPressedFromInput: OverwrittenKeyTypes) => {
|
|
358
|
+
// React state unknown
|
|
359
|
+
if (editorState.dropdownShown) {
|
|
360
|
+
switch (keyPressedFromInput) {
|
|
361
|
+
case OVERWRITTEN_KEYS.ArrowUp:
|
|
362
|
+
handleArrowUp();
|
|
363
|
+
break;
|
|
364
|
+
case OVERWRITTEN_KEYS.ArrowDown:
|
|
365
|
+
handleArrowDown();
|
|
366
|
+
break;
|
|
367
|
+
case OVERWRITTEN_KEYS.Enter:
|
|
368
|
+
handleEnterPressed();
|
|
369
|
+
break;
|
|
370
|
+
case OVERWRITTEN_KEYS.Tab:
|
|
371
|
+
handleTabPressed();
|
|
372
|
+
break;
|
|
373
|
+
default:
|
|
374
|
+
//do nothing
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const handleItemHighlighting = React.useCallback((item: ISuggestionWithReplacementInfo | undefined) => {
|
|
380
|
+
setHighlightedElement(item)
|
|
381
|
+
}, [])
|
|
382
|
+
|
|
383
|
+
const hasError = !!value && !pathIsValid && !pathValidationPending;
|
|
384
|
+
const autoSuggestionInput = <div id={id} className="ecc-auto-suggestion-box">
|
|
385
|
+
<div className={`ecc-auto-suggestion-box__editor-box ${BlueprintClassNames.INPUT_GROUP} ${BlueprintClassNames.FILL} ${hasError ? BlueprintClassNames.INTENT_DANGER : ""}`}>
|
|
386
|
+
<SingleLineCodeEditor
|
|
387
|
+
mode="null"
|
|
388
|
+
setEditorInstance={setEditorInstance}
|
|
389
|
+
onChange={handleChange}
|
|
390
|
+
onCursorChange={handleCursorChange}
|
|
391
|
+
initialValue={value}
|
|
392
|
+
onFocusChange={handleInputFocus}
|
|
393
|
+
onKeyDown={handleInputEditorKeyPress}
|
|
394
|
+
enableTab={useTabForCompletions}
|
|
395
|
+
placeholder={placeholder}
|
|
396
|
+
onSelection={setSelectedTextRanges}
|
|
397
|
+
showScrollBar={showScrollBar}
|
|
398
|
+
/>
|
|
399
|
+
{!!value && (
|
|
400
|
+
<span className={BlueprintClassNames.INPUT_ACTION}>
|
|
401
|
+
<IconButton
|
|
402
|
+
data-test-id={"value-path-clear-btn"}
|
|
403
|
+
name="operation-clear"
|
|
404
|
+
text={clearIconText}
|
|
405
|
+
onClick={handleInputEditorClear}
|
|
406
|
+
/>
|
|
407
|
+
</span>
|
|
408
|
+
)}
|
|
409
|
+
</div>
|
|
410
|
+
{shouldShowDropdown ? <AutoSuggestionList
|
|
411
|
+
left={coords.left}
|
|
412
|
+
loading={suggestionsPending}
|
|
413
|
+
options={suggestions}
|
|
414
|
+
isOpen={!suggestionsPending && shouldShowDropdown}
|
|
415
|
+
onItemSelectionChange={handleDropdownChange}
|
|
416
|
+
currentlyFocusedIndex={focusedIndex}
|
|
417
|
+
itemToHighlight={handleItemHighlighting}
|
|
418
|
+
/> : null}
|
|
419
|
+
</div>
|
|
420
|
+
|
|
421
|
+
const withRightElement = rightElement || leftElement ? <Toolbar noWrap={true}>
|
|
422
|
+
{leftElement && <ToolbarSection>{leftElement}</ToolbarSection>}
|
|
423
|
+
<ToolbarSection canGrow={true}>{autoSuggestionInput}</ToolbarSection>
|
|
424
|
+
{rightElement && <ToolbarSection>{rightElement}</ToolbarSection>}
|
|
425
|
+
</Toolbar> : autoSuggestionInput
|
|
426
|
+
|
|
427
|
+
return label ? (
|
|
428
|
+
<FieldItem
|
|
429
|
+
labelAttributes={{
|
|
430
|
+
text: (
|
|
431
|
+
<>
|
|
432
|
+
{label}
|
|
433
|
+
|
|
434
|
+
{(pathValidationPending || suggestionsPending) && (
|
|
435
|
+
<Spinner size="tiny" position="inline" description="Validating value path" />
|
|
436
|
+
)}
|
|
437
|
+
</>)
|
|
438
|
+
}}
|
|
439
|
+
hasStateDanger={hasError}
|
|
440
|
+
messageText={hasError ? validationErrorText : undefined}
|
|
441
|
+
>
|
|
442
|
+
{withRightElement}
|
|
443
|
+
</FieldItem>
|
|
444
|
+
) : withRightElement
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
export default AutoSuggestion;
|