@hpcc-js/react 2.54.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/index.js +2 -575
  2. package/dist/index.js.map +7 -1
  3. package/package.json +34 -33
  4. package/src/ImageChar.tsx +12 -9
  5. package/src/__package__.ts +2 -2
  6. package/src/edge.tsx +3 -3
  7. package/src/icon.tsx +10 -10
  8. package/src/image.tsx +3 -3
  9. package/src/index.ts +15 -13
  10. package/src/render.ts +46 -17
  11. package/src/shape.tsx +15 -15
  12. package/src/span.tsx +9 -0
  13. package/src/subgraph.tsx +3 -3
  14. package/src/text.tsx +58 -39
  15. package/src/vertex.tsx +17 -14
  16. package/src/vertex2.tsx +5 -5
  17. package/src/vertex3.tsx +11 -11
  18. package/src/vertex4.tsx +10 -11
  19. package/types/ImageChar.d.ts +4 -5
  20. package/types/__package__.d.ts +2 -3
  21. package/types/edge.d.ts +2 -3
  22. package/types/icon.d.ts +6 -7
  23. package/types/image.d.ts +3 -4
  24. package/types/index.d.ts +15 -14
  25. package/types/render.d.ts +16 -8
  26. package/types/shape.d.ts +9 -10
  27. package/types/span.d.ts +5 -0
  28. package/types/subgraph.d.ts +1 -2
  29. package/types/text.d.ts +11 -13
  30. package/types/vertex.d.ts +5 -6
  31. package/types/vertex2.d.ts +2 -3
  32. package/types/vertex3.d.ts +8 -9
  33. package/types/vertex4.d.ts +4 -5
  34. package/dist/index.es6.js +0 -542
  35. package/dist/index.es6.js.map +0 -1
  36. package/dist/index.min.js +0 -2
  37. package/dist/index.min.js.map +0 -1
  38. package/types/ImageChar.d.ts.map +0 -1
  39. package/types/__package__.d.ts.map +0 -1
  40. package/types/edge.d.ts.map +0 -1
  41. package/types/icon.d.ts.map +0 -1
  42. package/types/image.d.ts.map +0 -1
  43. package/types/index.d.ts.map +0 -1
  44. package/types/render.d.ts.map +0 -1
  45. package/types/shape.d.ts.map +0 -1
  46. package/types/subgraph.d.ts.map +0 -1
  47. package/types/text.d.ts.map +0 -1
  48. package/types/vertex.d.ts.map +0 -1
  49. package/types/vertex2.d.ts.map +0 -1
  50. package/types/vertex3.d.ts.map +0 -1
  51. package/types/vertex4.d.ts.map +0 -1
  52. package/types-3.4/ImageChar.d.ts +0 -14
  53. package/types-3.4/__package__.d.ts +0 -4
  54. package/types-3.4/edge.d.ts +0 -30
  55. package/types-3.4/icon.d.ts +0 -27
  56. package/types-3.4/image.d.ts +0 -11
  57. package/types-3.4/index.d.ts +0 -15
  58. package/types-3.4/render.d.ts +0 -27
  59. package/types-3.4/shape.d.ts +0 -41
  60. package/types-3.4/subgraph.d.ts +0 -14
  61. package/types-3.4/text.d.ts +0 -51
  62. package/types-3.4/vertex.d.ts +0 -33
  63. package/types-3.4/vertex2.d.ts +0 -4
  64. package/types-3.4/vertex3.d.ts +0 -34
  65. package/types-3.4/vertex4.d.ts +0 -32
package/package.json CHANGED
@@ -1,49 +1,50 @@
1
1
  {
2
2
  "name": "@hpcc-js/react",
3
- "version": "2.54.0",
3
+ "version": "3.1.0",
4
4
  "description": "hpcc-js - Viz React",
5
- "main": "dist/index.js",
6
- "module": "dist/index.es6",
7
- "unpkg": "dist/index.min.js",
8
- "jsdelivr": "dist/index.min.js",
9
- "types": "types/index.d.ts",
10
- "typesVersions": {
11
- "<3.8": {
12
- "*": [
13
- "types-3.4/index.d.ts"
14
- ]
15
- }
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./types/index.d.ts",
9
+ "default": "./dist/index.js"
10
+ },
11
+ "./dist/*": "./dist/*"
16
12
  },
