@eccenca/gui-elements 24.1.0-rc.2 → 24.1.0-rc.4

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 (92) hide show
  1. package/CHANGELOG.md +37 -1
  2. package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js +5 -3
  3. package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
  4. package/dist/cjs/components/AutocompleteField/AutoCompleteField.js +4 -2
  5. package/dist/cjs/components/AutocompleteField/AutoCompleteField.js.map +1 -1
  6. package/dist/cjs/components/Card/CardActions.js +2 -1
  7. package/dist/cjs/components/Card/CardActions.js.map +1 -1
  8. package/dist/cjs/components/Card/CardContent.js +4 -6
  9. package/dist/cjs/components/Card/CardContent.js.map +1 -1
  10. package/dist/cjs/components/Dialog/SimpleDialog.js +3 -3
  11. package/dist/cjs/components/Dialog/SimpleDialog.js.map +1 -1
  12. package/dist/cjs/components/Icon/canonicalIconNames.js +2 -0
  13. package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
  14. package/dist/cjs/components/Label/Label.js +8 -3
  15. package/dist/cjs/components/Label/Label.js.map +1 -1
  16. package/dist/cjs/components/Menu/MenuItem.js +3 -2
  17. package/dist/cjs/components/Menu/MenuItem.js.map +1 -1
  18. package/dist/cjs/components/Switch/Switch.js +6 -4
  19. package/dist/cjs/components/Switch/Switch.js.map +1 -1
  20. package/dist/cjs/components/Tag/TagList.js +1 -1
  21. package/dist/cjs/components/Tag/TagList.js.map +1 -1
  22. package/dist/cjs/extensions/codemirror/CodeMirror.js +17 -16
  23. package/dist/cjs/extensions/codemirror/CodeMirror.js.map +1 -1
  24. package/dist/cjs/extensions/codemirror/tests/codemirrorTestHelper.js +4 -1
  25. package/dist/cjs/extensions/codemirror/tests/codemirrorTestHelper.js.map +1 -1
  26. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js +136 -41
  27. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  28. package/dist/cjs/extensions/react-flow/nodes/nodeUtils.js +5 -6
  29. package/dist/cjs/extensions/react-flow/nodes/nodeUtils.js.map +1 -1
  30. package/dist/esm/components/AutoSuggestion/AutoSuggestion.js +5 -3
  31. package/dist/esm/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
  32. package/dist/esm/components/AutocompleteField/AutoCompleteField.js +4 -3
  33. package/dist/esm/components/AutocompleteField/AutoCompleteField.js.map +1 -1
  34. package/dist/esm/components/Card/CardActions.js +2 -1
  35. package/dist/esm/components/Card/CardActions.js.map +1 -1
  36. package/dist/esm/components/Card/CardContent.js +4 -5
  37. package/dist/esm/components/Card/CardContent.js.map +1 -1
  38. package/dist/esm/components/Dialog/SimpleDialog.js +4 -4
  39. package/dist/esm/components/Dialog/SimpleDialog.js.map +1 -1
  40. package/dist/esm/components/Icon/canonicalIconNames.js +2 -0
  41. package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
  42. package/dist/esm/components/Label/Label.js +8 -3
  43. package/dist/esm/components/Label/Label.js.map +1 -1
  44. package/dist/esm/components/Menu/MenuItem.js +3 -2
  45. package/dist/esm/components/Menu/MenuItem.js.map +1 -1
  46. package/dist/esm/components/Switch/Switch.js +7 -5
  47. package/dist/esm/components/Switch/Switch.js.map +1 -1
  48. package/dist/esm/components/Tag/TagList.js +1 -1
  49. package/dist/esm/components/Tag/TagList.js.map +1 -1
  50. package/dist/esm/extensions/codemirror/CodeMirror.js +18 -17
  51. package/dist/esm/extensions/codemirror/CodeMirror.js.map +1 -1
  52. package/dist/esm/extensions/codemirror/tests/codemirrorTestHelper.js +4 -0
  53. package/dist/esm/extensions/codemirror/tests/codemirrorTestHelper.js.map +1 -1
  54. package/dist/esm/extensions/react-flow/nodes/NodeContent.js +145 -48
  55. package/dist/esm/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  56. package/dist/esm/extensions/react-flow/nodes/nodeUtils.js +5 -6
  57. package/dist/esm/extensions/react-flow/nodes/nodeUtils.js.map +1 -1
  58. package/dist/types/components/Card/CardActions.d.ts +5 -1
  59. package/dist/types/components/Card/CardContent.d.ts +1 -2
  60. package/dist/types/components/Dialog/SimpleDialog.d.ts +4 -1
  61. package/dist/types/components/Icon/canonicalIconNames.d.ts +2 -0
  62. package/dist/types/components/Label/Label.d.ts +7 -1
  63. package/dist/types/components/Menu/MenuItem.d.ts +8 -1
  64. package/dist/types/components/Switch/Switch.d.ts +3 -3
  65. package/dist/types/extensions/codemirror/tests/codemirrorTestHelper.d.ts +1 -0
  66. package/dist/types/extensions/react-flow/nodes/NodeContent.d.ts +18 -4
  67. package/dist/types/extensions/react-flow/nodes/nodeUtils.d.ts +7 -6
  68. package/package.json +2 -2
  69. package/src/cmem/react-flow/configuration/_colors-graph.scss +4 -1
  70. package/src/cmem/react-flow/configuration/_colors-workflow.scss +3 -0
  71. package/src/components/AutoSuggestion/AutoSuggestion.tsx +5 -3
  72. package/src/components/AutocompleteField/AutoCompleteField.tsx +5 -3
  73. package/src/components/Card/CardActions.tsx +6 -0
  74. package/src/components/Card/CardContent.tsx +8 -4
  75. package/src/components/Card/card.scss +15 -0
  76. package/src/components/Dialog/SimpleDialog.tsx +9 -2
  77. package/src/components/Icon/canonicalIconNames.tsx +2 -0
  78. package/src/components/Label/Label.stories.tsx +2 -1
  79. package/src/components/Label/Label.tsx +17 -1
  80. package/src/components/Label/label.scss +5 -1
  81. package/src/components/Menu/MenuItem.tsx +27 -1
  82. package/src/components/Menu/menu.scss +1 -0
  83. package/src/components/OverviewItem/overviewitem.scss +4 -1
  84. package/src/components/Switch/Switch.tsx +27 -8
  85. package/src/components/Tag/TagList.tsx +2 -2
  86. package/src/extensions/codemirror/CodeMirror.tsx +18 -16
  87. package/src/extensions/codemirror/tests/codemirrorTestHelper.ts +4 -0
  88. package/src/extensions/react-flow/_config.scss +1 -0
  89. package/src/extensions/react-flow/nodes/NodeContent.tsx +166 -52
  90. package/src/extensions/react-flow/nodes/_nodes.scss +71 -35
  91. package/src/extensions/react-flow/nodes/nodeUtils.tsx +16 -14
  92. package/src/extensions/react-flow/nodes/stories/NodeContent.stories.tsx +6 -3
