@eccenca/gui-elements 23.2.0 → 23.3.0-rc.1

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 (149) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js +5 -1
  3. package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -1
  4. package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +9 -11
  5. package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
  6. package/dist/cjs/cmem/react-flow/extensions/ReactFlowHotkeyContext.js +12 -0
  7. package/dist/cjs/cmem/react-flow/extensions/ReactFlowHotkeyContext.js.map +1 -0
  8. package/dist/cjs/common/index.js +5 -2
  9. package/dist/cjs/common/index.js.map +1 -1
  10. package/dist/cjs/common/utils/globalVars.js +21 -0
  11. package/dist/cjs/common/utils/globalVars.js.map +1 -0
  12. package/dist/cjs/components/Application/ApplicationHeader.js +2 -3
  13. package/dist/cjs/components/Application/ApplicationHeader.js.map +1 -1
  14. package/dist/cjs/components/Dialog/Modal.js +35 -8
  15. package/dist/cjs/components/Dialog/Modal.js.map +1 -1
  16. package/dist/cjs/components/Dialog/SimpleDialog.js +15 -2
  17. package/dist/cjs/components/Dialog/SimpleDialog.js.map +1 -1
  18. package/dist/cjs/components/Icon/IconButton.js +1 -1
  19. package/dist/cjs/components/Icon/IconButton.js.map +1 -1
  20. package/dist/cjs/components/Icon/canonicalIconNames.js +1 -0
  21. package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
  22. package/dist/cjs/components/OverviewItem/OverviewItemDepiction.js +3 -6
  23. package/dist/cjs/components/OverviewItem/OverviewItemDepiction.js.map +1 -1
  24. package/dist/cjs/components/PropertyValuePair/PropertyName.js +3 -3
  25. package/dist/cjs/components/PropertyValuePair/PropertyName.js.map +1 -1
  26. package/dist/cjs/components/Separation/Spacing.js +18 -4
  27. package/dist/cjs/components/Separation/Spacing.js.map +1 -1
  28. package/dist/cjs/components/Table/TableExpandHeader.js +7 -8
  29. package/dist/cjs/components/Table/TableExpandHeader.js.map +1 -1
  30. package/dist/cjs/components/TextField/TextField.js +23 -3
  31. package/dist/cjs/components/TextField/TextField.js.map +1 -1
  32. package/dist/cjs/extensions/codemirror/CodeMirror.js +39 -7
  33. package/dist/cjs/extensions/codemirror/CodeMirror.js.map +1 -1
  34. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js +10 -9
  35. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
  36. package/dist/cjs/extensions/react-flow/handles/HandleContent.js +4 -4
  37. package/dist/cjs/extensions/react-flow/handles/HandleContent.js.map +1 -1
  38. package/dist/cjs/extensions/react-flow/handles/HandleDefault.js +56 -6
  39. package/dist/cjs/extensions/react-flow/handles/HandleDefault.js.map +1 -1
  40. package/dist/cjs/extensions/react-flow/handles/HandleTools.js +41 -0
  41. package/dist/cjs/extensions/react-flow/handles/HandleTools.js.map +1 -0
  42. package/dist/cjs/extensions/react-flow/index.js +2 -0
  43. package/dist/cjs/extensions/react-flow/index.js.map +1 -1
  44. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js +42 -13
  45. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  46. package/dist/esm/cmem/markdown/Markdown.js +1 -1
  47. package/dist/esm/cmem/react-flow/ReactFlow/ReactFlow.js +5 -1
  48. package/dist/esm/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -1
  49. package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +9 -11
  50. package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
  51. package/dist/esm/cmem/react-flow/extensions/ReactFlowHotkeyContext.js +6 -0
  52. package/dist/esm/cmem/react-flow/extensions/ReactFlowHotkeyContext.js.map +1 -0
  53. package/dist/esm/common/index.js +5 -2
  54. package/dist/esm/common/index.js.map +1 -1
  55. package/dist/esm/common/utils/globalVars.js +16 -0
  56. package/dist/esm/common/utils/globalVars.js.map +1 -0
  57. package/dist/esm/components/Application/ApplicationHeader.js +2 -3
  58. package/dist/esm/components/Application/ApplicationHeader.js.map +1 -1
  59. package/dist/esm/components/Dialog/Modal.js +36 -9
  60. package/dist/esm/components/Dialog/Modal.js.map +1 -1
  61. package/dist/esm/components/Dialog/SimpleDialog.js +14 -1
  62. package/dist/esm/components/Dialog/SimpleDialog.js.map +1 -1
  63. package/dist/esm/components/Icon/IconButton.js +1 -1
  64. package/dist/esm/components/Icon/IconButton.js.map +1 -1
  65. package/dist/esm/components/Icon/canonicalIconNames.js +1 -0
  66. package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
  67. package/dist/esm/components/OverviewItem/OverviewItemDepiction.js +3 -6
  68. package/dist/esm/components/OverviewItem/OverviewItemDepiction.js.map +1 -1
  69. package/dist/esm/components/PropertyValuePair/PropertyName.js +3 -3
  70. package/dist/esm/components/PropertyValuePair/PropertyName.js.map +1 -1
  71. package/dist/esm/components/Separation/Spacing.js +28 -4
  72. package/dist/esm/components/Separation/Spacing.js.map +1 -1
  73. package/dist/esm/components/Table/TableExpandHeader.js +7 -8
  74. package/dist/esm/components/Table/TableExpandHeader.js.map +1 -1
  75. package/dist/esm/components/TextField/TextField.js +25 -5
  76. package/dist/esm/components/TextField/TextField.js.map +1 -1
  77. package/dist/esm/extensions/codemirror/CodeMirror.js +49 -6
  78. package/dist/esm/extensions/codemirror/CodeMirror.js.map +1 -1
  79. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js +10 -9
  80. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
  81. package/dist/esm/extensions/react-flow/handles/HandleContent.js +16 -5
  82. package/dist/esm/extensions/react-flow/handles/HandleContent.js.map +1 -1
  83. package/dist/esm/extensions/react-flow/handles/HandleDefault.js +75 -9
  84. package/dist/esm/extensions/react-flow/handles/HandleDefault.js.map +1 -1
  85. package/dist/esm/extensions/react-flow/handles/HandleTools.js +61 -0
  86. package/dist/esm/extensions/react-flow/handles/HandleTools.js.map +1 -0
  87. package/dist/esm/extensions/react-flow/index.js +2 -0
  88. package/dist/esm/extensions/react-flow/index.js.map +1 -1
  89. package/dist/esm/extensions/react-flow/nodes/NodeContent.js +49 -20
  90. package/dist/esm/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  91. package/dist/types/cmem/react-flow/extensions/ReactFlowHotkeyContext.d.ts +8 -0
  92. package/dist/types/common/index.d.ts +4 -0
  93. package/dist/types/common/utils/globalVars.d.ts +2 -0
  94. package/dist/types/components/Application/ApplicationHeader.d.ts +1 -2
  95. package/dist/types/components/Dialog/Modal.d.ts +22 -7
  96. package/dist/types/components/Dialog/SimpleDialog.d.ts +12 -1
  97. package/dist/types/components/Icon/canonicalIconNames.d.ts +1 -1
  98. package/dist/types/components/PropertyValuePair/PropertyName.d.ts +7 -1
  99. package/dist/types/components/Separation/Spacing.d.ts +2 -2
  100. package/dist/types/components/Table/TableExpandHeader.d.ts +5 -1
  101. package/dist/types/components/TextField/TextField.d.ts +4 -2
  102. package/dist/types/extensions/codemirror/CodeMirror.d.ts +17 -3
  103. package/dist/types/extensions/react-flow/edges/EdgeLabel.d.ts +7 -3
  104. package/dist/types/extensions/react-flow/handles/HandleContent.d.ts +7 -2
  105. package/dist/types/extensions/react-flow/handles/HandleDefault.d.ts +15 -6
  106. package/dist/types/extensions/react-flow/handles/HandleTools.d.ts +7 -0
  107. package/dist/types/extensions/react-flow/index.d.ts +2 -0
  108. package/dist/types/extensions/react-flow/nodes/NodeContent.d.ts +24 -8
  109. package/package.json +19 -17
  110. package/scripts/compile-sass.ts +1 -1
  111. package/src/cmem/react-flow/ReactFlow/ReactFlow.tsx +10 -0
  112. package/src/cmem/react-flow/StickyNoteModal/StickyNoteModal.tsx +10 -12
  113. package/src/cmem/react-flow/extensions/ReactFlowHotkeyContext.ts +14 -0
  114. package/src/common/index.ts +6 -3
  115. package/src/common/utils/globalVars.ts +18 -0
  116. package/src/components/Application/ApplicationHeader.tsx +8 -13
  117. package/src/components/Application/_header.scss +17 -17
  118. package/src/components/Application/_toolbar.scss +22 -33
  119. package/src/components/Application/application.scss +8 -6
  120. package/src/components/AutoSuggestion/tests/AutoSuggestion.test.tsx +34 -21
  121. package/src/components/AutoSuggestion/tests/SingleLineCodeEditor.test.tsx +20 -9
  122. package/src/components/Dialog/Modal.tsx +96 -39
  123. package/src/components/Dialog/SimpleDialog.tsx +19 -1
  124. package/src/components/Dialog/dialog.scss +33 -17
  125. package/src/components/Icon/IconButton.tsx +1 -1
  126. package/src/components/Icon/canonicalIconNames.tsx +2 -0
  127. package/src/components/OverviewItem/OverviewItemDepiction.tsx +8 -16
  128. package/src/components/PropertyValuePair/PropertyName.tsx +15 -4
  129. package/src/components/PropertyValuePair/propertyvalue.scss +1 -0
  130. package/src/components/Separation/Spacing.tsx +12 -8
  131. package/src/components/Table/TableExpandHeader.tsx +21 -18
  132. package/src/components/TextField/TextField.tsx +32 -6
  133. package/src/components/Tooltip/tooltip.scss +15 -1
  134. package/src/extensions/codemirror/CodeMirror.tsx +62 -8
  135. package/src/extensions/codemirror/_codemirror.scss +53 -8
  136. package/src/extensions/react-flow/edges/EdgeLabel.tsx +78 -81
  137. package/src/extensions/react-flow/edges/_edges.scss +62 -67
  138. package/src/extensions/react-flow/edges/stories/EdgeDefault.stories.tsx +43 -44
  139. package/src/extensions/react-flow/handles/HandleContent.tsx +14 -13
  140. package/src/extensions/react-flow/handles/HandleDefault.tsx +121 -44
  141. package/src/extensions/react-flow/handles/HandleTools.tsx +46 -0
  142. package/src/extensions/react-flow/handles/_handles.scss +135 -50
  143. package/src/extensions/react-flow/handles/stories/HandleDefault.stories.tsx +69 -25
  144. package/src/extensions/react-flow/index.ts +2 -0
  145. package/src/extensions/react-flow/nodes/NodeContent.tsx +97 -32
  146. package/src/extensions/react-flow/nodes/_nodes.scss +170 -110
  147. package/src/extensions/react-flow/nodes/stories/NodeContent.stories.tsx +75 -52
  148. package/src/extensions/react-flow/nodes/stories/NodeDefault.stories.tsx +34 -36
  149. package/src/extensions/react-flow/nodes/stories/nodeTypes.ts +11 -0