13
+ "module": "./dist/index.js",
14
+ "browser": "./dist/index.js",
15
+ "types": "./types/index.d.ts",
17
16
  "files": [
18
17
  "dist/*",
19
- "types/*",
20
- "types-3.4/*",
21
- "src/*"
18
+ "src/*",
19
+ "types/*"
22
20
  ],
23
21
  "scripts": {
24
- "clean": "rimraf --glob lib* types dist *.tsbuildinfo",
25
- "compile-es6": "tsc --module es6 --outDir ./lib-es6",
26
- "compile-es6-watch": "npm run compile-es6 -- -w",
27
- "compile-umd": "tsc --module umd --outDir ./lib-umd",
28
- "compile-umd-watch": "npm run compile-umd -- -w",
29
- "bundle": "rollup -c",
30
- "bundle-watch": "npm run bundle -- -w",
31
- "minimize": "terser dist/index.js -c -m --source-map \"content='dist/index.js.map',url='index.min.js.map'\" -o dist/index.min.js",
32
- "gen-legacy-types": "downlevel-dts ./types ./types-3.4",
33
- "build": "npm run compile-es6 && npm run bundle",
34
- "watch": "npm-run-all compile-es6 -p compile-es6-watch bundle-watch",
35
- "stamp": "node ../../node_modules/@hpcc-js/bundle/src/stamp.js",
22
+ "clean": "rimraf --glob lib* types dist *.tsbuildinfo .turbo",
23
+ "bundle": "node esbuild.js",
24
+ "bundle-watch": "npm run bundle -- --development --watch",
25
+ "gen-types": "tsc --project tsconfig.json",
26
+ "gen-types-watch": "npm run gen-types -- --watch",
27
+ "build": "run-p gen-types bundle",
36
28
  "lint": "eslint ./src",
29
+ "lint-fix": "eslint --fix src/**/*.ts",
37
30
  "docs": "typedoc --options tdoptions.json .",
38
- "update": "npx --yes npm-check-updates -u -t minor"
31
+ "test-browser": "vitest run --project browser",
32
+ "test": "vitest run",
33
+ "coverage": "vitest run --coverage",
34
+ "update": "npx --yes npm-check-updates -u -t minor",
35
+ "update-major": "npx --yes npm-check-updates -u"
39
36
  },
40
37
  "dependencies": {
41
- "@hpcc-js/common": "^2.72.0",
42
- "@hpcc-js/preact-shim": "^2.17.0"
38
+ "@hpcc-js/common": "^3.2.0"
43
39
  },
44
40
  "devDependencies": {
45
- "@hpcc-js/bundle": "^2.12.0",
46
- "tslib": "2.6.3"
41
+ "@hpcc-js/esbuild-plugins": "^1.3.0",
42
+ "react": "18.3.1",
43
+ "react-dom": "18.3.1"
44
+ },
45
+ "peerDependencies": {
46
+ "react": "^17.0.0 || ^18.0.0",
47
+ "react-dom": "^17.0.0 || ^18.0.0"
47
48
  },
48
49
  "repository": {
49
50
  "type": "git",
@@ -56,5 +57,5 @@
56
57
  "url": "https://github.com/hpcc-systems/Visualization/issues"
57
58
  },
58
59
  "homepage": "https://github.com/hpcc-systems/Visualization",
59
- "gitHead": "99332f074dd1fff0cbb8eae52c5b6c98d6ad5a7a"
60
+ "gitHead": "658c50fd965a7744ba8db675ba6878607c44d5e2"
60
61
  }
package/src/ImageChar.tsx CHANGED
@@ -1,7 +1,7 @@
1
+ import React, { useMemo } from "react";
1
2
  import { Utility } from "@hpcc-js/common";
2
- import * as React from "@hpcc-js/preact-shim";
3
3
 