@@ -1,3 +1,4 @@
1
+ $reactflow-color-project-node: #A5356E !default; // Cannot be part of a workflow but we have no other place atm to configure it
1
2
  $reactflow-color-dataset-node: #3a7896 !default;
2
3
  $reactflow-color-linking-node: #0097a7 !default;
3
4
  $reactflow-color-transform-node: #40a691 !default;
@@ -10,12 +11,14 @@ $reactflow-color-replaceable-input: #faa854 !default;
10
11
  }
11
12
 
12
13
  .#{eccgui}-configuration--colors__react-flow-workflow {
14
+ --projectNode: #{$reactflow-color-project-node};
13
15
  --datasetNode: #{$reactflow-color-dataset-node};
14
16
  --linkingNode: #{$reactflow-color-linking-node};
15
17
  --transformNode: #{$reactflow-color-transform-node};
16
18
  --taskNode: #{$reactflow-color-task-node};
17
19
  --workflowNode: #{$reactflow-color-workflow-node};
18
20
  --replaceableInput: #{$reactflow-color-replaceable-input};
21
+ --projectNodeBright: #{bright($reactflow-color-project-node)};
19
22
  --datasetNodeBright: #{bright($reactflow-color-dataset-node)};
20
23
  --linkingNodeBright: #{bright($reactflow-color-linking-node)};
