@eccenca/gui-elements 23.1.0-easynav.0 → 23.1.0-easynav.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 (40) hide show
  1. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js +58 -0
  2. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js.map +1 -0
  3. package/dist/cjs/extensions/react-flow/handles/HandleDefault.js +10 -2
  4. package/dist/cjs/extensions/react-flow/handles/HandleDefault.js.map +1 -1
  5. package/dist/cjs/extensions/react-flow/index.js +11 -0
  6. package/dist/cjs/extensions/react-flow/index.js.map +1 -1
  7. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js +35 -12
  8. package/dist/cjs/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  9. package/dist/cjs/extensions/react-flow/nodes/NodeDefault.js +2 -1
  10. package/dist/cjs/extensions/react-flow/nodes/NodeDefault.js.map +1 -1
  11. package/dist/cjs/extensions/react-flow/versionsupport.js +17 -0
  12. package/dist/cjs/extensions/react-flow/versionsupport.js.map +1 -1
  13. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js +47 -0
  14. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js.map +1 -0
  15. package/dist/esm/extensions/react-flow/handles/HandleDefault.js +10 -2
  16. package/dist/esm/extensions/react-flow/handles/HandleDefault.js.map +1 -1
  17. package/dist/esm/extensions/react-flow/index.js +1 -0
  18. package/dist/esm/extensions/react-flow/index.js.map +1 -1
  19. package/dist/esm/extensions/react-flow/nodes/NodeContent.js +43 -19
  20. package/dist/esm/extensions/react-flow/nodes/NodeContent.js.map +1 -1
  21. package/dist/esm/extensions/react-flow/nodes/NodeDefault.js +2 -1
  22. package/dist/esm/extensions/react-flow/nodes/NodeDefault.js.map +1 -1
  23. package/dist/esm/extensions/react-flow/versionsupport.js +31 -1
  24. package/dist/esm/extensions/react-flow/versionsupport.js.map +1 -1
  25. package/dist/types/extensions/react-flow/edges/EdgeLabel.d.ts +32 -0
  26. package/dist/types/extensions/react-flow/index.d.ts +1 -0
  27. package/dist/types/extensions/react-flow/nodes/NodeContent.d.ts +16 -2
  28. package/dist/types/extensions/react-flow/versionsupport.d.ts +2 -1
  29. package/package.json +1 -1
  30. package/src/extensions/react-flow/_config.scss +1 -0
  31. package/src/extensions/react-flow/edges/EdgeLabel.tsx +83 -0
  32. package/src/extensions/react-flow/edges/_edges.scss +77 -0
  33. package/src/extensions/react-flow/edges/stories/EdgeLabel.stories.tsx +39 -0
  34. package/src/extensions/react-flow/handles/HandleDefault.tsx +18 -11
  35. package/src/extensions/react-flow/index.ts +1 -0
  36. package/src/extensions/react-flow/nodes/NodeContent.tsx +71 -22
  37. package/src/extensions/react-flow/nodes/NodeDefault.tsx +2 -2
  38. package/src/extensions/react-flow/nodes/_nodes.scss +43 -10
  39. package/src/extensions/react-flow/nodes/stories/NodeContent.stories.tsx +32 -1
  40. package/src/extensions/react-flow/versionsupport.ts +17 -1
@@ -1,11 +1,11 @@
1
1
  import React from "react";
2
2
  import { Position, useStoreState as useStoreStateFlowLegacy } from "react-flow-renderer";
3
3
  import { useStore as useStoreStateFlowNext } from "react-flow-renderer-lts";
4
- import { Icon, Depiction } from "../../../index";
4
+ import { Icon, Depiction, OverflowText } from "../../../index";
5
5
  import { CLASSPREFIX as eccgui } from "../../../configuration/constants";
6
6
  import { ValidIconName } from "../../../components/Icon/canonicalIconNames";
7
7
  import { DepictionProps } from "../../../components/Depiction/Depiction";
8
- import { ReacFlowVersionSupportProps } from "../versionsupport";
8
+ import { ReacFlowVersionSupportProps, useReactFlowVersion } from "../versionsupport";
9
9
  import { HandleDefault, HandleProps, HandleNextProps } from "./../handles/HandleDefault";