4
- interface ImageChar {
4
+ export interface ImageCharProps {
5
5
  x?: number;
6
6
  y?: number;
7
7
  height?: number;
@@ -10,19 +10,21 @@ interface ImageChar {
10
10
  fontFamily?: string;
11
11
  char?: string;
12
12
  yOffset?: number;
13
+ fontWeight?: number;
13
14
  }
14
15
 
15
- export const ImageChar: React.FunctionComponent<ImageChar> = ({
16
+ export const ImageChar: React.FunctionComponent<ImageCharProps> = ({
16
17
  x,
17
18
  y = 0,
18
19
  height = 12,
19
20
  fill,
20
21
  stroke,
21
22
  fontFamily = "FontAwesome",
22
- char = ""
23
+ char = "",
24
+ fontWeight
23
25
  }) => {
24
26
 
25
- const renderChar = React.useMemo(() => {
27
+ const renderChar = useMemo(() => {
26
28
  return fontFamily === "FontAwesome" ? Utility.faChar(char) : char;
27
29
  }, [char, fontFamily]);
28
30
 
@@ -31,9 +33,10 @@ export const ImageChar: React.FunctionComponent<ImageChar> = ({
31
33
  y={y}
32
34
  fill={fill}
33
35
  stroke={stroke}
34
- font-family={fontFamily}
35
- font-size={`${height}px`}
36
- dominant-baseline="middle"
37
- style="text-anchor: middle;alignment-baseline:middle;"
36
+ fontFamily={fontFamily}
37
+ fontSize={`${height}px`}
38
+ fontWeight={fontWeight}
39
+ dominantBaseline="middle"
40
+ style={{ textAnchor: "middle", alignmentBaseline: "middle" }}
38
41
  >{renderChar}</text>;
39
42
  };
@@ -1,3 +1,3 @@
1
1
  export const PKG_NAME = "@hpcc-js/react";
2
- export const PKG_VERSION = "2.54.0";
3
- export const BUILD_VERSION = "2.106.0";
2
+ export const PKG_VERSION = "3.1.0";
3
+ export const BUILD_VERSION = "3.2.0";
package/src/edge.tsx CHANGED
@@ -1,6 +1,6 @@
1
- import * as React from "@hpcc-js/preact-shim";
2
- import { VertexProps } from "./vertex";
3
- import { Text } from "./text";
1
+ import React from "react";
2
+ import { VertexProps } from "./vertex.tsx";
3
+ import { Text } from "./text.tsx";
4
4
 
5
5
  type Point = [number, number];
6
6
 
package/src/icon.tsx CHANGED
@@ -1,10 +1,10 @@
1
+ import React from "react";
1
2
  import { Palette } from "@hpcc-js/common";
2
- import * as React from "@hpcc-js/preact-shim";
3
- import { Image } from "./image";
4
- import { ImageChar } from "./ImageChar";
5
- import { Shape } from "./shape";
3
+ import { Image } from "./image.tsx";
4
+ import { ImageChar } from "./ImageChar.tsx";
5
+ import { Shape } from "./shape.tsx";
6
6
 
7
- export interface Icon {
7
+ export interface IconProps {
8
8
  shape?: "circle" | "square" | "rectangle";
9
9
  width?: number;
10
10
  height?: number;
@@ -22,7 +22,7 @@ export interface Icon {
22
22
  shapeRendering?: "auto" | "optimizeSpeed" | "crispEdges" | "geometricPrecision";
23
23
  }
24
24
 
25
- export const Icon: React.FunctionComponent<Icon> = ({
25
+ export const Icon: React.FunctionComponent<IconProps> = ({
26
26
  shape = "circle",
27
27
  width,
28
28
  height = 32,
@@ -64,21 +64,21 @@ export const Icon: React.FunctionComponent<Icon> = ({
64
64
  fontFamily={imageFontFamily}
65
65
  char={imageChar}
66
66
  fill={imageCharFill}
67
- font-weight={400}
67
+ fontWeight={400}
68
68
  ></ImageChar>
69
69
  }
70
70
  </>;
71
71
  };
72
72
 
73
- export interface IconEx extends Icon {
73
+ export interface IconEx extends IconProps {
74
74
  id: string;
75
75
  }
76
76
 
77
- export interface Icons {
77
+ export interface IconsProps {
78
78
  icons: IconEx[];
79
79
  }
80
80
 
81
- export const Icons: React.FunctionComponent<Icons> = ({
81
+ export const Icons: React.FunctionComponent<IconsProps> = ({
82
82
  icons = []
83
83
  }) => {
84
84
  const IconComponents = icons.map(cat => {
package/src/image.tsx CHANGED
@@ -1,6 +1,6 @@
1
- import * as React from "@hpcc-js/preact-shim";
1
+ import React from "react";
2
2
 
3
- interface Image {
3
+ interface ImageProps {
4
4
  href: string;
5
5
  x?: number;
6
6
  y?: number;
@@ -8,7 +8,7 @@ interface Image {
8
8
  yOffset?: number;
9
9
  }
10
10
 
11
- export const Image: React.FunctionComponent<Image> = ({
11
+ export const Image: React.FunctionComponent<ImageProps> = ({
12
12
  href,
13
13
  x,
14
14
  y = 0,
package/src/index.ts CHANGED
@@ -1,18 +1,20 @@
1
- export * from "./__package__";
1
+ export * from "./__package__.ts";
2
2
 
3
- export * from "./edge";
4
- export * from "./ImageChar";
5
- export * from "./icon";
6
- export * from "./render";
7
- export * from "./shape";
8
- export * from "./text";
9
- export * from "./vertex";
10
- export * from "./vertex2";
11
- export * from "./vertex3";
12
- export * from "./vertex4";
13
- export * from "./subgraph";
3
+ export * from "./edge.tsx";
4
+ export * from "./ImageChar.tsx";
5
+ export * from "./icon.tsx";
6
+ export * from "./image.tsx";
7
+ export * from "./render.ts";
8
+ export * from "./shape.tsx";
9
+ export * from "./span.tsx";
10
+ export * from "./text.tsx";
11
+ export * from "./vertex.tsx";
12
+ export * from "./vertex2.tsx";
13
+ export * from "./vertex3.tsx";
14
+ export * from "./vertex4.tsx";
15
+ export * from "./subgraph.tsx";
14
16
 
15
- import * as React from "@hpcc-js/preact-shim";
17
+ import React from "react";
16
18
  export {
17
19
  React
18
20
  };
package/src/render.ts CHANGED
@@ -1,21 +1,17 @@
1
- import { HTMLWidget, publish, SVGWidget } from "@hpcc-js/common";
2
- import * as React from "@hpcc-js/preact-shim";
1
+ import React from "react";
2
+ import { render as reactRender } from "react-dom";
3
+ import { createRoot, Root } from "react-dom/client";
4
+ import { HTMLWidget, SVGWidget } from "@hpcc-js/common";
3
5
 
4
- export function render<P>(C: React.FunctionComponent<P>, props: Readonly<P>, parent: Element | Document | ShadowRoot | DocumentFragment, replaceNode?: Element | Text) {
5
- React.render(React.h(C, props), parent, replaceNode);
6
- }
7
-
8
- export interface FunctionComponent<T> extends React.FunctionComponent<T> {
9
- }
10
-
11
- export function svgRender<P>(C: React.FunctionComponent<P>, props: Readonly<P>, parent: Element | Document | ShadowRoot | DocumentFragment, replaceNode?: Element | Text) {
12
- React.render(React.h("svg", null, React.h(C, props)), parent, replaceNode);
6
+ export function render<P>(C: React.FunctionComponent<P>, props: Readonly<P>, parent: Element | Document | ShadowRoot | DocumentFragment) {
7
+ const re = React.createElement(C, props);
8
+ reactRender(re, parent);
13
9
  }
14
10
 
15
11
  export class HTMLAdapter<P> extends HTMLWidget {
16
12
 
17
- @publish({}, "object", "Properties")
18
- protected _props: P = {} as P;
13
+ protected _root: Root;
14
+
19
15
  props(): P;
20
16
  props(_: Partial<P>): this;
21
17
  props(_?: Partial<P>): P | this {
@@ -36,16 +32,32 @@ export class HTMLAdapter<P> extends HTMLWidget {
36
32
  super();
37
33
  }
38
34
 
35
+ enter(domNode, element) {
36
+ super.enter(domNode, element);
37
+ this._root = createRoot(domNode);
38
+ }
39
+
39
40
  update(domNode, element) {
40
41
  super.update(domNode, element);
41
- render(this._component, this._props, domNode);
42
+ this._root.render(React.createElement(this._component, this.props()));
43
+ }
44
+
45
+ exit(domNode, element) {
46
+ this._root.unmount();
47
+ super.exit(domNode, element);
42
48
  }
43
49
  }
50
+ HTMLAdapter.prototype._class += " react_HTMLAdapter";
51
+
52
+ export interface HTMLAdapter<P> {
53
+ _props: P;
54
+ }
55
+ HTMLAdapter.prototype.publish("props", {}, "object", "Properties");
44
56
 
45
57
  export class SVGAdapter<P> extends SVGWidget {
46
58
 
47
- @publish({}, "object", "Properties")
48
- protected _props: P = {} as P;
59
+ protected _root: Root;
60
+
49
61
  props(): P;
50
62
  props(_: Partial<P>): this;
51
63
  props(_?: Partial<P>): P | this {
@@ -66,8 +78,25 @@ export class SVGAdapter<P> extends SVGWidget {
66
78
  super();
67
79
  }
68
80
 
81
+ _c2: React.ReactElement;
82
+ enter(domNode, element) {
83
+ super.enter(domNode, element);
84
+ this._root = createRoot(domNode);
85
+ }
86
+
69
87
  update(domNode, element) {
70
88
  super.update(domNode, element);
71
- render(this._component, this._props, domNode);
89
+ this._root.render(React.createElement(this._component, this.props()));
72
90
  }
91
+
92
+ exit(domNode, element) {
93
+ this._root.unmount();
94
+ super.exit(domNode, element);
95
+ }
96
+ }
97
+ SVGAdapter.prototype._class += " react_SVGAdapter";
98
+
99
+ export interface SVGAdapter<P> {
100
+ _props: P;
73
101
  }
102
+ SVGAdapter.prototype.publish("props", {}, "object", "Properties");
package/src/shape.tsx CHANGED
@@ -1,6 +1,6 @@
1
- import * as React from "@hpcc-js/preact-shim";
1
+ import React from "react";
2
2
 
3
- interface Circle {
3
+ interface CircleProps {
4
4
  radius?: number;
5
5
  fill?: string;
6
6
  stroke?: string;
@@ -8,7 +8,7 @@ interface Circle {
8
8
  shapeRendering?: "auto" | "optimizeSpeed" | "crispEdges" | "geometricPrecision";
9
9
  }
10
10
 
11
- export const Circle: React.FunctionComponent<Circle> = ({
11
+ export const Circle: React.FunctionComponent<CircleProps> = ({
12
12
  radius = 32,
13
13
  fill = "navy",
14
14
  stroke = fill,
@@ -18,11 +18,11 @@ export const Circle: React.FunctionComponent<Circle> = ({
18
18
  r={radius}
19
19
  fill={fill}
20
20
  stroke={stroke}
21
- stroke-width={strokeWidth}
22
- shape-rendering={shapeRendering}
21
+ strokeWidth={strokeWidth}
22
+ shapeRendering={shapeRendering}
23
23
  />;
24
24
 
25
- interface Square {
25
+ interface SquareProps {
26
26
  radius?: number;
27
27
  cornerRadius?: number;
28
28
  fill?: string;
@@ -31,7 +31,7 @@ interface Square {
31
31
  shapeRendering?: "auto" | "optimizeSpeed" | "crispEdges" | "geometricPrecision";
32
32
  }
33
33
 
34
- export const Square: React.FunctionComponent<Square> = ({
34
+ export const Square: React.FunctionComponent<SquareProps> = ({
35
35
  radius = 30,
36
36
  cornerRadius = 0,
37
37
  fill = "white",
@@ -47,11 +47,11 @@ export const Square: React.FunctionComponent<Square> = ({
47
47
  height={radius * 2}
48
48
  fill={fill}
49
49
  stroke={stroke || fill}
50
- stroke-width={strokeWidth}
51
- shape-rendering={shapeRendering}
50
+ strokeWidth={strokeWidth}
51
+ shapeRendering={shapeRendering}
52
52
  />;
53
53
 
54
- interface Rectangle {
54
+ interface RectangleProps {
55
55
  width?: number;
56
56
  height?: number;
57
57
  cornerRadius?: number;
@@ -61,7 +61,7 @@ interface Rectangle {
61
61
  shapeRendering?: "auto" | "optimizeSpeed" | "crispEdges" | "geometricPrecision";
62
62
  }
63
63
 
64
- export const Rectangle: React.FunctionComponent<Rectangle> = ({
64
+ export const Rectangle: React.FunctionComponent<RectangleProps> = ({
65
65
  width = 30,
66
66
  height = 30,
67
67
  cornerRadius = 0,
@@ -79,12 +79,12 @@ export const Rectangle: React.FunctionComponent<Rectangle> = ({
79
79
  height={height}
80
80
  fill={fill}
81
81
  stroke={stroke || fill}
82
- stroke-width={strokeWidth}
83
- shape-rendering={shapeRendering}
82
+ strokeWidth={strokeWidth}
83
+ shapeRendering={shapeRendering}
84
84
  />;
85
85
  };
86
86
 
87
- interface Shape {
87
+ interface ShapeProps {
88
88
  shape?: "circle" | "square" | "rectangle";
89
89
  height?: number;
90
90
  width?: number;
@@ -95,7 +95,7 @@ interface Shape {
95
95
  cornerRadius?: number;
96
96
  }
97
97
 
98
- export const Shape: React.FunctionComponent<Shape> = ({
98
+ export const Shape: React.FunctionComponent<ShapeProps> = ({
99
99
  shape = "circle",
100
100
  height = 128,
101
101
  width,
package/src/span.tsx ADDED
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+
3
+ export interface SpanProps {
4
+ text: string;
5
+ }
6
+
7
+ export const Span: React.FunctionComponent<SpanProps> = ({
8
+ text
9
+ }) => <span>{text}</span>;
package/src/subgraph.tsx CHANGED
@@ -1,7 +1,7 @@
1
+ import React from "react";
1
2
  import { Utility } from "@hpcc-js/common";
2
- import * as React from "@hpcc-js/preact-shim";
3
- import { Rectangle } from "./shape";
4
- import { Text } from "./text";
3
+ import { Rectangle } from "./shape.tsx";
4
+ import { Text } from "./text.tsx";
5
5
 
6
6
  export interface SubgraphProps {
7
7
  id: string;
package/src/text.tsx CHANGED
@@ -1,9 +1,9 @@
1
+ import React from "react";
1
2
  import { Utility } from "@hpcc-js/common";
2
- import * as React from "@hpcc-js/preact-shim";
3
- import { Icon } from "./icon";
4
- import { Rectangle } from "./shape";
3
+ import { Icon } from "./icon.tsx";
4
+ import { Rectangle } from "./shape.tsx";
5
5
 
6
- interface TextLine {
6
+ export interface TextLineProps {
7
7
  text: string;
8
8
  height?: number;
9
9
  anchor?: string;
@@ -12,7 +12,7 @@ interface TextLine {
12
12
  fill?: string;
13
13
  }
14
14
 
15
- export const TextLine: React.FunctionComponent<TextLine> = ({
15
+ export const TextLine: React.FunctionComponent<TextLineProps> = ({
16
16
  text,
17
17
  height = 12,
18
18
  anchor = "middle",
@@ -21,15 +21,15 @@ export const TextLine: React.FunctionComponent<TextLine> = ({
21
21
  fill = "black"
22
22
  }) => {
23
23
  return <text
24
- font-family={fontFamily}
25
- font-size={`${height}px`}
26
- text-anchor={anchor}
27
- dominant-baseline={baseline}
24
+ fontFamily={fontFamily}
25
+ fontSize={`${height}px`}
26
+ textAnchor={anchor}
27
+ dominantBaseline={baseline}
28
28
  fill={fill}
29
29
  >{text}</text>;
30
30
  };
31
31
 
32
- interface Text {
32
+ export interface TextProps {
33
33
  text: string;
34
34
  height?: number;
35
35
  fontFamily?: string;
@@ -37,35 +37,36 @@ interface Text {
37
37
  onSizeUpdate?: (size: { width: number, height: number }) => void;
38
38
  }
39
39
 
40
- export const Text: React.FunctionComponent<Text> = ({
40
+ export const Text: React.FunctionComponent<TextProps> = ({
41
41
  text,
42
42
  height = 12,
43
43
  fontFamily = "Verdana",
44
44
  fill = "black",
45
45
  onSizeUpdate
46
46
  }) => {
47
- const [totalWidth, setTotalWidthUpdate] = React.useState(0);
48
- const [totalHeight, setTotalHeightUpdate] = React.useState(0);
47
+ const [totalWidth, setTotalWidth] = React.useState(0);
48
+ const [totalHeight, setTotalHeight] = React.useState(0);
49
49
 
50
50
  React.useEffect(() => {
51
- onSizeUpdate && onSizeUpdate({ width: totalWidth, height: totalHeight });
51
+ if (onSizeUpdate) {
52
+ onSizeUpdate({ width: totalWidth, height: totalHeight });
53
+ }
52
54
  }, [totalWidth, totalHeight, onSizeUpdate]);
53
55
 
54
56
  const parts = React.useMemo(() => {
55
57
  return text.split("\n");
56
58
  }, [text]);
57
59
 
58
- const ts = React.useMemo(() => {
59
- return Utility.textSize(parts, fontFamily, height);
60
+ React.useLayoutEffect(() => {
61
+ const size = Utility.textSize(parts, fontFamily, height);
62
+ setTotalWidth(size.width);
63
+ setTotalHeight(size.height);
60
64
  }, [fontFamily, height, parts]);
61
65
 
62
- setTotalWidthUpdate(ts.width);
63
- setTotalHeightUpdate(parts.length * (height + 2) - 2);
64
-
65
- const yOffset = -(totalHeight / 2) + (height / 2);
66
66
  const TextLines = React.useMemo(() => {
67
+ const yOffset = -(totalHeight / 2) + (height / 2);
67
68
  return parts.map((p, i) => {
68
- return <g key={i} transform={`translate(0 ${yOffset + i * (height + 2)})`}>
69
+ return <g key={`key-${i}`} transform={`translate(0 ${yOffset + i * (height + 2)})`}>
69
70
  <TextLine
70
71
  text={p}
71
72
  height={height}
@@ -74,12 +75,12 @@ export const Text: React.FunctionComponent<Text> = ({
74
75
  />
75
76
  </g>;
76
77
  });
77
- }, [fill, fontFamily, height, parts, yOffset]);
78
+ }, [parts, totalHeight, height, fontFamily, fill]);
78
79
 
79
- return <>{TextLines}</>;
80
+ return <g>{TextLines}</g>;
80
81
  };
81
82
 
82
- export interface TextBox {
83
+ export interface TextBoxProps {
83
84
  text: string;
84
85
  height?: number;
85
86
  fontFamily?: string;
@@ -93,7 +94,7 @@ export interface TextBox {
93
94
  onSizeUpdate?: (size: { width: number, height: number }) => void;
94
95
  }
95
96
 
96
- export const TextBox: React.FunctionComponent<TextBox> = ({
97
+ export const TextBox: React.FunctionComponent<TextBoxProps> = ({
97
98
  text,
98
99
  height = 12,
99
100
  fontFamily = "Verdana",
@@ -109,7 +110,9 @@ export const TextBox: React.FunctionComponent<TextBox> = ({
109
110
  const [textHeight, setTextHeightUpdate] = React.useState(0);
110
111
 
111
112
  React.useEffect(() => {
112
- onSizeUpdate && onSizeUpdate({ width: textWidth, height: textHeight });
113
+ if (onSizeUpdate) {
114
+ onSizeUpdate({ width: textWidth, height: textHeight });
115
+ }
113
116
  }, [textWidth, textHeight, onSizeUpdate]);
114
117
 
115
118
  const onTextSizeUpdate = React.useCallback(size => {
@@ -142,17 +145,11 @@ export const TextBox: React.FunctionComponent<TextBox> = ({
142
145
  </>;
143
146
  };
144
147
 
145
- export interface LabelledRect extends TextBox {
148
+ export interface LabelledRect extends TextBoxProps {
146
149
  width?: number;
147
150
  fontSize?: number;
148
151
  }
149
152
 
150
- export interface IconLabelledRect extends LabelledRect {
151
- icon: string;
152
- iconFontFamily: string;
153
- iconFontSize: number;
154
- }
155
-
156
153
  export const LabelledRect: React.FunctionComponent<LabelledRect> = ({
157
154
  text,
158
155
  height = 12,
@@ -165,18 +162,34 @@ export const LabelledRect: React.FunctionComponent<LabelledRect> = ({
165
162
  textFill = "black",
166
163
  strokeWidth = 1,
167
164
  cornerRadius = 0,
168
- onSizeUpdate = (size: { width: number, height: number }) => { }
165
+ onSizeUpdate
169
166
  }) => {
167
+
168
+ const [actualWidth, setActualWidthUpdate] = React.useState(width);
169
+ const [actualHeight, setActualHeightUpdate] = React.useState(height);
170
+
171
+ React.useLayoutEffect(() => {
172
+ const size = Utility.textSize(text, fontFamily, fontSize);
173
+ setActualWidthUpdate(size.width + padding * 2);
174
+ setActualHeightUpdate(size.height + padding * 2);
175
+ }, [text, fontFamily, fontSize, padding]);
176
+
177
+ React.useLayoutEffect(() => {
178
+ if (onSizeUpdate) {
179
+ onSizeUpdate({ width: actualWidth, height: actualHeight });
180
+ }
181
+ }, [actualWidth, actualHeight, padding, onSizeUpdate]);
182
+
170
183
  return <>
171
184
  <Rectangle
172
- width={width}
173
- height={height}
185
+ width={actualWidth}
186
+ height={actualHeight}
174
187
  fill={fill}
175
188
  stroke={stroke}
176
189
  strokeWidth={strokeWidth}
177
190
  cornerRadius={cornerRadius}
178
191
  />
179
- <g transform={`translate(${-(width / 2) + padding} ${-(height / 2) + padding})`}>
192
+ <g transform={`translate(${-(actualWidth / 2) + padding} ${-(actualHeight / 2) + padding + fontSize * 0.15})`}>
180
193
  <TextLine
181
194
  text={text}
182
195
  fontFamily={fontFamily}
@@ -189,6 +202,12 @@ export const LabelledRect: React.FunctionComponent<LabelledRect> = ({
189
202
  </>;
190
203
  };
191
204
 
205
+ export interface IconLabelledRect extends LabelledRect {
206
+ icon: string;
207
+ iconFontFamily?: string;
208
+ iconFontSize?: number;
209
+ }
210
+
192
211
  export const IconLabelledRect: React.FunctionComponent<IconLabelledRect> = ({
193
212
  icon,
194
213
  iconFontFamily,
@@ -202,9 +221,9 @@ export const IconLabelledRect: React.FunctionComponent<IconLabelledRect> = ({
202
221
  stroke = "lightgray",
203
222
  textFill = "black",
204
223
  strokeWidth = 1,
205
- cornerRadius = 0,
206
- onSizeUpdate = (size: { width: number, height: number }) => { }
224
+ cornerRadius = 0
207
225
  }) => {
226
+
208
227
  return <>
209
228
  <Rectangle
210
229
  width={width}