@@ -1,82 +1,139 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
  import {
3
3
  Classes as BlueprintClassNames,
4
- OverlayProps, Overlay as BlueprintOverlay,
5
- IOverlayState,
4
+ IOverlayState as BlueprintOverlayState,
5
+ Overlay as BlueprintOverlay,
6
+ OverlayProps as BlueprintOverlayProps,
6
7
  } from "@blueprintjs/core";
7
- import {Card} from "./../Card";
8
- import {CLASSPREFIX as eccgui} from "../../configuration/constants";
9
8
 
10
- export interface ModalProps extends OverlayProps, IOverlayState {
11
- children: React.ReactNode | React.ReactNode[];
12
- /**
13
- * A space-delimited list of class names to pass along to the BlueprintJS `Overlay` element that is used to create the modal.
14
- */
15
- overlayClassName?: string;
16
- /**
17
- * Size of the modal.
18
- */
19
- size?: "tiny" | "small" | "regular" | "large" | "fullscreen";
20
- /**
21
- * Prevents that a backdrop area is displayed behind the modal elements.
22
- */
23
- preventBackdrop?: boolean;
24
- /** Optional props for the wrapper div element inside the modal overlay. */
25
- wrapperDivProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
9
+ import { Utilities } from "../../common";
10
+ import { CLASSPREFIX as eccgui } from "../../configuration/constants";
11
+
12
+ import { Card } from "./../Card";
13
+
14
+ export interface ModalProps extends BlueprintOverlayProps, BlueprintOverlayState {
15
+ children: React.ReactNode | React.ReactNode[];
16
+ /**
17
+ * A space-delimited list of class names to pass along to the BlueprintJS `Overlay` element that is used to create the modal.
18
+ */
19
+ overlayClassName?: string;
20
+ /**
21
+ * Size of the modal.
22
+ */
23
+ size?: "tiny" | "small" | "regular" | "large" | "xlarge" | "fullscreen";
24
+ /**
25
+ * Prevents that a backdrop area is displayed behind the modal elements.
26
+ */
27
+ preventBackdrop?: boolean;
28
+ /**
29
+ * Optional props for the wrapper div element inside the modal overlay.
30
+ */
31
+ wrapperDivProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
32
+ /**
33
+ * Make the modal focusable, e.g. when clicking somewhere on it.
34
+ * This is needed, e.g. when capturing key (down, up) events that should bubble to the modal's parent elements.
35
+ */
36
+ modalFocusable?: boolean;
37
+ /**
38
+ * Works only for modals inside portals (`usePortal={true}`).
39
+ * When set to `true` then the `z-index` of the modal's portal element is recalculated, so that the modal is always shown on top of all other visible elements.
40
+ * Use this with care!
41
+ * Usually the normal opening sequence is enough to show the currently most important modal on top.
42
+ * If this option is used inflationary then this could harm the visibility of other overlays.
43
+ */
44
+ forceTopPosition?: boolean;
26
45
  }
27
46
 
28
47
  /**
29
48
  * Displays contents on top of other elements, used to create dialogs.
30
- * For most situations the usage of `SimpleDialog` and `AlertDialog` should be sufficent.
49
+ * For most situations the usage of `SimpleDialog` and `AlertDialog` should be sufficient.
31
50
  * Otherwise this element can be used to create own modal elements and edge cases for modal dialogs.
32
51
  * Then it is recommended to use the `Card` element inside.
33
52
  */
34
53
  export const Modal = ({
35
54
  children,
36
- className='',
37
- overlayClassName='',
38
- size="regular",
39
- canOutsideClickClose=false,
40
- canEscapeKeyClose=false,
41
- preventBackdrop=false,
55
+ className = "",
56
+ overlayClassName = "",
57
+ size = "regular",
58
+ canOutsideClickClose = false,
59
+ canEscapeKeyClose = false,
60
+ preventBackdrop = false,
42
61
  wrapperDivProps,
62
+ modalFocusable = true,
63
+ usePortal = true,
64
+ forceTopPosition = false,
65
+ onOpening,
43
66
  ...otherProps
44
67
  }: ModalProps) => {
68
+ const backdropProps: React.HTMLProps<HTMLDivElement> | undefined =
69
+ !canOutsideClickClose && canEscapeKeyClose
70
+ ? {
71
+ ...otherProps.backdropProps,
72
+ // Escape key won't work anymore otherwise after clicking on the backdrop
73
+ tabIndex: 0,
74
+ }
75
+ : otherProps.backdropProps;
76
+
77
+ const focusableProps = modalFocusable
78
+ ? {
79
+ tabIndex: 0,
80
+ }
81
+ : undefined;
45
82
 
46
83
  const alteredChildren = React.Children.map(children, (child) => {
47
- if ((child as React.ReactElement).type && (child as React.ReactElement).type === Card) {
48
- return React.cloneElement(
49
- child as React.ReactElement,
50
- {
51
- isOnlyLayout: true,
52
- elevation: 4
53
- }
54
- );
84
+ if ((child as React.ReactElement).type && (child as React.ReactElement).type === Card) {
85
+ return React.cloneElement(child as React.ReactElement, {
86
+ isOnlyLayout: true,
87
+ elevation: 4,
88
+ });
55
89
  }
56
90
 
57
91
  return child;
58
92
  });
59
93
 
94
+ const handlerOnOpening = (modalElement: HTMLElement) => {
95
+ if (onOpening) {
96
+ // call the original event handler
97
+ onOpening(modalElement);
98
+ }
99
+ if (usePortal && forceTopPosition) {
100
+ const parentalPortal = modalElement.closest(`.${BlueprintClassNames.PORTAL}`) as HTMLElement;
101
+ const highestTopIndex = (Utilities.getGlobalVar("highestModalTopIndex") as unknown as number) ?? 0;
102
+ if (parentalPortal) {
103
+ const portalTopIndex = parseInt(getComputedStyle(parentalPortal).zIndex ?? 0, 10);
104
+ const newTopIndex = Math.max(portalTopIndex, highestTopIndex) + 1;
105
+ parentalPortal.style.zIndex = `${newTopIndex}`;
106
+ Utilities.setGlobalVar("highestModalTopIndex", newTopIndex);
107
+ }
108
+ }
109
+ };
110
+
60
111
  return (
61
112
  <BlueprintOverlay
62
113
  {...otherProps}
114
+ backdropProps={backdropProps}
63
115
  className={overlayClassName}
64
116
  backdropClassName={`${eccgui}-dialog__backdrop`}
65
117
  canOutsideClickClose={canOutsideClickClose}
66
118
  canEscapeKeyClose={canEscapeKeyClose}
67
119
  hasBackdrop={!preventBackdrop}
120
+ usePortal={usePortal}
121
+ onOpening={handlerOnOpening}
122
+ portalClassName={`${eccgui}-dialog__portal`}
68
123
  >
69
124
  <div
70
125
  {...wrapperDivProps}
71
126
  className={BlueprintClassNames.DIALOG_CONTAINER}
72
127
  // this is a workaround because data attribute on SimpleDialog is not correctly routed to the overlay by blueprint js
73
128
  data-test-id={(otherProps as any)["data-test-id"] ?? "simpleDialogWidget"}
129
+ {...focusableProps}
130
+ tabIndex={0}
74
131
  >
75
132
  <section
76
133
  className={
77
134
  `${eccgui}-dialog__wrapper` +
78
- (typeof size === 'string' ? ` ${eccgui}-dialog__wrapper--` + size : '') +
79
- (className ? ' ' + className : '')
135
+ (typeof size === "string" ? ` ${eccgui}-dialog__wrapper--` + size : "") +
136
+ (className ? " " + className : "")
80
137
  }
81
138
  >
82
139
  {alteredChildren}
@@ -84,6 +141,6 @@ export const Modal = ({
84
141
  </div>
85
142
  </BlueprintOverlay>
86
143
  );
87
- }
144
+ };
88
145
 
89
146
  export default Modal;
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, {BaseSyntheticEvent} from "react";
2
2
 
3
3
  import { IntentTypes } from "../../common/Intent";
4
4
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
@@ -71,10 +71,15 @@ export const SimpleDialog = ({
71
71
  const [displayFullscreen, setDisplayFullscreen] = React.useState<boolean>(startInFullScreenMode);
72
72
  const showToggler = startInFullScreenMode || showFullScreenToggler;
73
73
  const intentClassName = intent ? `${eccgui}-intent--${intent}` : "";
74
+ const wrapperDivProps = {
75
+ ...modalPreventEvents,
76
+ ...otherProps.wrapperDivProps,
77
+ };
74
78
  return (
75
79
  <Modal
76
80
  enforceFocus={enforceFocus}
77
81
  {...otherProps}
82
+ wrapperDivProps={wrapperDivProps}
78
83
  // set default test id if not given
79
84
  data-test-id={otherProps["data-test-id"] ?? "simpleDialogWidget"}
80
85
  canOutsideClickClose={canOutsideClickClose || !preventSimpleClosing}
@@ -116,4 +121,17 @@ export const SimpleDialog = ({
116
121
  );
117
122
  };
118
123
 
124
+ /** Events that should be prevented to bubble up from a modal that goes beyond the most simple version of a modal, e.g.
125
+ * allows to drag or supports hot keys etc. */
126
+ export const modalPreventEvents = {
127
+ // Prevent certain events from leaving the modal, so that e.g. react-flow does not receive these events doing unexpected stuff
128
+ onContextMenu: (event: BaseSyntheticEvent) => event.stopPropagation(),
129
+ onDrag: (event: BaseSyntheticEvent) => event.stopPropagation(),
130
+ onDragStart: (event: BaseSyntheticEvent) => event.stopPropagation(),
131
+ onDragEnd: (event: BaseSyntheticEvent) => event.stopPropagation(),
132
+ onMouseDown: (event: BaseSyntheticEvent) => event.stopPropagation(),
133
+ onMouseUp: (event: BaseSyntheticEvent) => event.stopPropagation(),
134
+ onClick: (event: BaseSyntheticEvent) => event.stopPropagation()
135
+ };
136
+
119
137
  export default SimpleDialog;
@@ -2,31 +2,37 @@
2
2
 
3
3
  // our vars
4
4
  $eccgui-size-modal-tiny-width: math.div(4, 16) * 100vw !default;
5
- $eccgui-size-modal-tiny-height: math.div(1, 9) * 100vh !default;
6
- $eccgui-size-modal-small-width: math.div(6, 16) * 100vw !default;
7
- $eccgui-size-modal-small-height: math.div(2, 9) * 100vh !default;
8
- $eccgui-size-modal-regular-width: math.div(6, 16) * 100vw !default;
9
- $eccgui-size-modal-regular-height: math.div(3, 9) * 100vh !default;
10
- $eccgui-size-modal-large-width: math.div(8, 16) * 100vw !default;
11
- $eccgui-size-modal-large-height: math.div(6, 9) * 100vh !default;
5
+ $eccgui-size-modal-tiny-height: math.div(1, 9) * 100vh !default;
6
+ $eccgui-size-modal-small-width: math.div(5, 16) * 100vw !default;
7
+ $eccgui-size-modal-small-height: math.div(2, 9) * 100vh !default;
8
+ $eccgui-size-modal-regular-width: math.div(6, 16) * 100vw !default;
9
+ $eccgui-size-modal-regular-height: math.div(3, 9) * 100vh !default;
10
+ $eccgui-size-modal-large-width: math.div(9, 16) * 100vw !default;
11
+ $eccgui-size-modal-large-height: math.div(6, 9) * 100vh !default;
12
+ $eccgui-size-modal-xlarge-width: math.div(12, 16) * 100vw !default;
13
+ $eccgui-size-modal-xlarge-height: math.div(7, 9) * 100vh !default;
12
14
  $eccgui-color-modal-backdrop: rgba(invert($eccgui-color-workspace-background), 0.69) !default;
13
15
 
14
16
  @import "~@blueprintjs/core/src/components/dialog/dialog";
15
17
 
18
+ .#{$eccgui}-dialog__portal {
19
+ z-index: 8001; // higher than carbon ui shell header
20
+ }
21
+
16
22
  .#{$eccgui}-dialog__backdrop {
17
23
  background-color: $eccgui-color-modal-backdrop;
18
24
  }
19
25
 
20
26
  .#{$eccgui}-dialog__wrapper {
21
- margin: 2rem;
27
+ display: flex;
28
+ align-content: stretch;
29
+ align-items: stretch;
30
+ justify-content: center;
22
31
  max-width: calc(100vw - 4rem);
23
32
  max-height: calc(100vh - 4rem);
33
+ margin: 2rem;
24
34
  pointer-events: all;
25
35
  user-select: text;
26
- display: flex;
27
- justify-content: center;
28
- align-items: stretch;
29
- align-content: stretch;
30
36
 
31
37
  & > * {
32
38
  flex-grow: 1;
@@ -34,9 +40,14 @@ $eccgui-color-modal-backdrop: rgba(invert($eccgui-color-workspace-background), 0
34
40
  max-width: 100%;
35
41
  }
36
42
 
37
- & * {
43
+ * {
38
44
  pointer-events: all;
39
45
  }
46
+
47
+ .#{$prefix}--popover {
48
+ // workaround to fix the arrows in pagination when used in modal
49
+ pointer-events: none;
50
+ }
40
51
  }
41
52
 
42
53
  .#{$eccgui}-dialog__wrapper--tiny {
@@ -59,14 +70,19 @@ $eccgui-color-modal-backdrop: rgba(invert($eccgui-color-workspace-background), 0
59
70
  min-height: $eccgui-size-modal-large-height;
60
71
  }
61
72
 
73
+ .#{$eccgui}-dialog__wrapper--xlarge {
74
+ width: $eccgui-size-modal-xlarge-width;
75
+ min-height: $eccgui-size-modal-xlarge-height;
76
+ }
77
+
62
78
  .#{$eccgui}-dialog__wrapper--fullscreen {
63
- margin: 0;
64
- padding: $eccgui-size-block-whitespace;
65
79
  box-sizing: border-box;
66
- height: 100vh;
67
80
  width: 100vw;
68
- max-height: 100vh;
69
81
  max-width: 100vw;
82
+ height: 100vh;
83
+ max-height: 100vh;
84
+ padding: $eccgui-size-block-whitespace;
85
+ margin: 0;
70
86
  }
71
87
 
72
88
  .#{$eccgui}-dialog__notifications {
@@ -48,7 +48,7 @@ export const IconButton = ({
48
48
  }: IconButtonProps) => {
49
49
  const defaultIconTooltipProps = {
50
50
  hoverOpenDelay: 1000,
51
- openOnTargetFocus: restProps.disabled || (restProps.tabIndex ?? "0") < 0 ? false : undefined,
51
+ openOnTargetFocus: restProps.disabled || (restProps.tabIndex ?? 0) < 0 ? false : undefined,
52
52
  };
53
53
  const iconProps = {
54
54
  small: restProps.small,
@@ -13,6 +13,7 @@ export type ValidIconName =
13
13
  | "application-useraccount"
14
14
  | "application-vocabularies"
15
15
  | "application-warning"
16
+ | "application-hotkeys"
16
17
  | "artefact-commit"
17
18
  | "artefact-customtask"
18
19
  | "artefact-dataset"
@@ -162,6 +163,7 @@ const canonicalIconNames: Record<ValidIconName, CarbonIconType> = {
162
163
  "application-useraccount": icons.UserAvatar,
163
164
  "application-vocabularies": icons.Catalog,
164
165
  "application-warning": icons.WarningAlt,
166
+ "application-hotkeys": icons.Keyboard,
165
167
 
166
168
  "artefact-commit": icons.Commit,
167
169
  "artefact-customtask": icons.Script,
@@ -11,7 +11,7 @@ export interface OverviewItemDepictionProps extends React.HTMLAttributes<HTMLDiv
11
11
 
12
12
  export const OverviewItemDepiction = ({
13
13
  children,
14
- className = '',
14
+ className = "",
15
15
  keepColors = false,
16
16
  ...restProps
17
17
  }: OverviewItemDepictionProps) => {
@@ -20,19 +20,11 @@ export const OverviewItemDepiction = ({
20
20
  border: false,
21
21
  backgroundColor: keepColors ? undefined : "dark",
22
22
  ratio: "1:1" as "1:1",
23
- padding: "medium" as "medium"
24
- }
23
+ padding: "medium" as "medium",
24
+ };
25
25
  // only return Depiction element if it is wrapped inside OverviewItemDepiction
26
- if (
27
- typeof children === "object" &&
28
- !!children &&
29
- "type" in children &&
30
- children.type === Depiction
31
- ) {
32
- return React.cloneElement(
33
- children,
34
- defaultDepictionDisplay
35
- );
26
+ if (typeof children === "object" && !!children && "type" in children && children.type === Depiction) {
27
+ return React.cloneElement(children, defaultDepictionDisplay);
36
28
  }
37
29
  // use Depiction element for basic icons
38
30
  if (
@@ -41,7 +33,7 @@ export const OverviewItemDepiction = ({
41
33
  "type" in children &&
42
34
  (children.type === Icon || children.type === TestIcon)
43
35
  ) {
44
- return <Depiction image={children} {...defaultDepictionDisplay} />
36
+ return <Depiction image={children as JSX.Element} {...defaultDepictionDisplay} />;
45
37
  }
46
38
  return (
47
39
  <div
@@ -54,7 +46,7 @@ export const OverviewItemDepiction = ({
54
46
  >
55
47
  {children}
56
48
  </div>
57
- )
58
- }
49
+ );
50
+ };
59
51
 
60
52
  export default OverviewItemDepiction;
@@ -1,16 +1,21 @@
1
1
  import React from "react";
2
2
 
3
3
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
4
- import Label from "../Label/Label";
4
+ import Label, { LabelProps } from "../Label/Label";
5
5
 
6
6
  export interface PropertyNameProps extends React.HTMLAttributes<HTMLElement> {
7
7
  /**
8
8
  * Increase or decrease the width used for the property name.
9
9
  */
10
10
  size?: "small" | "medium" | "large";
11
+ /**
12
+ * Additional label properties, e.g. `tooltip`.
13
+ * It is only used if the `PropertyName` has simple text input.
14
+ */
15
+ labelProps?: LabelProps;
11
16
  }
12
17
 
13
- export const PropertyName = ({ className = "", size, children, ...otherProps }: PropertyNameProps) => {
18
+ export const PropertyName = ({ className = "", size, children, labelProps, ...otherDtProps }: PropertyNameProps) => {
14
19
  return (
15
20
  <dt
16
21
  className={
@@ -18,9 +23,15 @@ export const PropertyName = ({ className = "", size, children, ...otherProps }:
18
23
  (size ? ` ${eccgui}-propertyvalue__property--${size}` : "") +
19
24
  (className ? " " + className : "")
20
25
  }
21
- {...otherProps}
26
+ {...otherDtProps}
22
27
  >
23
- <div>{typeof children === "string" ? <Label text={children} isLayoutForElement="span" /> : children}</div>
28
+ <div>
29
+ {typeof children === "string" ? (
30
+ <Label text={children} isLayoutForElement="span" {...labelProps} />
31
+ ) : (
32
+ children
33
+ )}
34
+ </div>
24
35
  </dt>
25
36
  );
26
37
  };
@@ -6,6 +6,7 @@
6
6
 
7
7
  .#{$eccgui}-propertyvalue__pair {
8
8
  display: block;
9
+ max-width: 100%;
9
10
  clear: both;
10
11
 
11
12
  &.#{$eccgui}-propertyvalue__pair--hasdivider {
@@ -1,38 +1,42 @@
1
1
  import React from "react";
2
+
2
3
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
3
4
 
4
- export interface SpacingProps {
5
+ export interface SpacingProps extends React.HTMLAttributes<HTMLDivElement> {
5
6
  /**
6
7
  * Set the amount of white space that separates two elements.
7
8
  */
8
- size?: "tiny" | "small" | "medium" | "large" | "xlarge"
9
+ size?: "tiny" | "small" | "medium" | "large" | "xlarge";
9
10
  /**
10
11
  * If set then is a ruler displayed in the middle of the spacing area.
11
12
  * The direction of the ruler is used from the spacing.
12
13
  */
13
- hasDivider?: boolean
14
+ hasDivider?: boolean;
14
15
  /**
15
16
  * If set then the spacing separates two elements on the horizontal axis.
16
17
  * The spacing area then is created on a vertical axis.
17
18
  */
18
- vertical?: boolean
19
+ vertical?: boolean;
19
20
  }
20
21
 
21
22
  /**
22
23
  * Adds horizontal or vertical space between neighbouring elements.
23
24
  * It also can add a visual ruler inside.
24
25
  */
25
- export const Spacing = ({ size = "medium", hasDivider = false, vertical = false }: SpacingProps) => {
26
+ export const Spacing = ({ size = "medium", hasDivider = false, vertical = false, ...otherDivProps }: SpacingProps) => {
26
27
  const direction = vertical ? "vertical" : "horizontal";
27
28
  return (
28
29
  <div
29
30
  className={
30
- `${eccgui}-separation__spacing-` + direction +
31
- ` ${eccgui}-separation__spacing--` + size +
31
+ `${eccgui}-separation__spacing-` +
32
+ direction +
33
+ ` ${eccgui}-separation__spacing--` +
34
+ size +
32
35
  (hasDivider ? ` ${eccgui}-separation__spacing--hasdivider` : "")
33
36
  }
37
+ {...otherDivProps}
34
38
  />
35
39
  );
36
- }
40
+ };
37
41
 
38
42
  export default Spacing;
@@ -3,49 +3,52 @@ import {
3
3
  TableExpandHeader as CarbonTableExpandHeader,
4
4
  TableExpandHeaderProps as CarbonTableExpandHeaderProps,
5
5
  } from "carbon-components-react";
6
- import IconButton from "./../Icon/IconButton";
6
+
7
7
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
8
+ import { TestIconProps } from "../Icon";
9
+ import { ValidIconName } from "../Icon/canonicalIconNames";
10
+
11
+ import IconButton from "./../Icon/IconButton";
8
12
 
9
- export interface TableExpandHeaderProps extends Omit<
10
- CarbonTableExpandHeaderProps,
11
- "children" | "ariaLabel" | "enableExpando" | "expandIconDescription"
12
- >, React.ThHTMLAttributes<HTMLTableCellElement> {
13
+ export interface TableExpandHeaderProps
14
+ extends Omit<CarbonTableExpandHeaderProps, "children" | "ariaLabel" | "enableExpando" | "expandIconDescription">,
15
+ React.ThHTMLAttributes<HTMLTableCellElement> {
13
16
  /**
14
17
  * This text is displayed as tooltip for the button that toggles the expanded/collapsed state.
15
18
  */
16
19
  togglerText: string;
17
- };
20
+
21
+ /** An optional icon that is shown as toggle icon. */
22
+ toggleIcon?: ValidIconName | string[] | React.ReactElement<TestIconProps>;
23
+ }
18
24
 
19
25
  /**
20
26
  * Adds a button to the table header that can trigger a function to expand/collapse all rows of the table.
21
27
  */
22
- export function TableExpandHeader ({
28
+ export function TableExpandHeader({
23
29
  togglerText,
24
30
  isExpanded,
25
31
  onExpand,
26
32
  className,
27
33
  enableToggle,
34
+ toggleIcon,
28
35
  ...otherCarbonTableExpandHeaderProps
29
36
  }: TableExpandHeaderProps) {
30
-
31
- const toggleButton = isExpanded ?
32
- React.cloneElement(<IconButton name="toggler-rowcollapse" text={togglerText} />, {onClick: onExpand}) :
33
- React.cloneElement(<IconButton name="toggler-rowexpand" text={togglerText} />, {onClick: onExpand});
34
-
37
+ const defaultToggleIcon = isExpanded ? "toggler-rowcollapse" : "toggler-rowexpand";
38
+ const toggleButton = React.cloneElement(<IconButton name={toggleIcon ?? defaultToggleIcon} text={togglerText} />, {
39
+ onClick: onExpand,
40
+ });
35
41
  return (
36
42
  <CarbonTableExpandHeader
37
- className={
38
- `${eccgui}-simpletable__headexpander` +
39
- (!!className ? ` ${className}` : "")
40
- }
43
+ className={`${eccgui}-simpletable__headexpander` + (className ? ` ${className}` : "")}
41
44
  isExpanded={isExpanded}
42
45
  onExpand={onExpand}
43
46
  enableToggle={false}
44
47
  {...otherCarbonTableExpandHeaderProps}
45
48
  >
46
- { enableToggle && toggleButton }
49
+ {enableToggle && toggleButton}
47
50
  </CarbonTableExpandHeader>
48
- )
51
+ );
49
52
  }
50
53
 
51
54
  export default TableExpandHeader;
@@ -1,15 +1,15 @@
1
- import React from "react";
1
+ import React, {KeyboardEventHandler, RefObject} from "react";
2
2
  import {
3
- InputGroup as BlueprintInputGroup,
4
3
  Classes as BlueprintClassNames,
5
- Intent as BlueprintIntent,
6
- MaybeElement,
7
4
  HTMLInputProps,
5
+ InputGroup as BlueprintInputGroup,
8
6
  InputGroupProps2,
7
+ Intent as BlueprintIntent,
8
+ MaybeElement,
9
9
  } from "@blueprintjs/core";
10
- import { IntentTypes, Definitions as IntentDefinitions } from "../../common/Intent";
10
+ import {Definitions as IntentDefinitions, IntentTypes} from "../../common/Intent";
11
11
  import Icon from "../Icon/Icon";
12
- import { CLASSPREFIX as eccgui } from "../../configuration/constants";
12
+ import {CLASSPREFIX as eccgui} from "../../configuration/constants";
13
13
  import {ValidIconName} from "../Icon/canonicalIconNames";
14
14
  import {InvisibleCharacterWarningProps, useTextValidation} from "./useTextValidation";
15
15
 
@@ -50,6 +50,9 @@ export interface TextFieldProps extends Partial<Omit<InputGroupProps2, "intent"
50
50
  * If set, allows to be informed of invisible, hard to spot characters in the string value.
51
51
  */
52
52
  invisibleCharacterWarning?: InvisibleCharacterWarningProps
53
+
54
+ /** If true pressing the Escape key will blur/de-focus the input field. Default: false */
55
+ escapeToBlur?: boolean
53
56
  }
54
57
 
55
58
  /**
@@ -64,8 +67,10 @@ export const TextField = ({
64
67
  fullWidth = true,
65
68
  leftIcon,
66
69
  invisibleCharacterWarning,
70
+ escapeToBlur = false,
67
71
  ...otherProps
68
72
  }: TextFieldProps) => {
73
+ const inputRef = React.useRef<HTMLInputElement | null>(null)
69
74
  let deprecatedIntent;
70
75
  switch (true) {
71
76
  case hasStatePrimary:
@@ -84,6 +89,25 @@ export const TextField = ({
84
89
  break;
85
90
  }
86
91
 
92
+ const handleLabelEscape = React.useCallback(() => {
93
+ inputRef.current?.blur()
94
+ if(otherProps.inputRef) {
95
+ const otherInputRef = otherProps.inputRef as RefObject<HTMLInputElement>
96
+ if(otherInputRef.current) {
97
+ otherInputRef.current.blur()
98
+ }
99
+ }
100
+ }, [])
101
+
102
+ const onKeyDown: KeyboardEventHandler<HTMLInputElement> = React.useCallback((event) => {
103
+ if(escapeToBlur && event.key === "Escape") {
104
+ event.preventDefault()
105
+ handleLabelEscape()
106
+ return false
107
+ }
108
+ return otherProps.onKeyDown?.(event)
109
+ }, [otherProps.onKeyDown, escapeToBlur])
110
+
87
111
  const {
88
112
  intent = deprecatedIntent,
89
113
  ...otherBlueprintInputGroupProps
@@ -110,6 +134,7 @@ export const TextField = ({
110
134
 
111
135
  return (
112
136
  <BlueprintInputGroup
137
+ inputRef={inputRef}
113
138
  className={
114
139
  `${eccgui}-textfield` +
115
140
  (intent ? ` ${eccgui}-intent--${intent}` : "") +
@@ -133,6 +158,7 @@ export const TextField = ({
133
158
  }
134
159
  dir={"auto"}
135
160
  onChange={maybeWrappedOnChange}
161
+ onKeyDown={otherProps.onKeyDown || escapeToBlur ? onKeyDown : undefined}
136
162
  />
137
163
  );
138
164
  }