@eccenca/gui-elements 24.1.0-rc.3 → 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.
- package/CHANGELOG.md +36 -2
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js +5 -3
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
- package/dist/cjs/components/AutocompleteField/AutoCompleteField.js +4 -2
- package/dist/cjs/components/AutocompleteField/AutoCompleteField.js.map +1 -1
- package/dist/cjs/components/Card/CardActions.js +2 -1
- package/dist/cjs/components/Card/CardActions.js.map +1 -1
- package/dist/cjs/components/Card/CardContent.js +4 -6
- package/dist/cjs/components/Card/CardContent.js.map +1 -1
- package/dist/cjs/components/Dialog/SimpleDialog.js +3 -3
- package/dist/cjs/components/Dialog/SimpleDialog.js.map +1 -1
- package/dist/cjs/components/Icon/canonicalIconNames.js +2 -0
- package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/cjs/components/Label/Label.js +2 -1
- package/dist/cjs/components/Label/Label.js.map +1 -1
- package/dist/cjs/components/Menu/MenuItem.js +3 -2
- package/dist/cjs/components/Menu/MenuItem.js.map +1 -1
- package/dist/cjs/components/Switch/Switch.js +6 -4
- package/dist/cjs/components/Switch/Switch.js.map +1 -1
- package/dist/cjs/components/Tag/TagList.js +1 -1
- package/dist/cjs/components/Tag/TagList.js.map +1 -1
- package/dist/cjs/extensions/codemirror/CodeMirror.js +17 -16
- package/dist/cjs/extensions/codemirror/CodeMirror.js.map +1 -1
- package/dist/cjs/extensions/codemirror/tests/codemirrorTestHelper.js +4 -1
- package/dist/cjs/extensions/codemirror/tests/codemirrorTestHelper.js.map +1 -1
- package/dist/cjs/extensions/react-flow/nodes/NodeContent.js +136 -41
- package/dist/cjs/extensions/react-flow/nodes/NodeContent.js.map +1 -1
- package/dist/cjs/extensions/react-flow/nodes/nodeUtils.js +5 -6
- package/dist/cjs/extensions/react-flow/nodes/nodeUtils.js.map +1 -1
- package/dist/esm/components/AutoSuggestion/AutoSuggestion.js +5 -3
- package/dist/esm/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
- package/dist/esm/components/AutocompleteField/AutoCompleteField.js +4 -3
- package/dist/esm/components/AutocompleteField/AutoCompleteField.js.map +1 -1
- package/dist/esm/components/Card/CardActions.js +2 -1
- package/dist/esm/components/Card/CardActions.js.map +1 -1
- package/dist/esm/components/Card/CardContent.js +4 -5
- package/dist/esm/components/Card/CardContent.js.map +1 -1
- package/dist/esm/components/Dialog/SimpleDialog.js +4 -4
- package/dist/esm/components/Dialog/SimpleDialog.js.map +1 -1
- package/dist/esm/components/Icon/canonicalIconNames.js +2 -0
- package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/esm/components/Label/Label.js +2 -1
- package/dist/esm/components/Label/Label.js.map +1 -1
- package/dist/esm/components/Menu/MenuItem.js +3 -2
- package/dist/esm/components/Menu/MenuItem.js.map +1 -1
- package/dist/esm/components/Switch/Switch.js +7 -5
- package/dist/esm/components/Switch/Switch.js.map +1 -1
- package/dist/esm/components/Tag/TagList.js +1 -1
- package/dist/esm/components/Tag/TagList.js.map +1 -1
- package/dist/esm/extensions/codemirror/CodeMirror.js +18 -17
- package/dist/esm/extensions/codemirror/CodeMirror.js.map +1 -1
- package/dist/esm/extensions/codemirror/tests/codemirrorTestHelper.js +4 -0
- package/dist/esm/extensions/codemirror/tests/codemirrorTestHelper.js.map +1 -1
- package/dist/esm/extensions/react-flow/nodes/NodeContent.js +145 -48
- package/dist/esm/extensions/react-flow/nodes/NodeContent.js.map +1 -1
- package/dist/esm/extensions/react-flow/nodes/nodeUtils.js +5 -6
- package/dist/esm/extensions/react-flow/nodes/nodeUtils.js.map +1 -1
- package/dist/types/components/Card/CardActions.d.ts +5 -1
- package/dist/types/components/Card/CardContent.d.ts +1 -2
- package/dist/types/components/Dialog/SimpleDialog.d.ts +4 -1
- package/dist/types/components/Icon/canonicalIconNames.d.ts +2 -0
- package/dist/types/components/Label/Label.d.ts +3 -1
- package/dist/types/components/Menu/MenuItem.d.ts +8 -1
- package/dist/types/components/Switch/Switch.d.ts +3 -3
- package/dist/types/extensions/codemirror/tests/codemirrorTestHelper.d.ts +1 -0
- package/dist/types/extensions/react-flow/nodes/NodeContent.d.ts +18 -4
- package/dist/types/extensions/react-flow/nodes/nodeUtils.d.ts +7 -6
- package/package.json +2 -2
- package/src/cmem/react-flow/configuration/_colors-graph.scss +4 -1
- package/src/cmem/react-flow/configuration/_colors-workflow.scss +3 -0
- package/src/components/AutoSuggestion/AutoSuggestion.tsx +5 -3
- package/src/components/AutocompleteField/AutoCompleteField.tsx +5 -3
- package/src/components/Card/CardActions.tsx +6 -0
- package/src/components/Card/CardContent.tsx +8 -4
- package/src/components/Card/card.scss +15 -0
- package/src/components/Dialog/SimpleDialog.tsx +9 -2
- package/src/components/Icon/canonicalIconNames.tsx +2 -0
- package/src/components/Label/Label.tsx +4 -0
- package/src/components/Label/label.scss +5 -1
- package/src/components/Menu/MenuItem.tsx +27 -1
- package/src/components/Menu/menu.scss +1 -0
- package/src/components/OverviewItem/overviewitem.scss +4 -1
- package/src/components/Switch/Switch.tsx +27 -8
- package/src/components/Tag/TagList.tsx +2 -2
- package/src/extensions/codemirror/CodeMirror.tsx +18 -16
- package/src/extensions/codemirror/tests/codemirrorTestHelper.ts +4 -0
- package/src/extensions/react-flow/_config.scss +1 -0
- package/src/extensions/react-flow/nodes/NodeContent.tsx +166 -52
- package/src/extensions/react-flow/nodes/_nodes.scss +71 -35
- package/src/extensions/react-flow/nodes/nodeUtils.tsx +16 -14
- package/src/extensions/react-flow/nodes/stories/NodeContent.stories.tsx +6 -3
|
@@ -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 = ({
|
|
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)
|
|
@@ -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
|
|
2
|
-
import {
|
|
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) =>
|
|
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:
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
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 = [
|
|
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 (
|
|
324
|
-
|
|
325
|
-
|
|
323
|
+
if (view?.dom) {
|
|
324
|
+
if (height) {
|
|
325
|
+
view.dom.style.height = typeof height === "string" ? height : `${height}px`;
|
|
326
|
+
}
|
|
326
327
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
if (disabled) {
|
|
329
|
+
view.dom.className += ` ${eccgui}-disabled`;
|
|
330
|
+
}
|
|
330
331
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
332
|
+
if (intent) {
|
|
333
|
+
view.dom.className += ` ${eccgui}-intent--${intent}`;
|
|
334
|
+
}
|
|
334
335
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
336
|
+
if (autoFocus) {
|
|
337
|
+
view.focus();
|
|
338
|
+
}
|
|
338
339
|
|
|
339
|
-
|
|
340
|
-
|
|
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;
|
|
@@ -22,11 +22,16 @@ type NodeContentHandleNextProps = HandleNextProps;
|
|
|
22
22
|
|
|
23
23
|
export type NodeContentHandleProps = NodeContentHandleLegacyProps | NodeContentHandleNextProps;
|
|
24
24
|
|
|
25
|
-
type NodeDimensions = {
|
|
26
|
-
width
|
|
27
|
-
height
|
|
25
|
+
export type NodeDimensions = {
|
|
26
|
+
width?: number;
|
|
27
|
+
height?: number;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
+
type ResizeDirections =
|
|
31
|
+
| { right: true; bottom?: false }
|
|
32
|
+
| { right?: false; bottom: true }
|
|
33
|
+
| { right: true; bottom: true };
|
|
34
|
+
|
|
30
35
|
type IntroductionTime = {
|
|
31
36
|
/**
|
|
32
37
|
* The delay time in ms before the introduction animation is displayed.
|
|
@@ -210,6 +215,10 @@ export interface NodeContentProps<NODE_DATA, NODE_CONTENT_PROPS = any>
|
|
|
210
215
|
* width and height dimensions of the node (Optional)
|
|
211
216
|
*/
|
|
212
217
|
nodeDimensions?: NodeDimensions;
|
|
218
|
+
/** if node is resizable, this allows direction of specificity */
|
|
219
|
+
resizeDirections?: ResizeDirections;
|
|
220
|
+
/** determines how much width a node can be resized to */
|
|
221
|
+
resizeMaxDimensions?: Partial<NodeDimensions>;
|
|
213
222
|
}
|
|
214
223
|
|
|
215
224
|
interface MemoHandlerLegacyProps extends HandleProps {
|
|
@@ -317,20 +326,24 @@ export function NodeContent<CONTENT_PROPS = any>({
|
|
|
317
326
|
//handles = defaultHandles(),
|
|
318
327
|
adaptHeightForHandleMinCount,
|
|
319
328
|
adaptSizeIncrement = 15,
|
|
329
|
+
// FIXME: getMinimalTooltipData is just being ignored, only used in `NodeDefault`
|
|
320
330
|
getMinimalTooltipData = getDefaultMinimalTooltipData,
|
|
321
331
|
style = {},
|
|
322
332
|
showUnconnectableHandles = false,
|
|
323
333
|
animated = false,
|
|
324
334
|
introductionTime = 0,
|
|
335
|
+
// resizing
|
|
325
336
|
onNodeResize,
|
|
326
337
|
nodeDimensions,
|
|
338
|
+
resizeDirections = { bottom: true, right: true },
|
|
339
|
+
resizeMaxDimensions,
|
|
327
340
|
// forwarded props
|
|
328
341
|
targetPosition = Position.Left,
|
|
329
342
|
sourcePosition = Position.Right,
|
|
330
343
|
isConnectable = true,
|
|
331
344
|
selected,
|
|
332
345
|
letPassWheelEvents = false,
|
|
333
|
-
// businessData is just being ignored
|
|
346
|
+
// FIXME: businessData is just being ignored
|
|
334
347
|
businessData,
|
|
335
348
|
// other props for DOM element
|
|
336
349
|
...otherDomProps
|
|
@@ -341,11 +354,16 @@ export function NodeContent<CONTENT_PROPS = any>({
|
|
|
341
354
|
|
|
342
355
|
const { handles = defaultHandles(flowVersionCheck), ...otherProps } = otherDomProps;
|
|
343
356
|
|
|
344
|
-
const
|
|
345
|
-
const
|
|
346
|
-
|
|
357
|
+
const hasValidResizeDirection = resizeDirections.bottom || resizeDirections.right;
|
|
358
|
+
const isResizable = typeof onNodeResize === "function" && hasValidResizeDirection && minimalShape === "none";
|
|
359
|
+
|
|
360
|
+
const [width, setWidth] = React.useState<number | undefined>(nodeDimensions?.width ?? undefined);
|
|
361
|
+
const [height, setHeight] = React.useState<number | undefined>(nodeDimensions?.height ?? undefined);
|
|
362
|
+
// Keeps the initial size of the element
|
|
363
|
+
const originalSize = React.useRef<NodeDimensions>({})
|
|
364
|
+
|
|
347
365
|
let zoom = 1;
|
|
348
|
-
if (
|
|
366
|
+
if (isResizable)
|
|
349
367
|
try {
|
|
350
368
|
[, , zoom] =
|
|
351
369
|
flowVersionCheck === "legacy"
|
|
@@ -371,29 +389,71 @@ export function NodeContent<CONTENT_PROPS = any>({
|
|
|
371
389
|
handleStack[Position.Left] =
|
|
372
390
|
flowVersionCheck === "legacy" ? ([] as NodeContentHandleLegacyProps[]) : ([] as NodeContentHandleNextProps[]);
|
|
373
391
|
|
|
374
|
-
|
|
392
|
+
const saveOriginalSize = () => {
|
|
393
|
+
originalSize.current.width = nodeContentRef.current.offsetWidth as number;
|
|
394
|
+
originalSize.current.height = nodeContentRef.current.offsetHeight as number;
|
|
395
|
+
}
|
|
396
|
+
|
|
375
397
|
React.useEffect(() => {
|
|
376
|
-
if
|
|
377
|
-
|
|
378
|
-
setWidth(nodeContentRef.current.offsetWidth);
|
|
379
|
-
setHeight(nodeContentRef.current.offsetHeight);
|
|
380
|
-
onNodeResize({
|
|
381
|
-
height: nodeContentRef.current.offsetHeight,
|
|
382
|
-
width: nodeContentRef.current.offsetWidth,
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
nodeContentRef.current.className = nodeContentRef.current.className + " is-resizeable";
|
|
398
|
+
if(nodeContentRef.current && !(originalSize.current.width || originalSize.current.height)) {
|
|
399
|
+
saveOriginalSize();
|
|
386
400
|
}
|
|
387
|
-
}, [nodeContentRef,
|
|
401
|
+
}, [!!nodeContentRef.current, !(originalSize.current.width || originalSize.current.height)])
|
|
388
402
|
|
|
389
|
-
//
|
|
403
|
+
// Update width and height when node dimensions parameters has changed
|
|
390
404
|
React.useEffect(() => {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
405
|
+
const updateWidth = nodeDimensions?.width ? validateWidth(nodeDimensions?.width) : undefined;
|
|
406
|
+
const updateHeight = nodeDimensions?.height ? validateHeight(nodeDimensions?.height) : undefined;
|
|
407
|
+
setWidth(updateWidth);
|
|
408
|
+
setHeight(updateHeight);
|
|
409
|
+
if (!nodeDimensions?.width && !nodeDimensions?.height) {
|
|
410
|
+
// provoke new measuring if no dimensions are set
|
|
411
|
+
saveOriginalSize();
|
|
394
412
|
}
|
|
395
413
|
}, [nodeDimensions]);
|
|
396
414
|
|
|
415
|
+
const isResizingActive = React.useCallback((): boolean => {
|
|
416
|
+
const currentClassNames = nodeContentRef.current.classList;
|
|
417
|
+
return resizeDirections.right === currentClassNames.contains("is-resizable-horizontal") &&
|
|
418
|
+
resizeDirections.bottom === currentClassNames.contains("is-resizable-vertical");
|
|
419
|
+
}, [])
|
|
420
|
+
|
|
421
|
+
// force default size when resizing is activated but no dimensions are set
|
|
422
|
+
React.useEffect(() => {
|
|
423
|
+
const resizingActive = isResizingActive();
|
|
424
|
+
|
|
425
|
+
if (isResizable && !resizingActive) {
|
|
426
|
+
if (!width || !height) {
|
|
427
|
+
const newWidth = validateWidth(width ?? originalSize.current?.width as number);
|
|
428
|
+
const newHeight = validateHeight(height ?? originalSize.current?.height as number);
|
|
429
|
+
setWidth(newWidth);
|
|
430
|
+
setHeight(newHeight);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}, [nodeContentRef.current, onNodeResize, minimalShape, resizeDirections?.bottom, resizeDirections?.right, width, height]); // need to be done everytime a property is changed and the element is re-rendered, otherwise the resizing class is lost
|
|
434
|
+
|
|
435
|
+
// conditional enhancements for activated resizing
|
|
436
|
+
React.useEffect(() => {
|
|
437
|
+
const currentClassNames = nodeContentRef.current.classList;
|
|
438
|
+
const resizingActive = isResizingActive();
|
|
439
|
+
|
|
440
|
+
if (isResizable && !resizingActive) {
|
|
441
|
+
if (currentClassNames.contains("is-resizable-horizontal")) {
|
|
442
|
+
nodeContentRef.current.classList.remove("is-resizable-horizontal");
|
|
443
|
+
}
|
|
444
|
+
if (currentClassNames.contains("is-resizable-vertical")) {
|
|
445
|
+
nodeContentRef.current.classList.remove("is-resizable-vertical");
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (resizeDirections.right) {
|
|
449
|
+
nodeContentRef.current.classList.add("is-resizable-horizontal");
|
|
450
|
+
}
|
|
451
|
+
if (resizeDirections.bottom) {
|
|
452
|
+
nodeContentRef.current.classList.add("is-resizable-vertical");
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}); // need to be done everytime a property is changed and the element is re-rendered, otherwise the resizing class is lost
|
|
456
|
+
|
|
397
457
|
// remove introduction class
|
|
398
458
|
React.useEffect(() => {
|
|
399
459
|
if (nodeContentRef && introductionTime) {
|
|
@@ -460,7 +520,14 @@ export function NodeContent<CONTENT_PROPS = any>({
|
|
|
460
520
|
);
|
|
461
521
|
|
|
462
522
|
const resizableStyles =
|
|
463
|
-
|
|
523
|
+
isResizable && (width ?? 0) + (height ?? 0) > 0
|
|
524
|
+
? {
|
|
525
|
+
width,
|
|
526
|
+
height,
|
|
527
|
+
maxWidth: resizeMaxDimensions?.width ?? undefined,
|
|
528
|
+
maxHeight: resizeMaxDimensions?.height ?? undefined,
|
|
529
|
+
}
|
|
530
|
+
: {};
|
|
464
531
|
|
|
465
532
|
const introductionStyles =
|
|
466
533
|
introductionTime && !introductionDone
|
|
@@ -470,6 +537,7 @@ export function NodeContent<CONTENT_PROPS = any>({
|
|
|
470
537
|
}ms`,
|
|
471
538
|
} as React.CSSProperties)
|
|
472
539
|
: {};
|
|
540
|
+
|
|
473
541
|
const nodeContent = (
|
|
474
542
|
<>
|
|
475
543
|
<section
|
|
@@ -590,34 +658,80 @@ export function NodeContent<CONTENT_PROPS = any>({
|
|
|
590
658
|
</>
|
|
591
659
|
);
|
|
592
660
|
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
661
|
+
const validateWidth = (resizedWidth: number): number | undefined => {
|
|
662
|
+
// only allow value if resize direction is allowed
|
|
663
|
+
if (!resizeDirections.right) {
|
|
664
|
+
return undefined;
|
|
665
|
+
}
|
|
666
|
+
// we need to check because there is probably a min value defined via CSS
|
|
667
|
+
const min = parseFloat(getComputedStyle(nodeContentRef.current).getPropertyValue("min-width"));
|
|
668
|
+
// we need to check for a given max value
|
|
669
|
+
const max = resizeMaxDimensions?.width ?? Infinity;
|
|
670
|
+
const validatedWidth = Math.max(Math.min(resizedWidth, max), min);
|
|
671
|
+
return validatedWidth;
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
const validateHeight = (resizedHeight: number): number | undefined => {
|
|
675
|
+
if (!resizeDirections.bottom) {
|
|
676
|
+
return undefined;
|
|
677
|
+
}
|
|
678
|
+
// we need to check because there is probably a min value defined via CSS
|
|
679
|
+
const min = parseFloat(getComputedStyle(nodeContentRef.current).getPropertyValue("min-height"));
|
|
680
|
+
const max = resizeMaxDimensions?.height ?? Infinity;
|
|
681
|
+
const validatedHeight = Math.max(Math.min(resizedHeight, max), min);
|
|
682
|
+
return validatedHeight;
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
const resizableNode = () => {
|
|
686
|
+
const size = { height: height ?? "auto", width: width ?? "auto" };
|
|
687
|
+
return (
|
|
688
|
+
<Resizable
|
|
689
|
+
className={
|
|
690
|
+
`${eccgui}-graphviz__node__resizer` +
|
|
691
|
+
(resizeDirections.right ? ` ${eccgui}-graphviz__node__resizer--right` : "") +
|
|
692
|
+
(resizeDirections.bottom ? ` ${eccgui}-graphviz__node__resizer--bottom` : "")
|
|
604
693
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
694
|
+
handleWrapperClass={`${eccgui}-graphviz__node__resizer--cursorhandles` + " nodrag"}
|
|
695
|
+
size={size}
|
|
696
|
+
maxHeight={resizeMaxDimensions?.height ?? undefined}
|
|
697
|
+
maxWidth={resizeMaxDimensions?.width ?? undefined}
|
|
698
|
+
enable={resizeDirections.bottom && resizeDirections.right ? { bottomRight: true } : resizeDirections}
|
|
699
|
+
scale={zoom}
|
|
700
|
+
onResize={(_0, _1, _2, d) => {
|
|
701
|
+
if (nodeContentRef.current) {
|
|
702
|
+
const nextWidth = resizeDirections.right
|
|
703
|
+
? (width ?? originalSize.current.width ?? 0) + d.width
|
|
704
|
+
: undefined;
|
|
705
|
+
const nextHeight = resizeDirections.bottom
|
|
706
|
+
? (height ?? originalSize.current.height ?? 0) + d.height
|
|
707
|
+
: undefined;
|
|
708
|
+
if (nextWidth) {
|
|
709
|
+
nodeContentRef.current.style.width = `${nextWidth}px`;
|
|
710
|
+
}
|
|
711
|
+
if (nextHeight) {
|
|
712
|
+
nodeContentRef.current.style.height = `${nextHeight}px`;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}}
|
|
716
|
+
onResizeStop={(_0, _1, _2, d) => {
|
|
717
|
+
const nextWidth = validateWidth((width ?? originalSize.current.width ?? 0) + d.width);
|
|
718
|
+
const nextHeight = validateHeight((height ?? originalSize.current.height ?? 0) + d.height);
|
|
719
|
+
setWidth(nextWidth);
|
|
720
|
+
setHeight(nextHeight);
|
|
721
|
+
if (onNodeResize) {
|
|
722
|
+
onNodeResize({
|
|
723
|
+
height: nextHeight,
|
|
724
|
+
width: nextWidth,
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
}}
|
|
728
|
+
>
|
|
729
|
+
{nodeContent}
|
|
730
|
+
</Resizable>
|
|
731
|
+
);
|
|
732
|
+
};
|
|
619
733
|
|
|
620
|
-
return
|
|
734
|
+
return isResizable ? resizableNode() : nodeContent;
|
|
621
735
|
}
|
|
622
736
|
|
|
623
737
|
const evaluateHighlightColors = (
|
|
@@ -644,7 +758,7 @@ const evaluateHighlightColors = (
|
|
|
644
758
|
let customColor = Color("#ffffff");
|
|
645
759
|
try {
|
|
646
760
|
customColor = Color(color);
|
|
647
|
-
} catch
|
|
761
|
+
} catch {
|
|
648
762
|
// eslint-disable-next-line no-console
|
|
649
763
|
console.warn("Received invalid color for highlight: " + color);
|
|
650
764
|
}
|
|
@@ -49,6 +49,38 @@
|
|
|
49
49
|
&:hover {
|
|
50
50
|
box-shadow: 0 0 0 6 * $reactflow-node-border-width rgba($reactflow-edge-stroke-color-selected, 0.05);
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
&.is-resizable-vertical {
|
|
54
|
+
max-height: unset;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.#{$eccgui}-graphviz__node--tiny {
|
|
59
|
+
width: $reactflow-node-basesize * 4;
|
|
60
|
+
min-height: $reactflow-node-basesize;
|
|
61
|
+
max-height: $reactflow-node-basesize * 4;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.#{$eccgui}-graphviz__node--small {
|
|
65
|
+
width: $reactflow-node-basesize * 5;
|
|
66
|
+
min-height: $reactflow-node-basesize;
|
|
67
|
+
max-height: $reactflow-node-basesize * 8;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.#{$eccgui}-graphviz__node--medium {
|
|
71
|
+
width: $reactflow-node-basesize * 8;
|
|
72
|
+
min-height: $reactflow-node-basesize;
|
|
73
|
+
max-height: $reactflow-node-basesize * 13;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.#{$eccgui}-graphviz__node--large {
|
|
77
|
+
width: $reactflow-node-basesize * 13;
|
|
78
|
+
min-height: $reactflow-node-basesize;
|
|
79
|
+
max-height: $reactflow-node-basesize * 13;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.#{$eccgui}-graphviz__node--fullwidth {
|
|
83
|
+
width: 100%;
|
|
52
84
|
}
|
|
53
85
|
|
|
54
86
|
.#{$eccgui}-graphviz__node--minimal-rectangular,
|
|
@@ -200,54 +232,58 @@
|
|
|
200
232
|
background-color: $reactflow-node-background-color;
|
|
201
233
|
}
|
|
202
234
|
|
|
203
|
-
// Node
|
|
235
|
+
// Node Resizer
|
|
204
236
|
|
|
205
|
-
.#{$eccgui}-
|
|
206
|
-
.#{$eccgui}-graphviz__node.is-
|
|
237
|
+
.#{$eccgui}-graphviz__node.is-resizable-horizontal,
|
|
238
|
+
.#{$eccgui}-graphviz__node.is-resizable-vertical {
|
|
207
239
|
min-width: 2.5 * $reactflow-node-basesize;
|
|
208
240
|
min-height: 2.5 * $reactflow-node-basesize;
|
|
209
241
|
}
|
|
210
242
|
|
|
243
|
+
.#{$eccgui}-graphviz__node__resizer--cursorhandles {
|
|
244
|
+
position: absolute;
|
|
245
|
+
height: 0;
|
|
246
|
+
width: 0;
|
|
247
|
+
bottom: 0;
|
|
248
|
+
right: 0;
|
|
249
|
+
overflow: visible;
|
|
250
|
+
display: none;
|
|
251
|
+
|
|
252
|
+
& > div {
|
|
253
|
+
overflow: visible;
|
|
254
|
+
z-index: 0 !important;
|
|
255
|
+
height: $reactflow-cursor-delimiter-offset * 3 !important;
|
|
256
|
+
width: $reactflow-cursor-delimiter-offset * 3 !important;
|
|
257
|
+
top: unset !important;
|
|
258
|
+
left: unset !important;
|
|
259
|
+
bottom: -1 * $reactflow-cursor-delimiter-offset !important;
|
|
260
|
+
right: -1 * $reactflow-cursor-delimiter-offset !important;
|
|
261
|
+
border-bottom: $reactflow-node-border-width solid $reactflow-node-border-color;
|
|
262
|
+
border-right: $reactflow-node-border-width solid $reactflow-node-border-color;
|
|
263
|
+
|
|
264
|
+
.#{$eccgui}-graphviz__node__resizer--right:not(.#{$eccgui}-graphviz__node__resizer--bottom) & {
|
|
265
|
+
bottom: 0 !important;
|
|
266
|
+
border-bottom: none;
|
|
267
|
+
}
|
|
268
|
+
.#{$eccgui}-graphviz__node__resizer--bottom:not(.#{$eccgui}-graphviz__node__resizer--right) & {
|
|
269
|
+
right: 0 !important;
|
|
270
|
+
border-right: none;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
211
275
|
.#{$eccgui}-graphviz__node__resizer {
|
|
276
|
+
min-width: 2.5 * $reactflow-node-basesize;
|
|
277
|
+
min-height: 2.5 * $reactflow-node-basesize;
|
|
278
|
+
|
|
212
279
|
.selected &,
|
|
213
280
|
&:hover {
|
|
214
281
|
.#{$eccgui}-graphviz__node__resizer--cursorhandles {
|
|
215
|
-
|
|
216
|
-
overflow: auto;
|
|
217
|
-
resize: both;
|
|
218
|
-
}
|
|
282
|
+
display: block;
|
|
219
283
|
}
|
|
220
284
|
}
|
|
221
285
|
}
|
|
222
286
|
|
|
223
|
-
.#{$eccgui}-graphviz__node--tiny:not(.is-resizeable) {
|
|
224
|
-
width: $reactflow-node-basesize * 4;
|
|
225
|
-
min-height: $reactflow-node-basesize;
|
|
226
|
-
max-height: $reactflow-node-basesize * 4;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.#{$eccgui}-graphviz__node--small:not(.is-resizeable) {
|
|
230
|
-
width: $reactflow-node-basesize * 5;
|
|
231
|
-
min-height: $reactflow-node-basesize;
|
|
232
|
-
max-height: $reactflow-node-basesize * 8;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.#{$eccgui}-graphviz__node--medium:not(.is-resizeable) {
|
|
236
|
-
width: $reactflow-node-basesize * 8;
|
|
237
|
-
min-height: $reactflow-node-basesize;
|
|
238
|
-
max-height: $reactflow-node-basesize * 13;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
.#{$eccgui}-graphviz__node--large:not(.is-resizeable) {
|
|
242
|
-
width: $reactflow-node-basesize * 13;
|
|
243
|
-
min-height: $reactflow-node-basesize;
|
|
244
|
-
max-height: $reactflow-node-basesize * 13;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
.#{$eccgui}-graphviz__node--fullwidth:not(.is-resizeable) {
|
|
248
|
-
width: 100%;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
287
|
// Node border overwrites
|
|
252
288
|
|
|
253
289
|
.#{$eccgui}-graphviz__node--border-solid {
|