10
10
  import { NodeProps } from "./NodeDefault";
11
11
  import { NodeContentExtensionProps } from "./NodeContentExtension";
@@ -44,7 +44,11 @@ interface NodeContentData<CONTENT_PROPS = any> {
44
44
  /**
45
45
  * Label that is displayed in the node header.
46
46
  */
47
- label: string;
47
+ label: string | JSX.Element;
48
+ /**
49
+ * Element that is displayed as subline under the label in the header.
50
+ */
51
+ labelSubline?: JSX.Element;
48
52
  /**
49
53
  * Content element, displayed in the node body.
50
54
  */
@@ -72,6 +76,16 @@ export interface NodeContentProps<NODE_DATA, NODE_CONTENT_PROPS = any>
72
76
  * If not set to `none` then the node is only displayed in normal size when it is selected.
73
77
  */
74
78
  minimalShape?: "none" | "circular" | "rectangular";
79
+ /**
80
+ * Stretches the node to the full available width.
81
+ */
82
+ fullWidth?: boolean;
83
+ /**
84
+ * Increase the hight of the node header.
85
+ * Use this for example if you need more space for a label subline.
86
+ * Also the depiction is displayed larger.
87
+ */
88
+ increadeHeader?: boolean;
75
89
  /**
76
90
  * Set the type of used highlights to mark the node.
77
91
  */
@@ -181,7 +195,17 @@ interface MemoHandlerNextProps extends HandleNextProps {
181
195
 
182
196
  type MemoHandlerProps = MemoHandlerLegacyProps | MemoHandlerNextProps;
183
197
 
184
- const defaultHandles = [{ type: "target" }, { type: "source" }] as IHandleProps[];
198
+ const defaultHandles = () => {
199
+ const flowVersion = useReactFlowVersion();
200
+ switch (flowVersion) {
201
+ case "legacy":
202
+ return [{ type: "target" }, { type: "source" }] as IHandleProps[];
203
+ case "next":
204
+ return [{ type: "target" }, { type: "source" }] as NodeContentHandleNextProps[];
205
+ default:
206
+ return [];
207
+ }
208
+ }
185
209
 
186
210
  const getDefaultMinimalTooltipData = (node: any) => {
187
211
  return {
@@ -235,22 +259,25 @@ const MemoHandler = React.memo(
235
259
  * This element cannot be used directly, all properties must be routed through the `data` property of an `elements` property item inside the `ReactFlow` container.
236
260
  */
237
261
  export function NodeContent<CONTENT_PROPS = any>({
238
- flowVersion = "legacy",
262
+ flowVersion = useReactFlowVersion(),
239
263
  iconName,
240
264
  depiction,
241
265
  leftElement,
242
266
  typeLabel,
243
267
  label,
268
+ labelSubline,
269
+ increadeHeader,
270
+ fullWidth,
244
271
  showExecutionButtons = true,
245
272
  executionButtons,
246
273
  menuButtons,
247
274
  content,
248
275
  contentExtension,
249
- footerContent,
276
+ footerContent,
250
277
  size = "small",
251
278
  minimalShape = "circular",
252
279
  highlightedState,
253
- handles = defaultHandles,
280
+ handles = defaultHandles(),
254
281
  adaptHeightForHandleMinCount,
255
282
  adaptSizeIncrement = 15,
256
283
  getMinimalTooltipData = getDefaultMinimalTooltipData,
@@ -270,11 +297,15 @@ export function NodeContent<CONTENT_PROPS = any>({
270
297
  // other props for DOM element
271
298
  ...otherProps
272
299
  }: NodeContentProps<any>) {
300
+ const isResizeable = (!!onNodeResize && minimalShape === "none");
273
301
  const [width, setWidth] = React.useState<number>(nodeDimensions?.width ?? 0);
274
302
  const [height, setHeight] = React.useState<number>(nodeDimensions?.height ?? 0);
275
- const [, , zoom] = flowVersion === "legacy"
276
- ? useStoreStateFlowLegacy((state) => state.transform)
277
- : useStoreStateFlowNext((state) => state.transform);
303
+ let zoom = 1;
304
+ if (isResizeable) try {
305
+ [, , zoom] = flowVersion === "legacy"
306
+ ? useStoreStateFlowLegacy((state) => state.transform)
307
+ : useStoreStateFlowNext((state) => state.transform);
308
+ } catch {}
278
309
  const [adjustedContentProps, setAdjustedContentProps] = React.useState<Partial<CONTENT_PROPS>>({});
279
310
  const nodeContentRef = React.useRef<any>();
280
311
  const handleStack = flowVersion==="legacy" ? {} as { [key: string]: IHandleProps[] } : {} as { [key: string]: NodeContentHandleNextProps[] };
@@ -346,6 +377,7 @@ export function NodeContent<CONTENT_PROPS = any>({
346
377
  `${eccgui}-graphviz__node` +
347
378
  ` ${eccgui}-graphviz__node--${size}` +
348
379
  ` ${eccgui}-graphviz__node--minimal-${minimalShape}` +
380
+ (fullWidth ? ` ${eccgui}-graphviz__node--fullwidth` : "") +
349
381
  (!!highlightedState
350
382
  ? " " + gethighlightedStateClasses(highlightedState, `${eccgui}-graphviz__node`)
351
383
  : "") +
@@ -354,9 +386,12 @@ export function NodeContent<CONTENT_PROPS = any>({
354
386
  (letPassWheelEvents === false ? ` nowheel` : "")
355
387
  }
356
388
  >
357
- <header className={`${eccgui}-graphviz__node__header`}>
389
+ <header className={
390
+ `${eccgui}-graphviz__node__header` +
391
+ ((increadeHeader && minimalShape==="none") ? ` ${eccgui}-graphviz__node__header--large` : "")
392
+ }>
358
393
  {(!!iconName || !!depiction || !!leftElement) && (
359
- <span className={`${eccgui}-graphviz__node__header-depiction`}>
394
+ <div className={`${eccgui}-graphviz__node__header-depiction`}>
360
395
  { leftElement }
361
396
  {!!depiction && !leftElement && typeof depiction === "string" && (
362
397
  <Depiction
@@ -380,23 +415,37 @@ export function NodeContent<CONTENT_PROPS = any>({
380
415
  })
381
416
  )}
382
417
  {!!iconName && !leftElement && !depiction && (
383
- <Icon
384
- name={iconName}
385
- tooltipText={minimalShape === "none" || selected ? typeLabel : undefined}
418
+ <Depiction
419
+ image={<Icon name={iconName} />}
420
+ caption={minimalShape === "none" || selected ? typeLabel : undefined}
421
+ captionPosition="tooltip"
422
+ padding="tiny"
423
+ ratio="1:1"
424
+ resizing="contain"
425
+ forceInlineSvg
386
426
  />
387
427
  )}
388
- </span>
428
+ </div>
389
429
  )}
390
- <span className={`${eccgui}-graphviz__node__header-label`} title={label}>
391
- {label}
392
- </span>
430
+ <div className={`${eccgui}-graphviz__node__header-label`} title={typeof label==="string" ? label : undefined}>
431
+ {
432
+ typeof label === "string"
433
+ ? <OverflowText className={`${eccgui}-graphviz__node__header-label__mainline`}>{label}</OverflowText>
434
+ : <div className={`${eccgui}-graphviz__node__header-label__mainline`}>{label}</div>
435
+ }
436
+ {!!labelSubline && (
437
+ <div className={`${eccgui}-graphviz__node__header-label__subline`}>
438
+ { labelSubline }
439
+ </div>
440
+ )}
441
+ </div>
393
442
  {(menuButtons || (showExecutionButtons && executionButtons)) && (
394
- <span className={`${eccgui}-graphviz__node__header-menu`}>
443
+ <div className={`${eccgui}-graphviz__node__header-menu`}>
395
444
  {showExecutionButtons && typeof executionButtons === "function"
396
445
  ? executionButtons(adjustedContentProps, setAdjustedContentProps)
397
446
  : null}
398
447
  {menuButtons ?? null}
399
- </span>
448
+ </div>
400
449
  )}
401
450
  </header>
402
451
  {content && (
@@ -449,5 +498,5 @@ export function NodeContent<CONTENT_PROPS = any>({
449
498
  </Resizable>
450
499
  );
451
500
 
452
- return (!!onNodeResize && minimalShape === "none") ? resizableNode() : nodeContent;
501
+ return (isResizeable) ? resizableNode() : nodeContent;
453
502
  }
@@ -5,7 +5,7 @@ import {
5
5
  } from "react-flow-renderer";
6
6
  import { Tooltip } from "../../../index";
7
7
  import { NodeContent, NodeContentProps } from "./NodeContent";
8
- import { ReacFlowVersionSupportProps } from "../versionsupport";
8
+ import { ReacFlowVersionSupportProps, useReactFlowVersion } from "../versionsupport";
9
9
 
10
10
  export interface NodeProps<NODE_DATA, NODE_CONTENT_PROPS = any> extends ReacFlowVersionSupportProps, ReactFlowNodeProps {
11
11
  /**
@@ -23,7 +23,7 @@ export interface NodeProps<NODE_DATA, NODE_CONTENT_PROPS = any> extends ReacFlow
23
23
  export const NodeDefault = memo(
24
24
  (node: NodeProps<any>) => {
25
25
  const {
26
- flowVersion,
26
+ flowVersion = useReactFlowVersion(),
27
27
  data,
28
28
  targetPosition = Position.Left,
29
29
  sourcePosition = Position.Right,
@@ -120,22 +120,20 @@
120
120
  }
121
121
  }
122
122
 
123
+ .#{$eccgui}-graphviz__node__header--large {
124
+ min-height: $reactflow-node-largesize;
125
+ }
126
+
123
127
  .#{$eccgui}-graphviz__node__header-depiction,
124
128
  .#{$eccgui}-graphviz__node__header-menu {
125
129
  flex-grow: 0;
126
130
  flex-shrink: 0;
127
131
  max-height: calc(#{$reactflow-node-basesize} - #{2 * $reactflow-node-border-width});
128
- }
129
-
130
- .#{$eccgui}-graphviz__node__header-label {
131
132
  margin: 0 $eccgui-size-block-whitespace * 0.25;
132
- white-space: nowrap;
133
- overflow: hidden;
134
- text-overflow: ellipsis;
135
- flex-grow: 1;
136
- flex-shrink: 1;
137
- display: inline-block;
138
- text-align: left;
133
+
134
+ .#{$eccgui}-graphviz__node__header--large & {
135
+ max-height: calc(#{$reactflow-node-largesize} - #{2 * $reactflow-node-border-width});
136
+ }
139
137
  }
140
138
 
141
139
  .#{$eccgui}-graphviz__node__header-depiction {
@@ -165,6 +163,37 @@
165
163
  height: calc(#{$reactflow-node-basesize} - #{2 * $reactflow-node-border-width});
166
164
  }
167
165
  }
166
+
167
+ .#{$eccgui}-graphviz__node__header--large & {
168
+ min-width: calc(#{$reactflow-node-largesize} - #{2 * $reactflow-node-border-width});
169
+ min-height: calc(#{$reactflow-node-largesize} - #{2 * $reactflow-node-border-width});
170
+ max-width: calc(2 * (#{$reactflow-node-largesize} - #{2 * $reactflow-node-border-width}));
171
+
172
+ .#{$eccgui}-depiction__image {
173
+ height: calc(#{$reactflow-node-largesize} - #{2 * $reactflow-node-border-width});
174
+ }
175
+ }
176
+ }
177
+
178
+ .#{$eccgui}-graphviz__node__header-label {
179
+ margin: 0 $eccgui-size-block-whitespace * 0.25;
180
+ white-space: nowrap;
181
+ overflow: hidden;
182
+ text-overflow: ellipsis;
183
+ flex-grow: 1;
184
+ flex-shrink: 1;
185
+ display: inline-flex;
186
+ flex-direction: column;
187
+ text-align: left;
188
+ }
189
+
190
+ .#{$eccgui}-graphviz__node__header-label__mainline,
191
+ .#{$eccgui}-graphviz__node__header-label__subline {
192
+ overflow: hidden;
193
+ text-overflow: ellipsis;
194
+ white-space: nowrap;
195
+ flex-grow: 0;
196
+ flex-shrink: 0;
168
197
  }
169
198
 
170
199
  .#{$eccgui}-graphviz__node__content {
@@ -231,6 +260,10 @@
231
260
  max-height: $reactflow-node-basesize * 13;
232
261
  }
233
262
 
263
+ .#{$eccgui}-graphviz__node--fullwidth:not(.is-resizeable) {
264
+ width: 100%;
265
+ }
266
+
234
267
  // Node highlights
235
268
 
236
269
  .#{$eccgui}-graphviz__node--highlight-success,
@@ -1,10 +1,16 @@
1
1
  import React, { useState, useEffect, useCallback } from "react";
2
2
  import { ComponentStory, ComponentMeta } from "@storybook/react";
3
- import { LoremIpsum } from 'react-lorem-ipsum';
3
+ import { LoremIpsum, loremIpsum } from 'react-lorem-ipsum';
4
4
  import ReactFlow, { Elements, ReactFlowProvider } from 'react-flow-renderer';
5
5
  import {
6
+ Badge,
7
+ ContextMenu,
8
+ MenuItem,
6
9
  OverflowText,
7
10
  HtmlContentBlock,
11
+ IconButton,
12
+ Tag,
13
+ TagList,
8
14
  } from "./../../../../index";
9
15
  import canonicalIcons from "./../../../../components/Icon/canonicalIconNames";
10
16
 
@@ -30,6 +36,31 @@ export default {
30
36
  "Slide out example": <NodeContentExtension {...ContentExtensionExampleSlideOut.args} />,
31
37
  },
32
38
  },
39
+ labelSubline: {
40
+ control: "select",
41
+ options: ["Not set", "Text string", "OverflowText element", "Tag list"],
42
+ mapping: {
43
+ "Not set": undefined,
44
+ "Text string": loremIpsum({ p: 1, avgSentencesPerParagraph: 1, avgWordsPerSentence: 8, random: false }).toString(),
45
+ "OverflowText element": <OverflowText>{loremIpsum({ p: 1, avgSentencesPerParagraph: 2, avgWordsPerSentence: 4, random: false }).toString()}</OverflowText>,
46
+ "Tag list": <TagList>{
47
+ loremIpsum({ p: 1, avgSentencesPerParagraph: 1, avgWordsPerSentence: 5, random: false })
48
+ .toString()
49
+ .split(" ")
50
+ .map((term) => <Tag small>{term}</Tag>)
51
+ }</TagList>
52
+ },
53
+ },
54
+ menuButtons: {
55
+ control: "select",
56
+ options: ["Not set", "Icon button", "Context Menu", "Info badge"],
57
+ mapping: {
58
+ "Not set": undefined,
59
+ "Icon button": <IconButton name="item-info" text="Icon button" onClick={()=>alert("Click info")} />,
60
+ "Context Menu": <ContextMenu><MenuItem text="Context menu" /></ContextMenu>,
61
+ "Info badge": <Badge intent="info">Info</Badge>,
62
+ },
63
+ },
33
64
  iconName: {
34
65
  control: "select",
35
66
  options: [...(Object.keys(canonicalIcons))],
@@ -1,6 +1,22 @@
1
+ import { useStoreState as useStoreStateFlowLegacy } from "react-flow-renderer";
2
+ import { useStore as useStoreStateFlowNext } from "react-flow-renderer-lts";
3
+
1
4
  export interface ReacFlowVersionSupportProps {
2
5
  /**
3
6
  * Spevifies the context of the react flow renderer version that is used for the component.
4
7
  */
5
- flowVersion?: "legacy" | "next";
8
+ flowVersion?: "legacy" | "next" | "none";
9
+ }
10
+
11
+ export const useReactFlowVersion = () => {
12
+ try {
13
+ const [, , zoom] = useStoreStateFlowLegacy((state) => state.transform);
14
+ return !!zoom ? "legacy" : "none";
15
+ } catch {}
16
+ try {
17
+ const [, , zoom] = useStoreStateFlowNext((state) => state.transform);
18
+ return !!zoom ? "next" : "none";
19
+ } catch {}
20
+
21
+ return "none";
6
22
  }