Skip to content
This repository was archived by the owner on Mar 17, 2024. It is now read-only.

Commit a727ca3

Browse files
committed
Merge branch 'master' into support-react17
2 parents 1c8284c + e9759d6 commit a727ca3

File tree

11 files changed

+241
-28
lines changed

11 files changed

+241
-28
lines changed

.all-contributorsrc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"files": [
3+
"README.md"
4+
],
5+
"imageSize": 100,
6+
"commit": false,
7+
"contributors": [
8+
{
9+
"login": "kamiazya",
10+
"name": "Yuki Yamazaki",
11+
"avatar_url": "https://avatars0.githubusercontent.com/u/35218186?v=4",
12+
"profile": "http://blog.kamiazya.tech/",
13+
"contributions": [
14+
"code",
15+
"test",
16+
"ideas",
17+
"doc"
18+
]
19+
},
20+
{
21+
"login": "nagasawaryoya",
22+
"name": "nagasawaryoya",
23+
"avatar_url": "https://avatars.githubusercontent.com/u/53528726?v=4",
24+
"profile": "https://github.com/nagasawaryoya",
25+
"contributions": [
26+
"code",
27+
"test"
28+
]
29+
},
30+
{
31+
"login": "tokidrill",
32+
"name": "YukiSasaki",
33+
"avatar_url": "https://avatars.githubusercontent.com/u/42460318?v=4",
34+
"profile": "https://github.com/tokidrill",
35+
"contributions": [
36+
"code",
37+
"test"
38+
]
39+
}
40+
],
41+
"contributorsPerLine": 7,
42+
"projectName": "react",
43+
"projectOwner": "ts-graphviz",
44+
"repoType": "github",
45+
"repoHost": "https://github.com",
46+
"skipCi": true
47+
}

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
[![NodeCI](https://github.com/ts-graphviz/react/workflows/NodeCI/badge.svg)](https://github.com/kamiazya/ts-graphviz/actions?workflow=NodeCI) [![npm version](https://badge.fury.io/js/%40ts-graphviz%2Freact.svg)](https://badge.fury.io/js/%40ts-graphviz%2Freact) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com) [![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
1+
[![NodeCI](https://github.com/ts-graphviz/react/workflows/NodeCI/badge.svg)](https://github.com/kamiazya/ts-graphviz/actions?workflow=NodeCI)
2+
[![npm version](https://badge.fury.io/js/%40ts-graphviz%2Freact.svg)](https://badge.fury.io/js/%40ts-graphviz%2Freact)
3+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4+
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
5+
[![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest)
6+
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
7+
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)
8+
<!-- ALL-CONTRIBUTORS-BADGE:END -->
29

310
# @ts-graphviz/react
411

@@ -116,6 +123,29 @@ Graphviz-dot Test and Integration
116123
- [setup-graphviz](https://github.com/ts-graphviz/setup-graphviz)
117124
- GitHub Action to set up Graphviz cross-platform(Linux, macOS, Windows).
118125

126+
## Contributors
127+
128+
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
129+
130+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
131+
<!-- prettier-ignore-start -->
132+
<!-- markdownlint-disable -->
133+
<table>
134+
<tr>
135+
<td align="center"><a href="http://blog.kamiazya.tech/"><img src="https://avatars0.githubusercontent.com/u/35218186?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yuki Yamazaki</b></sub></a><br /><a href="https://github.com/ts-graphviz/react/commits?author=kamiazya" title="Code">💻</a> <a href="https://github.com/ts-graphviz/react/commits?author=kamiazya" title="Tests">⚠️</a> <a href="#ideas-kamiazya" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/ts-graphviz/react/commits?author=kamiazya" title="Documentation">📖</a></td>
136+
<td align="center"><a href="https://github.com/nagasawaryoya"><img src="https://avatars.githubusercontent.com/u/53528726?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nagasawaryoya</b></sub></a><br /><a href="https://github.com/ts-graphviz/react/commits?author=nagasawaryoya" title="Code">💻</a> <a href="https://github.com/ts-graphviz/react/commits?author=nagasawaryoya" title="Tests">⚠️</a></td>
137+
<td align="center"><a href="https://github.com/tokidrill"><img src="https://avatars.githubusercontent.com/u/42460318?v=4?s=100" width="100px;" alt=""/><br /><sub><b>YukiSasaki</b></sub></a><br /><a href="https://github.com/ts-graphviz/react/commits?author=tokidrill" title="Code">💻</a> <a href="https://github.com/ts-graphviz/react/commits?author=tokidrill" title="Tests">⚠️</a></td>
138+
</tr>
139+
</table>
140+
141+
<!-- markdownlint-restore -->
142+
<!-- prettier-ignore-end -->
143+
144+
<!-- ALL-CONTRIBUTORS-LIST:END -->
145+
146+
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors)
147+
specification. Contributions of any kind welcome!
148+
119149
## License
120150

121151
This software is released under the MIT License, see [LICENSE](./LICENSE).

example/example.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { FC } from 'react';
22
import { Digraph, Node, Subgraph, renderToDot, Edge, DOT } from '../src';
3-
import { ClusterPortal } from '../src/components/ClusterPortal';
43

54
const Example: FC = () => (
65
<Digraph

src/components/HtmlLike.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable no-undef */
22
import { AttributesValue } from 'ts-graphviz';
3+
import { ValueOf } from '../utils/value-of';
34

45
export type TableProps = {
56
ALIGN?: 'CENTER' | 'LEFT' | 'RIGHT'; // "CENTER|LEFT|RIGHT"
@@ -84,25 +85,26 @@ export type SProps = NoAttributes;
8485
export type HrProps = NoAttributes;
8586
export type VrProps = NoAttributes;
8687

87-
// eslint-disable-next-line no-shadow
88-
export enum DOT {
89-
PORT = 'dot-port',
90-
TABLE = 'dot-table',
91-
TR = 'dot-tr',
92-
TD = 'dot-td',
93-
FONT = 'dot-font',
94-
BR = 'dot-br',
95-
IMG = 'dot-img',
96-
I = 'dot-i',
97-
B = 'dot-b',
98-
U = 'dot-u',
99-
O = 'dot-o',
100-
SUB = 'dot-sub',
101-
SUP = 'dot-sup',
102-
S = 'dot-s',
103-
HR = 'dot-hr',
104-
VR = 'dot-vr',
105-
}
88+
export const DOT = Object.freeze({
89+
PORT: 'dot-port',
90+
TABLE: 'dot-table',
91+
TR: 'dot-tr',
92+
TD: 'dot-td',
93+
FONT: 'dot-font',
94+
BR: 'dot-br',
95+
IMG: 'dot-img',
96+
I: 'dot-i',
97+
B: 'dot-b',
98+
U: 'dot-u',
99+
O: 'dot-o',
100+
SUB: 'dot-sub',
101+
SUP: 'dot-sup',
102+
S: 'dot-s',
103+
HR: 'dot-hr',
104+
VR: 'dot-vr',
105+
} as const);
106+
107+
export type DOT = ValueOf<typeof DOT>;
106108

107109
declare global {
108110
// eslint-disable-next-line @typescript-eslint/no-namespace

src/components/Node.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import PropTypes from 'prop-types';
33
import { useNode, NodeProps } from '../hooks/use-node';
44
import { useRenderedID } from '../hooks/use-rendered-id';
55

6-
type Props = Omit<NodeProps, 'label'> & {
6+
type Props = Omit<NodeProps, 'label' | 'xlabel'> & {
77
label?: ReactElement | string;
8+
xlabel?: ReactElement | string;
89
};
910

10-
export const Node: FC<Props> = ({ children, label, ...props }) => {
11+
export const Node: FC<Props> = ({ children, label, xlabel, ...props }) => {
1112
const renderedLabel = useRenderedID(label);
13+
const renderedXlabel = useRenderedID(xlabel);
14+
1215
if (renderedLabel !== undefined) Object.assign(props, { label: renderedLabel });
16+
if (renderedXlabel !== undefined) Object.assign(props, { xlabel: renderedXlabel });
1317
useNode(props);
1418
return <>{children}</>;
1519
};
@@ -20,9 +24,11 @@ Node.propTypes = {
2024
id: PropTypes.string.isRequired,
2125
comment: PropTypes.string,
2226
label: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
27+
xlabel: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),
2328
};
2429

2530
Node.defaultProps = {
2631
comment: undefined,
2732
label: undefined,
33+
xlabel: undefined,
2834
};
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React from 'react';
2+
import 'jest-graphviz';
3+
import { Digraph } from '../Digraph';
4+
import { Node } from '../Node';
5+
import { DOT } from '../HtmlLike';
6+
import { renderToDot } from '../../renderer/render';
7+
8+
describe('Node', () => {
9+
test('pass without optional props and render correctly', () => {
10+
const dot = renderToDot(
11+
<Digraph>
12+
<Node id="aaa" />
13+
</Digraph>,
14+
);
15+
expect(dot).toBeValidDotAndMatchSnapshot();
16+
});
17+
18+
test('pass label with string and render correctly', () => {
19+
const dot = renderToDot(
20+
<Digraph>
21+
<Node id="aaa" label="label test" />
22+
</Digraph>,
23+
);
24+
expect(dot).toBeValidDotAndMatchSnapshot();
25+
});
26+
27+
test('pass label with HTMLLike ReactElement and render correctly', () => {
28+
const dot = renderToDot(
29+
<Digraph>
30+
<Node
31+
id="aaa"
32+
label={
33+
<DOT.TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
34+
<DOT.TR>
35+
<DOT.TD>left</DOT.TD>
36+
<DOT.TD PORT="m">middle</DOT.TD>
37+
<DOT.TD PORT="r">right</DOT.TD>
38+
</DOT.TR>
39+
</DOT.TABLE>
40+
}
41+
/>
42+
</Digraph>,
43+
);
44+
expect(dot).toBeValidDotAndMatchSnapshot();
45+
});
46+
47+
test('pass xlabel with string and render correctly', () => {
48+
const dot = renderToDot(
49+
<Digraph>
50+
<Node id="aaa" xlabel="xlabel test" />
51+
</Digraph>,
52+
);
53+
expect(dot).toBeValidDotAndMatchSnapshot();
54+
});
55+
56+
test('pass xlabel with HTMLLike ReactElement and render correctly', () => {
57+
const dot = renderToDot(
58+
<Digraph>
59+
<Node
60+
id="aaa"
61+
xlabel={
62+
<DOT.TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
63+
<DOT.TR>
64+
<DOT.TD>left</DOT.TD>
65+
<DOT.TD PORT="m">middle</DOT.TD>
66+
<DOT.TD PORT="r">right</DOT.TD>
67+
</DOT.TR>
68+
</DOT.TABLE>
69+
}
70+
/>
71+
</Digraph>,
72+
);
73+
expect(dot).toBeValidDotAndMatchSnapshot();
74+
});
75+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Node pass label with HTMLLike ReactElement and render correctly 1`] = `
4+
digraph {
5+
"aaa" [
6+
label = <<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"><TR><TD>left</TD><TD PORT="m">middle</TD><TD PORT="r">right</TD></TR></TABLE>>,
7+
];
8+
}
9+
`;
10+
11+
exports[`Node pass label with string and render correctly 1`] = `
12+
digraph {
13+
"aaa" [
14+
label = "label test",
15+
];
16+
}
17+
`;
18+
19+
exports[`Node pass without optional props and render correctly 1`] = `
20+
digraph {
21+
"aaa";
22+
}
23+
`;
24+
25+
exports[`Node pass xlabel with HTMLLike ReactElement and render correctly 1`] = `
26+
digraph {
27+
"aaa" [
28+
xlabel = <<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"><TR><TD>left</TD><TD PORT="m">middle</TD><TD PORT="r">right</TD></TR></TABLE>>,
29+
];
30+
}
31+
`;
32+
33+
exports[`Node pass xlabel with string and render correctly 1`] = `
34+
digraph {
35+
"aaa" [
36+
xlabel = "xlabel test",
37+
];
38+
}
39+
`;

src/hooks/__tests__/use-edge.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,27 @@ describe('useEdge', () => {
1212
expect(result.current).toBeInstanceOf(Edge);
1313
});
1414

15+
it('returns an Edge instance in a digraph wrapper for grouped edge targets', () => {
16+
const { result } = renderHook(() => useEdge({ targets: ['a', ['b1', 'b2'], 'c'] }), {
17+
wrapper: digraph(),
18+
});
19+
expect(result.current).toBeInstanceOf(Edge);
20+
});
21+
1522
it('returns Edge instance in graph wrapper', () => {
1623
const { result } = renderHook(() => useEdge({ targets: ['a', 'b'] }), {
1724
wrapper: graph(),
1825
});
1926
expect(result.current).toBeInstanceOf(Edge);
2027
});
2128

29+
it('returns an Edge instance in a graph wrapper for grouped edge targets', () => {
30+
const { result } = renderHook(() => useEdge({ targets: ['a', ['b1', 'b2'], 'c'] }), {
31+
wrapper: graph(),
32+
});
33+
expect(result.current).toBeInstanceOf(Edge);
34+
});
35+
2236
test('throw error if the target is less than 2', () => {
2337
const { result } = renderHook(() => useEdge({ targets: ['a'] }), {
2438
wrapper: graph(),

src/hooks/use-edge.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { useEffect, useMemo } from 'react';
2-
import { EdgeTargetLike, IEdge, EdgeAttributes } from 'ts-graphviz';
2+
import { EdgeTargetLike, EdgeTargetsLike, IEdge, EdgeAttributes } from 'ts-graphviz';
33
import { useCluster } from './use-cluster';
44
import { EdgeTargetLengthErrorMessage } from '../utils/errors';
55
import { useHasComment } from './use-comment';
66
import { useHasAttributes } from './use-has-attributes';
77

88
export type EdgeProps = {
9-
targets: EdgeTargetLike[];
9+
targets: (EdgeTargetLike | EdgeTargetsLike)[];
1010
comment?: string;
1111
} & EdgeAttributes;
1212

src/utils/value-of.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type ValueOf<T> = T[keyof T];

0 commit comments

Comments
 (0)