21
24
  --transformNodeBright: #{bright($reactflow-color-transform-node)};
@@ -219,6 +219,8 @@ const AutoSuggestion = ({
219
219
  CodeAutocompleteFieldSuggestionWithReplacementInfo | undefined
220
220
  >(undefined);
221
221
  const [cm, setCM] = React.useState<EditorView>();
222
+ const currentCm = React.useRef<EditorView>()
223
+ currentCm.current = cm
222
224
  const isFocused = React.useRef(false);
223
225
  const autoSuggestionDivRef = React.useRef<HTMLDivElement>(null);
224
226
  /** Mutable editor state, since this needs to be current in scope of the SingleLineEditorComponent. */
@@ -235,12 +237,12 @@ const AutoSuggestion = ({
235
237
  const pathIsValid = validationResponse?.valid ?? true;
236
238
 
237
239
  React.useEffect(() => {
238
- if (reInitOnInitialValueChange && initialValue != null && cm) {
240
+ if (reInitOnInitialValueChange && initialValue != null && currentCm.current) {
239
241
  dispatch({
240
- changes: { from: 0, to: cm?.state?.doc.length, insert: initialValue },
242
+ changes: { from: 0, to: currentCm.current.state?.doc.length, insert: initialValue },
241
243
  });
242
244
  }
243
- }, [initialValue, cm, reInitOnInitialValueChange]);
245
+ }, [initialValue, reInitOnInitialValueChange]);
244
246
 
245
247
  const setCurrentIndex = (newIndex: number) => {
246
248
  editorState.index = newIndex;
@@ -301,13 +301,15 @@ function AutoCompleteField<T, UPDATE_VALUE>(props: AutoCompleteFieldProps<T, UPD
301
301
  let enableHighlighting = true;
302
302
  if (onlySelectItemReturned) {
303
303
  // If the auto-completion only returns no suggestion or the selected item itself, query with empty string.
304
- const emptyStringResults = await onSearch("");
304
+ const emptyStringResults: T[] = await onSearch("");
305
305
  // Disable highlighting, since we used empty string search
306
306
  enableHighlighting = false;
307
307
  // Put selected item at the top if it is not in the result list
308
308
  if (!!selectedItem && itemIndexOf(emptyStringResults, selectedItem) > -1) {
309
- emptyStringResults.splice(itemIndexOf(emptyStringResults, selectedItem), 1);
310
- result = [selectedItem, ...emptyStringResults];
309
+ // Do not mutate original array
310
+ const withoutSelected = [...emptyStringResults]
311
+ withoutSelected.splice(itemIndexOf(emptyStringResults, selectedItem), 1);
312
+ result = [selectedItem, ...withoutSelected];
311
313
  } else {
312
314
  result = emptyStringResults;
313
315
  }
@@ -8,6 +8,10 @@ export interface CardActionsProps extends React.HTMLAttributes<HTMLDivElement> {
8
8
  * Mainly used for cards used as modals (dialogs).
9
9
  */
10
10
  inverseDirection?: boolean;
11
+ /**
12
+ * Set footer to display its children on only one line.
13
+ */
14
+ noWrap?: boolean;
11
15
  }
12
16
 
13
17
  /**
@@ -18,6 +22,7 @@ export const CardActions = ({
18
22
  children,
19
23
  className = "",
20
24
  inverseDirection = false,
25
+ noWrap = false,
21
26
  ...otherProps
22
27
  }: CardActionsProps) => {
23
28
  return (
@@ -26,6 +31,7 @@ export const CardActions = ({
26
31
  className={
27
32
  `${eccgui}-card__actions` +
28
33
  (inverseDirection ? ` ${eccgui}-card__actions--inversedirection` : "") +
34
+ (noWrap ? ` ${eccgui}-card__actions--nowrap` : "") +
29
35
  (className ? " " + className : "")
30
36
  }
31
37
  >
@@ -15,10 +15,16 @@ export interface CardContentProps extends React.HTMLAttributes<HTMLDivElement> {
15
15
  * Holds the card content.
16
16
  * Display scrollbars in case there is not enough space for it.
17
17
  */
18
- export const CardContent = ({ children, className = "", noFlexHeight, ...otherProps }: CardContentProps) => {
18
+ export const CardContent = React.forwardRef<HTMLDivElement, CardContentProps>(({
19
+ children,
20
+ className='',
21
+ noFlexHeight,
22
+ ...otherProps
23
+ }: CardContentProps, ref) => {
19
24
  return (
20
25
  <div
21
26
  {...otherProps}
27
+ ref={ref}
22
28
  className={
23
29
  `${eccgui}-card__content` +
24
30
  (noFlexHeight ? ` ${eccgui}-card__content--noflexheight` : "") +
@@ -28,6 +34,4 @@ export const CardContent = ({ children, className = "", noFlexHeight, ...otherPr
28
34
  {children}
29
35
  </div>
30
36
  );
31
- };
32
-
33
- export default CardContent;
37
+ });
@@ -236,6 +236,10 @@ $eccgui-size-card-spacing: $eccgui-size-typo-base !default;
236
236
  flex-direction: row-reverse;
237
237
  }
238
238
 
239
+ .#{$eccgui}-card__actions--nowrap {
240
+ flex-wrap: nowrap;
241
+ }
242
+
239
243
  .#{$eccgui}-card__actions__aux {
240
244
  display: flex;
241
245
  flex-flow: row wrap;
@@ -272,4 +276,15 @@ $eccgui-size-card-spacing: $eccgui-size-typo-base !default;
272
276
  .#{$eccgui}-card__actions--inversedirection > & {
273
277
  justify-content: flex-start;
274
278
  }
279
+
280
+ .#{$eccgui}-card__actions--nowrap > & {
281
+ flex-shrink: 5;
282
+ flex-wrap: nowrap;
283
+ min-width: 0;
284
+
285
+ & > * {
286
+ flex-shrink: 10;
287
+ min-width: 0;
288
+ }
289
+ }
275
290
  }
@@ -5,7 +5,7 @@ import { CLASSPREFIX as eccgui } from "../../configuration/constants";
5
5
  import IconButton from "../Icon/IconButton";
6
6
  import { TestableComponent } from "../interfaces";
7
7
 
8
- import { Card, CardActions, CardContent, CardHeader, CardOptions, CardTitle } from "./../Card";
8
+ import { Card, CardActions, CardActionsProps, CardContent, CardHeader, CardOptions, CardTitle } from "./../Card";
9
9
  import Divider from "./../Separation/Divider";
10
10
  import Modal, { ModalProps } from "./Modal";
11
11
 
@@ -45,6 +45,8 @@ export interface SimpleDialogProps extends ModalProps, TestableComponent {
45
45
  showFullScreenToggler?: boolean;
46
46
  /** Starts the modal in full screen mode. The show full screen toggler will be automatically enabled. */
47
47
  startInFullScreenMode?: boolean;
48
+ /** Forward properties to the actions footer component. */
49
+ actionsProps?: Omit<CardActionsProps, "inverseDirection">;
48
50
  }
49
51
 
50
52
  /**
@@ -66,6 +68,7 @@ export const SimpleDialog = ({
66
68
  showFullScreenToggler = false,
67
69
  startInFullScreenMode = false,
68
70
  size,
71
+ actionsProps,
69
72
  ...otherProps
70
73
  }: SimpleDialogProps) => {
71
74
  const [displayFullscreen, setDisplayFullscreen] = React.useState<boolean>(startInFullScreenMode);
@@ -112,7 +115,11 @@ export const SimpleDialog = ({
112
115
  <CardContent className={`${eccgui}-dialog__notifications`}>{notifications}</CardContent>
113
116
  )}
114
117
  {actions && (
115
- <CardActions inverseDirection className={intentClassName}>
118
+ <CardActions
119
+ {...actionsProps}
120
+ inverseDirection
121
+ className={`${actionsProps?.className ?? ""} ${intentClassName}`}
122
+ >
116
123
  {actions}
117
124
  </CardActions>
118
125
  )}
@@ -19,6 +19,7 @@ const canonicalIcons = {
19
19
  "artefact-commit": icons.Commit,
20
20
  "artefact-task-deleteprojectfiles": icons.TrashCan,
21
21
  "artefact-task-downloadfile": icons.CloudDownload,
22
+ "artefact-task-concatenatetofile": icons.DocumentExport,
22
23
  "artefact-dataset-csv": icons.Csv,
23
24
  "artefact-dataset-eccencadataplatform": icons.DataVis_1,
24
25
  "artefact-dataset-excel": icons.Xls,
@@ -65,6 +66,7 @@ const canonicalIcons = {
65
66
  "item-download": icons.Download,
66
67
  "item-draggable": icons.Draggable,
67
68
  "item-edit": icons.Edit,
69
+ "item-magic-edit": icons.MagicWand,
68
70
  "item-evaluation": icons.Analytics,
69
71
  "item-execution": icons.Run,
70
72
  "item-info": icons.Information,
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { loremIpsum } from "react-lorem-ipsum";
3
3
  import { Meta, StoryFn } from "@storybook/react";
4
4
 
5
- import { Label } from "../../index";
5
+ import { Icon, Label } from "../../index";
6
6
 
7
7
  export default {
8
8
  title: "Forms/Label",
@@ -19,4 +19,5 @@ Default.args = {
19
19
  tooltip: loremIpsum({ p: 1, avgSentencesPerParagraph: 2, startWithLoremIpsum: false, random: false }).toString(),
20
20
  disabled: false,
21
21
  htmlFor: "inputid",
22
+ additionalElements: <Icon name={"state-warning"} tooltipText={"message"} small />,
22
23
  };
@@ -2,6 +2,7 @@ import React from "react";
2
2
 
3
3
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
4
4
  import Icon from "../Icon/Icon";
5
+ import Spacing from "../Separation/Spacing";
5
6
  import Tooltip, { TooltipProps } from "../Tooltip/Tooltip";
6
7
 
7
8
  export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
@@ -34,6 +35,12 @@ export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement>
34
35
  * visual appearance of the label
35
36
  */
36
37
  emphasis?: "strong" | "normal";
38
+ /**
39
+ * Add other elements to the end of the label content
40
+ */
41
+ additionalElements?: React.ReactNode | React.ReactNode[];
42
+ /** Force label to get displayed as inline block element. */
43
+ inline?: boolean;
37
44
  }
38
45
 
39
46
  export const Label = ({
@@ -46,6 +53,8 @@ export const Label = ({
46
53
  tooltipProps,
47
54
  isLayoutForElement = "label",
48
55
  emphasis = "normal",
56
+ additionalElements,
57
+ inline,
49
58
  ...otherLabelProps
50
59
  }: LabelProps) => {
51
60
  let htmlElementstring = isLayoutForElement;
@@ -63,16 +72,23 @@ export const Label = ({
63
72
  </span>
64
73
  )}
65
74
  {children && <span className={`${eccgui}-label__other`}>{children}</span>}
75
+ {additionalElements && (
76
+ <>
77
+ <Spacing vertical size="tiny" />
78
+ {additionalElements}
79
+ </>
80
+ )}
66
81
  </>
67
82
  );
68
83
 
69
- return !!text || !!info || !!tooltip || !!children ? (
84
+ return !!text || !!info || !!tooltip || !!children || !!additionalElements ? (
70
85
  React.createElement(
71
86
  htmlElementstring,
72
87
  {
73
88
  className:
74
89
  `${eccgui}-label ${eccgui}-label--${emphasis}` +
75
90
  (className ? " " + className : "") +
91
+ (inline ? ` ${eccgui}-label--inline` : "") +
76
92
  (disabled ? ` ${eccgui}-label--disabled` : ""),
77
93
  ...otherLabelProps,
78
94
  },
@@ -8,7 +8,6 @@ $eccgui-color-label-info: rgba($eccgui-color-workspace-text, $eccgui-opacity-mut
8
8
  font-size: $eccgui-size-typo-label;
9
9
  line-height: $eccgui-size-typo-label-lineheight;
10
10
  color: $eccgui-color-label-text;
11
- vertical-align: middle;
12
11
 
13
12
  .#{$eccgui}-typography__overflowtext--passdown > & {
14
13
  display: flex;
@@ -17,6 +16,11 @@ $eccgui-color-label-info: rgba($eccgui-color-workspace-text, $eccgui-opacity-mut
17
16
  }
18
17
  }
19
18
 
19
+ .#{$eccgui}-label--inline {
20
+ display: inline-block;
21
+ vertical-align: middle;
22
+ }
23
+
20
24
  .#{$eccgui}-label--disabled {
21
25
  opacity: $eccgui-opacity-disabled;
22
26
  }
@@ -5,6 +5,7 @@ import { openInNewTab } from "../../common/utils/openInNewTab";
5
5
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
6
6
  import { ValidIconName } from "../Icon/canonicalIconNames";
7
7
  import Icon from "../Icon/Icon";
8
+ import Tooltip from "../Tooltip/Tooltip";
8
9
 
9
10
  import { TestIconProps } from "./../Icon/TestIcon";
10
11
 
@@ -15,16 +16,41 @@ export interface MenuItemProps
15
16
  * If set the icon is diplayed on the left side of the menu item.
16
17
  */
17
18
  icon?: ValidIconName | string[] | React.ReactElement<TestIconProps>;
19
+ /**
20
+ * Submenu.
21
+ */
18
22
  children?: React.ReactNode;
23
+ /**
24
+ * Tooltip, but only added to the label, not to the full menu item.
25
+ */
26
+ tooltip?: string | JSX.Element;
19
27
  }
20
28
 
21
29
  /**
22
30
  * Single item, used as child inside `Menu`.
23
31
  */
24
- export const MenuItem = ({ children, className = "", icon, onClick, href, ...restProps }: MenuItemProps) => {
32
+ export const MenuItem = ({
33
+ children,
34
+ className = "",
35
+ icon,
36
+ onClick,
37
+ href,
38
+ text,
39
+ tooltip,
40
+ ...restProps
41
+ }: MenuItemProps) => {
25
42
  return (
26
43
  <BlueprintMenuItem
27
44
  {...restProps}
45
+ text={
46
+ tooltip ? (
47
+ <Tooltip content={tooltip} fill>
48
+ {text}
49
+ </Tooltip>
50
+ ) : (
51
+ text
52
+ )
53
+ }
28
54
  href={href}
29
55
  onClick={(e: React.MouseEvent<HTMLElement>) =>
30
56
  openInNewTab(e as React.MouseEvent<HTMLAnchorElement>, onClick, href)
@@ -48,6 +48,7 @@ $menu-background-color: transparent !default;
48
48
  @import "~@blueprintjs/core/src/components/menu/menu";
49
49
 
50
50
  .#{$ns}-menu {
51
+ min-width: auto;
51
52
  padding: 0;
52
53
 
53
54
  .#{$ns}-popover2-content > & {
@@ -193,7 +193,10 @@ $eccgui-size-overviewitem-line-typo-large-lineheight: $eccgui-size-typo-subtitle
193
193
 
194
194
  .#{$eccgui}-overviewitem__item:hover &,
195
195
  .#{$eccgui}-overviewitem__item:focus &,
196
- .#{$eccgui}-overviewitem__item:active & {
196
+ .#{$eccgui}-overviewitem__item:active &,
197
+ &:focus-within,
198
+ &:has(.#{$ns}-active),
199
+ &:has(.#{$ns}-popover-open) {
197
200
  display: flex;
198
201
  }
199
202
  }
@@ -1,26 +1,45 @@
1
- import React, { memo, SyntheticEvent } from "react";
2
- import { Switch as BlueprintSwitch, SwitchProps as BlueprintSwitchProps } from "@blueprintjs/core";
1
+ import React, { memo } from "react";
2
+ import {
3
+ Classes as BlueprintClasses,
4
+ Switch as BlueprintSwitch,
5
+ SwitchProps as BlueprintSwitchProps,
6
+ } from "@blueprintjs/core";
3
7
 
4
8
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
9
+ import { Label } from "../Label/Label";
5
10
 
6
11
  export interface SwitchProps extends Omit<BlueprintSwitchProps, "onChange"> {
7
12
  /**
8
13
  * Event handler for changed state.
9
14
  */
10
- onChange?: (value: boolean) => any;
15
+ onChange?: (value: boolean) => void;
11
16
  /**
12
17
  * class names
13
18
  */
14
19
  className?: string;
15
20
  }
16
21
 
17
- export const Switch = ({ onChange, className, ...otherProps }: SwitchProps) => {
18
- const handleChange = (e: SyntheticEvent<HTMLInputElement>) => {
19
- const checked = !!(e as any).target?.checked;
20
- onChange && onChange(checked);
22
+ export const Switch = ({ onChange, className, label, ...otherProps }: SwitchProps) => {
23
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
24
+ if (onChange) {
25
+ onChange(!!e.target?.checked);
26
+ }
21
27
  };
22
28
 
23
- return <BlueprintSwitch className={`${eccgui}-switch ${className}`} {...otherProps} onChange={handleChange} />;
29
+ return (
30
+ <BlueprintSwitch
31
+ className={`${eccgui}-switch ${className ?? ""} ${
32
+ label && !otherProps.labelElement ? BlueprintClasses.INLINE : ""
33
+ }`}
34
+ labelElement={
35
+ label ? (
36
+ <Label text={label} isLayoutForElement="span" disabled={otherProps.disabled} inline />
37
+ ) : undefined
38
+ }
39
+ {...otherProps}
40
+ onChange={handleChange}
41
+ />
42
+ );
24
43
  };
25
44
 
26
45
  export default memo(Switch);
@@ -10,11 +10,11 @@ function TagList({ children, className = "", label = "", ...otherProps }: TagLis
10
10
  const tagList = (
11
11
  <ul className={`${eccgui}-tag__list` + (className && !label ? " " + className : "")} {...otherProps}>
12
12
  {React.Children.map(children, (child, i) => {
13
- return (
13
+ return child ? (
14
14
  <li className={`${eccgui}-tag__list-item`} key={"tagitem_" + i}>
15
15
  {child}
16
16
  </li>
17
- );
17
+ ) : null;
18
18
  })}
19
19
  </ul>
20
20
  );
@@ -1,7 +1,6 @@
1
1
  import React, { useMemo, useRef } from "react";
2
2
  import { defaultKeymap, indentWithTab } from "@codemirror/commands";
3
3
  import { foldKeymap } from "@codemirror/language";
4
- import { lintGutter } from "@codemirror/lint";
5
4
  import { EditorState, Extension } from "@codemirror/state";
6
5
  import { DOMEventHandlers, EditorView, KeyBinding, keymap, Rect, ViewUpdate } from "@codemirror/view";
7
6
  import { minimalSetup } from "codemirror";
@@ -29,6 +28,7 @@ import {
29
28
  adaptedHighlightSpecialChars,
30
29
  adaptedLineNumbers,
31
30
  adaptedPlaceholder,
31
+ adaptedLintGutter,
32
32
  } from "./tests/codemirrorTestHelper";
33
33
  import { ExtensionCreator } from "./types";
34
34
 
@@ -212,7 +212,7 @@ export const CodeEditor = ({
212
212
  return [];
213
213
  }
214
214
 
215
- const values = [lintGutter()];
215
+ const values = [adaptedLintGutter()];
216
216
 
217
217
  const linters = ModeLinterMap.get(mode);
218
218
  if (linters) {
@@ -320,24 +320,26 @@ export const CodeEditor = ({
320
320
  parent: parent.current,
321
321
  });
322
322
 
323
- if (height) {
324
- view.dom.style.height = typeof height === "string" ? height : `${height}px`;
325
- }
323
+ if (view?.dom) {
324
+ if (height) {
325
+ view.dom.style.height = typeof height === "string" ? height : `${height}px`;
326
+ }
326
327
 
327
- if (disabled) {
328
- view.dom.className += ` ${eccgui}-disabled`;
329
- }
328
+ if (disabled) {
329
+ view.dom.className += ` ${eccgui}-disabled`;
330
+ }
330
331
 
331
- if (intent) {
332
- view.dom.className += ` ${eccgui}-intent--${intent}`;
333
- }
332
+ if (intent) {
333
+ view.dom.className += ` ${eccgui}-intent--${intent}`;
334
+ }
334
335
 
335
- if (autoFocus) {
336
- view.focus();
337
- }
336
+ if (autoFocus) {
337
+ view.focus();
338
+ }
338
339
 
339
- if (setEditorView) {
340
- setEditorView(view);
340
+ if (setEditorView) {
341
+ setEditorView(view);
342
+ }
341
343
  }
342
344
 
343
345
  return () => {
@@ -10,6 +10,7 @@
10
10
  import { EditorView, placeholder, highlightSpecialChars, lineNumbers, highlightActiveLine } from "@codemirror/view";
11
11
  import { syntaxHighlighting, foldGutter, codeFolding } from "@codemirror/language";
12
12
  import { Extension } from "@codemirror/state";
13
+ import { lintGutter } from "@codemirror/lint";
13
14
 
14
15
  /** placeholder extension, current error '_view.placeholder is not a function' */
15
16
  export const adaptedPlaceholder = (text?: string) =>
@@ -55,3 +56,6 @@ export const adaptedFoldGutter = (props?: any) =>
55
56
 
56
57
  export const adaptedCodeFolding = (props?: any) =>
57
58
  typeof codeFolding === "function" ? codeFolding(props) : emptyExtension;
59
+
60
+ export const adaptedLintGutter = (props?: any) =>
61
+ typeof lintGutter === "function" ? lintGutter(props) : emptyExtension;
@@ -15,3 +15,4 @@ $reactflow-edge-stroke-color-selected: $eccgui-color-accent !default;
15
15
  $reactflow-transition-time: 0.25s !default;
16
16
  $reactflow-transition-function: "" !default;
17
17
  $reactflow-transition-anglestart: -90deg;
18
+ $reactflow-cursor-delimiter-offset: 0.9 * $eccgui-size-block-whitespace;