react-apextree 1.0.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.
- package/LICENSE +80 -0
- package/README.md +244 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +107 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
## 📄 License Options for react-apextree
|
|
2
|
+
|
|
3
|
+
react-apextree is offered under a **dual-license model** to support individuals, startups, and commercial products of all sizes.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
### 🔓 Community License (Free)
|
|
8
|
+
|
|
9
|
+
For individuals, non-profits, educators, and small businesses with **less than $2 million USD in annual revenue**.
|
|
10
|
+
|
|
11
|
+
✅ What's allowed:
|
|
12
|
+
|
|
13
|
+
- Personal, educational, or non-profit use
|
|
14
|
+
- Commercial use by small orgs (< $2M annual revenue)
|
|
15
|
+
- Modifications and redistribution (with attribution)
|
|
16
|
+
|
|
17
|
+
🚫 Not allowed:
|
|
18
|
+
|
|
19
|
+
- Use by companies or entities over $2M/year revenue
|
|
20
|
+
- Use in competing charting products
|
|
21
|
+
- Sublicensing under different terms
|
|
22
|
+
|
|
23
|
+
➡ By using react-apextree under this license, you confirm that **you qualify as a Small Organization**.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
### 💼 Commercial License (Paid)
|
|
28
|
+
|
|
29
|
+
Required if **you or your affiliated organization earns $2 million USD or more per year**.
|
|
30
|
+
|
|
31
|
+
✅ What's included:
|
|
32
|
+
|
|
33
|
+
- Use in internal tools and commercial applications
|
|
34
|
+
- Modifications and app-level distribution
|
|
35
|
+
- 12-month subscription with updates & support
|
|
36
|
+
|
|
37
|
+
🚫 Not allowed:
|
|
38
|
+
|
|
39
|
+
- Redistribution in toolkits, SDKs, or platforms
|
|
40
|
+
- Use by unlicensed developers
|
|
41
|
+
- Competing charting products
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### 🔄 OEM / Redistribution License (Paid)
|
|
46
|
+
|
|
47
|
+
Required if you are **embedding react-apextree into a product or platform used by other people**, such as:
|
|
48
|
+
|
|
49
|
+
- No-code dashboards
|
|
50
|
+
- Developer platforms
|
|
51
|
+
- Embedded BI tools
|
|
52
|
+
- White-labeled apps or SDKs
|
|
53
|
+
|
|
54
|
+
✅ What's included:
|
|
55
|
+
|
|
56
|
+
- Redistribution rights for 1 application or product
|
|
57
|
+
- 12-month subscription with updates & support
|
|
58
|
+
|
|
59
|
+
✅ OEM **not required** if your app simply renders static charts and users **cannot** configure or interact with them.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### ⚠️ License Acceptance
|
|
64
|
+
|
|
65
|
+
By installing react-apextree (e.g., via `npm install react-apextree`), you are agreeing to the applicable license based on your usage:
|
|
66
|
+
|
|
67
|
+
- Community License (if under $2M revenue)
|
|
68
|
+
- Commercial License (if over $2M revenue)
|
|
69
|
+
- OEM License (if redistributing to third-party users)
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### 🛠 Need a License or Have Questions?
|
|
74
|
+
|
|
75
|
+
📧 Contact us at [sales@apexcharts.com](mailto:sales@apexcharts.com)
|
|
76
|
+
📚 Read full license agreements here: [https://apexcharts.com/license](https://apexcharts.com/license)
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
Thank you for supporting ApexCharts! Your licensing helps keep it free and open for individuals and small teams.
|
package/README.md
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# react-apextree
|
|
2
|
+
|
|
3
|
+
React wrapper for [ApexTree](https://github.com/apexcharts/apextree) - a JavaScript library for creating organizational and hierarchical charts.
|
|
4
|
+
|
|
5
|
+
<img width="811" alt="ApexTree Example" src="https://github.com/apexcharts/tree/assets/17950663/e09212ec-6322-4c68-ac12-9afc524d2abd">
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install react-apextree apextree
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> **Note:** `apextree` is a peer dependency and must be installed alongside `react-apextree`.
|
|
14
|
+
|
|
15
|
+
## Basic Usage
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { ApexTreeChart } from "react-apextree";
|
|
19
|
+
|
|
20
|
+
const data = {
|
|
21
|
+
id: "1",
|
|
22
|
+
name: "CEO",
|
|
23
|
+
children: [
|
|
24
|
+
{
|
|
25
|
+
id: "2",
|
|
26
|
+
name: "CTO",
|
|
27
|
+
children: [
|
|
28
|
+
{ id: "3", name: "Dev Lead" },
|
|
29
|
+
{ id: "4", name: "QA Lead" },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "5",
|
|
34
|
+
name: "CFO",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function App() {
|
|
40
|
+
return (
|
|
41
|
+
<ApexTreeChart
|
|
42
|
+
data={data}
|
|
43
|
+
width={800}
|
|
44
|
+
height={600}
|
|
45
|
+
direction="top"
|
|
46
|
+
nodeWidth={120}
|
|
47
|
+
nodeHeight={80}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Using Imperative Methods
|
|
54
|
+
|
|
55
|
+
Access methods like `changeLayout`, `collapse`, `expand`, and `fitScreen` via ref:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { useRef } from "react";
|
|
59
|
+
import { ApexTreeChart, ApexTreeRef } from "react-apextree";
|
|
60
|
+
|
|
61
|
+
function App() {
|
|
62
|
+
const treeRef = useRef<ApexTreeRef>(null);
|
|
63
|
+
|
|
64
|
+
const handleChangeLayout = () => {
|
|
65
|
+
treeRef.current?.changeLayout("left");
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const handleCollapse = (nodeId: string) => {
|
|
69
|
+
treeRef.current?.collapse(nodeId);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const handleExpand = (nodeId: string) => {
|
|
73
|
+
treeRef.current?.expand(nodeId);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const handleFitScreen = () => {
|
|
77
|
+
treeRef.current?.fitScreen();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div>
|
|
82
|
+
<button onClick={handleChangeLayout}>Change Layout</button>
|
|
83
|
+
<button onClick={handleFitScreen}>Fit Screen</button>
|
|
84
|
+
|
|
85
|
+
<ApexTreeChart ref={treeRef} data={data} width={800} height={600} />
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Custom Node Templates
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
<ApexTreeChart
|
|
95
|
+
data={data}
|
|
96
|
+
width={800}
|
|
97
|
+
height={600}
|
|
98
|
+
contentKey="data"
|
|
99
|
+
nodeWidth={150}
|
|
100
|
+
nodeHeight={100}
|
|
101
|
+
nodeTemplate={(content) => `
|
|
102
|
+
<div style="display: flex; flex-direction: column; align-items: center; height: 100%;">
|
|
103
|
+
<img
|
|
104
|
+
src="${content.imageURL}"
|
|
105
|
+
style="width: 50px; height: 50px; border-radius: 50%;"
|
|
106
|
+
/>
|
|
107
|
+
<div style="font-weight: bold;">${content.name}</div>
|
|
108
|
+
</div>
|
|
109
|
+
`}
|
|
110
|
+
/>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Props
|
|
114
|
+
|
|
115
|
+
| Prop | Type | Default | Description |
|
|
116
|
+
| ---------------------- | ---------------------------------------- | ------------ | ----------------------------------- |
|
|
117
|
+
| `data` | `NodeData` | **required** | Tree data structure |
|
|
118
|
+
| `width` | `number \| string` | `400` | Width of the container |
|
|
119
|
+
| `height` | `number \| string` | `400` | Height of the container |
|
|
120
|
+
| `direction` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` | Direction of tree growth |
|
|
121
|
+
| `contentKey` | `string` | `'name'` | Key for node content |
|
|
122
|
+
| `siblingSpacing` | `number` | `50` | Spacing between siblings |
|
|
123
|
+
| `childrenSpacing` | `number` | `50` | Spacing between parent and children |
|
|
124
|
+
| `nodeWidth` | `number` | `50` | Width of nodes |
|
|
125
|
+
| `nodeHeight` | `number` | `30` | Height of nodes |
|
|
126
|
+
| `nodeTemplate` | `(content: unknown) => string` | - | Custom HTML template for nodes |
|
|
127
|
+
| `nodeStyle` | `string` | - | CSS styles for nodes |
|
|
128
|
+
| `nodeBGColor` | `string` | `'#FFFFFF'` | Node background color |
|
|
129
|
+
| `nodeBGColorHover` | `string` | `'#FFFFFF'` | Node background color on hover |
|
|
130
|
+
| `borderWidth` | `number` | `1` | Node border width |
|
|
131
|
+
| `borderStyle` | `string` | `'solid'` | Node border style |
|
|
132
|
+
| `borderRadius` | `string` | `'5px'` | Node border radius |
|
|
133
|
+
| `borderColor` | `string` | `'#BCBCBC'` | Node border color |
|
|
134
|
+
| `borderColorHover` | `string` | `'#5C6BC0'` | Node border color on hover |
|
|
135
|
+
| `edgeWidth` | `number` | `1` | Edge line width |
|
|
136
|
+
| `edgeColor` | `string` | `'#BCBCBC'` | Edge line color |
|
|
137
|
+
| `edgeColorHover` | `string` | `'#5C6BC0'` | Edge line color on hover |
|
|
138
|
+
| `fontSize` | `string` | `'14px'` | Font size |
|
|
139
|
+
| `fontFamily` | `string` | - | Font family |
|
|
140
|
+
| `fontWeight` | `string` | `'400'` | Font weight |
|
|
141
|
+
| `fontColor` | `string` | `'#000000'` | Font color |
|
|
142
|
+
| `highlightOnHover` | `boolean` | `true` | Enable highlight on hover |
|
|
143
|
+
| `enableToolbar` | `boolean` | `false` | Show toolbar |
|
|
144
|
+
| `enableExpandCollapse` | `boolean` | `false` | Enable expand/collapse buttons |
|
|
145
|
+
| `enableTooltip` | `boolean` | `false` | Enable tooltips |
|
|
146
|
+
| `tooltipTemplate` | `(content: unknown) => string` | - | Custom tooltip template |
|
|
147
|
+
| `groupLeafNodes` | `boolean` | `false` | Stack leaf nodes |
|
|
148
|
+
| `onNodeClick` | `(node: NodeData) => void` | - | Node click handler |
|
|
149
|
+
| `className` | `string` | - | CSS class for container |
|
|
150
|
+
| `style` | `CSSProperties` | - | Inline styles for container |
|
|
151
|
+
| `canvasStyle` | `string` | - | CSS styles for canvas |
|
|
152
|
+
|
|
153
|
+
## Ref Methods
|
|
154
|
+
|
|
155
|
+
| Method | Description |
|
|
156
|
+
| -------------------------- | --------------------------------- |
|
|
157
|
+
| `changeLayout(direction?)` | Change tree direction |
|
|
158
|
+
| `collapse(nodeId)` | Collapse a node |
|
|
159
|
+
| `expand(nodeId)` | Expand a node |
|
|
160
|
+
| `fitScreen()` | Fit tree to screen |
|
|
161
|
+
| `getGraph()` | Get the underlying graph instance |
|
|
162
|
+
|
|
163
|
+
## Data Structure
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
interface NodeData<T = unknown> {
|
|
167
|
+
id: string; // unique identifier
|
|
168
|
+
name?: string; // display name (or use contentKey)
|
|
169
|
+
data?: T; // custom data for templates
|
|
170
|
+
options?: NodeOptions; // per-node styling
|
|
171
|
+
children?: NodeData<T>[];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
interface NodeOptions {
|
|
175
|
+
nodeBGColor?: string;
|
|
176
|
+
nodeBGColorHover?: string;
|
|
177
|
+
borderColor?: string;
|
|
178
|
+
borderColorHover?: string;
|
|
179
|
+
fontSize?: string;
|
|
180
|
+
fontFamily?: string;
|
|
181
|
+
fontWeight?: string | number;
|
|
182
|
+
fontColor?: string;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## TypeScript Support
|
|
187
|
+
|
|
188
|
+
Full TypeScript support with exported types:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
import type {
|
|
192
|
+
ApexTreeProps,
|
|
193
|
+
ApexTreeRef,
|
|
194
|
+
NodeData,
|
|
195
|
+
NodeOptions,
|
|
196
|
+
TreeDirection,
|
|
197
|
+
GraphInstance,
|
|
198
|
+
} from "react-apextree";
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
React-Apextree uses the same dual-license model as ApexCharts. See [LICENSE](./LICENSE) for details.
|
|
204
|
+
|
|
205
|
+
- **Free** for individuals, non-profits, and small businesses (< $2M revenue)
|
|
206
|
+
- **Commercial license** required for larger organizations
|
|
207
|
+
|
|
208
|
+
## Links
|
|
209
|
+
|
|
210
|
+
- [ApexTree Documentation](https://github.com/apexcharts/apextree)
|
|
211
|
+
- [ApexCharts](https://apexcharts.com)
|
|
212
|
+
- [License Information](https://apexcharts.com/license)
|
|
213
|
+
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
### Running the Demo
|
|
217
|
+
|
|
218
|
+
The package includes a demo app showcasing various features:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# clone the repo
|
|
222
|
+
git clone https://github.com/apexcharts/react-apextree.git
|
|
223
|
+
cd react-apextree
|
|
224
|
+
|
|
225
|
+
# install dependencies
|
|
226
|
+
npm install
|
|
227
|
+
cd demo && npm install && cd ..
|
|
228
|
+
|
|
229
|
+
# build the library
|
|
230
|
+
npm run build
|
|
231
|
+
|
|
232
|
+
# run the demo
|
|
233
|
+
npm run demo
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Then open http://localhost:5173 to see the examples.
|
|
237
|
+
|
|
238
|
+
### Available Scripts
|
|
239
|
+
|
|
240
|
+
- `npm run build` - Build the library
|
|
241
|
+
- `npm run dev` - Build in watch mode
|
|
242
|
+
- `npm run typecheck` - Run TypeScript type checking
|
|
243
|
+
- `npm run demo` - Run the demo app
|
|
244
|
+
- `npm run demo:build` - Build the demo app
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var react=require('react'),x=require('apextree'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var x__default=/*#__PURE__*/_interopDefault(x);function u(c){let{className:e,style:d,data:a,...i}=c,l={};for(let[r,n]of Object.entries(i))n!==void 0&&(l[r]=n);return l}var C=react.forwardRef(function(e,d){let{data:a,className:i,style:l}=e,r=react.useRef(null),n=react.useRef(null),f=react.useMemo(()=>u(e),[e.width,e.height,e.direction,e.contentKey,e.siblingSpacing,e.childrenSpacing,e.containerClassName,e.canvasStyle,e.nodeWidth,e.nodeHeight,e.nodeTemplate,e.nodeStyle,e.nodeClassName,e.nodeBGColor,e.nodeBGColorHover,e.borderWidth,e.borderStyle,e.borderRadius,e.borderColor,e.borderColorHover,e.edgeWidth,e.edgeColor,e.edgeColorHover,e.fontSize,e.fontFamily,e.fontWeight,e.fontColor,e.enableTooltip,e.tooltipId,e.tooltipTemplate,e.tooltipMaxWidth,e.tooltipMinWidth,e.tooltipBorderColor,e.tooltipBGColor,e.tooltipFontColor,e.tooltipFontSize,e.tooltipPadding,e.tooltipOffset,e.highlightOnHover,e.enableToolbar,e.enableExpandCollapse,e.expandCollapseButtonBGColor,e.expandCollapseButtonBorderColor,e.groupLeafNodes,e.groupLeafNodesSpacing,e.onNodeClick]);return react.useImperativeHandle(d,()=>({changeLayout:t=>{var o;(o=n.current)==null||o.changeLayout(t);},collapse:t=>{var o;(o=n.current)==null||o.collapse(t);},expand:t=>{var o;(o=n.current)==null||o.expand(t);},fitScreen:()=>{var t;(t=n.current)==null||t.fitScreen();},getGraph:()=>n.current}),[]),react.useEffect(()=>{if(!r.current||!a)return;r.current.innerHTML="";let t=new x__default.default(r.current,f);n.current=t.render(a);},[a,f]),jsxRuntime.jsx("div",{ref:r,className:i,style:l})});exports.ApexTreeChart=C;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/ApexTreeChart.tsx"],"names":["buildOptions","props","_className","_style","_data","options","cleanOptions","key","value","ApexTreeChart","forwardRef","ref","data","className","style","containerRef","useRef","graphRef","useMemo","useImperativeHandle","direction","_a","nodeId","useEffect","tree","ApexTree","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ApexTreeProps } from './types';\n\n/**\n * extracts ApexTree options from React props\n * filters out react-specific props (className, style, data)\n */\nexport function buildOptions<T>(props: ApexTreeProps<T>): Record<string, unknown> {\n const {\n // exclude react-specific props\n className: _className,\n style: _style,\n data: _data,\n // everything else becomes options\n ...options\n } = props;\n\n // remove undefined values to let ApexTree use its defaults\n const cleanOptions: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(options)) {\n if (value !== undefined) {\n cleanOptions[key] = value;\n }\n }\n\n return cleanOptions;\n}\n\n/**\n * shallow comparison of two objects\n * used to detect option changes\n */\nexport function shallowEqual(\n obj1: Record<string, unknown>,\n obj2: Record<string, unknown>\n): boolean {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) {\n return false;\n }\n\n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) {\n return false;\n }\n }\n\n return true;\n}\n","import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react';\nimport ApexTree from 'apextree';\nimport type { ApexTreeProps, ApexTreeRef, GraphInstance } from './types';\nimport { buildOptions } from './utils';\n\n/**\n * react wrapper component for ApexTree\n */\nexport const ApexTreeChart = forwardRef<ApexTreeRef, ApexTreeProps>(\n function ApexTreeChart(props, ref) {\n const { data, className, style } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const graphRef = useRef<GraphInstance | null>(null);\n\n // memoize options to prevent unnecessary re-renders\n const options = useMemo(() => buildOptions(props), [\n props.width,\n props.height,\n props.direction,\n props.contentKey,\n props.siblingSpacing,\n props.childrenSpacing,\n props.containerClassName,\n props.canvasStyle,\n props.nodeWidth,\n props.nodeHeight,\n props.nodeTemplate,\n props.nodeStyle,\n props.nodeClassName,\n props.nodeBGColor,\n props.nodeBGColorHover,\n props.borderWidth,\n props.borderStyle,\n props.borderRadius,\n props.borderColor,\n props.borderColorHover,\n props.edgeWidth,\n props.edgeColor,\n props.edgeColorHover,\n props.fontSize,\n props.fontFamily,\n props.fontWeight,\n props.fontColor,\n props.enableTooltip,\n props.tooltipId,\n props.tooltipTemplate,\n props.tooltipMaxWidth,\n props.tooltipMinWidth,\n props.tooltipBorderColor,\n props.tooltipBGColor,\n props.tooltipFontColor,\n props.tooltipFontSize,\n props.tooltipPadding,\n props.tooltipOffset,\n props.highlightOnHover,\n props.enableToolbar,\n props.enableExpandCollapse,\n props.expandCollapseButtonBGColor,\n props.expandCollapseButtonBorderColor,\n props.groupLeafNodes,\n props.groupLeafNodesSpacing,\n props.onNodeClick,\n ]);\n\n // expose imperative methods via ref\n useImperativeHandle(ref, () => ({\n changeLayout: (direction) => {\n graphRef.current?.changeLayout(direction);\n },\n collapse: (nodeId) => {\n graphRef.current?.collapse(nodeId);\n },\n expand: (nodeId) => {\n graphRef.current?.expand(nodeId);\n },\n fitScreen: () => {\n graphRef.current?.fitScreen();\n },\n getGraph: () => graphRef.current,\n }), []);\n\n // render tree when data or options change\n useEffect(() => {\n if (!containerRef.current || !data) {\n return;\n }\n\n // clear previous content\n containerRef.current.innerHTML = '';\n\n // create new tree instance and render\n const tree = new ApexTree(containerRef.current, options);\n graphRef.current = tree.render(data as any) as GraphInstance;\n }, [data, options]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={style}\n />\n );\n }\n);"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
type TreeDirection = 'top' | 'bottom' | 'left' | 'right';
|
|
5
|
+
/**
|
|
6
|
+
* node data structure expected by ApexTree
|
|
7
|
+
*/
|
|
8
|
+
interface NodeData<T = unknown> {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly name?: string;
|
|
11
|
+
readonly data?: T;
|
|
12
|
+
readonly options?: NodeOptions;
|
|
13
|
+
readonly children?: Array<NodeData<T>>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* per-node styling options
|
|
17
|
+
*/
|
|
18
|
+
interface NodeOptions {
|
|
19
|
+
nodeBGColor?: string;
|
|
20
|
+
nodeBGColorHover?: string;
|
|
21
|
+
borderColor?: string;
|
|
22
|
+
borderColorHover?: string;
|
|
23
|
+
fontSize?: string;
|
|
24
|
+
fontFamily?: string;
|
|
25
|
+
fontWeight?: string | number;
|
|
26
|
+
fontColor?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* graph instance returned by ApexTree.render()
|
|
30
|
+
*/
|
|
31
|
+
interface GraphInstance {
|
|
32
|
+
changeLayout: (direction?: TreeDirection) => void;
|
|
33
|
+
collapse: (nodeId: string) => void;
|
|
34
|
+
expand: (nodeId: string) => void;
|
|
35
|
+
fitScreen: () => void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* imperative methods exposed via ref
|
|
39
|
+
*/
|
|
40
|
+
interface ApexTreeRef {
|
|
41
|
+
changeLayout: (direction?: TreeDirection) => void;
|
|
42
|
+
collapse: (nodeId: string) => void;
|
|
43
|
+
expand: (nodeId: string) => void;
|
|
44
|
+
fitScreen: () => void;
|
|
45
|
+
getGraph: () => GraphInstance | null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* props for the ApexTree React component
|
|
49
|
+
*/
|
|
50
|
+
interface ApexTreeProps<T = unknown> {
|
|
51
|
+
data: NodeData<T>;
|
|
52
|
+
className?: string;
|
|
53
|
+
style?: CSSProperties;
|
|
54
|
+
width?: number | string;
|
|
55
|
+
height?: number | string;
|
|
56
|
+
direction?: TreeDirection;
|
|
57
|
+
siblingSpacing?: number;
|
|
58
|
+
childrenSpacing?: number;
|
|
59
|
+
containerClassName?: string;
|
|
60
|
+
canvasStyle?: string;
|
|
61
|
+
contentKey?: string;
|
|
62
|
+
nodeWidth?: number;
|
|
63
|
+
nodeHeight?: number;
|
|
64
|
+
nodeTemplate?: (content: unknown) => string;
|
|
65
|
+
nodeStyle?: string;
|
|
66
|
+
nodeClassName?: string;
|
|
67
|
+
nodeBGColor?: string;
|
|
68
|
+
nodeBGColorHover?: string;
|
|
69
|
+
borderWidth?: number;
|
|
70
|
+
borderStyle?: string;
|
|
71
|
+
borderRadius?: string;
|
|
72
|
+
borderColor?: string;
|
|
73
|
+
borderColorHover?: string;
|
|
74
|
+
edgeWidth?: number;
|
|
75
|
+
edgeColor?: string;
|
|
76
|
+
edgeColorHover?: string;
|
|
77
|
+
fontSize?: string;
|
|
78
|
+
fontFamily?: string;
|
|
79
|
+
fontWeight?: string;
|
|
80
|
+
fontColor?: string;
|
|
81
|
+
enableTooltip?: boolean;
|
|
82
|
+
tooltipId?: string;
|
|
83
|
+
tooltipTemplate?: (content: unknown) => string;
|
|
84
|
+
tooltipMaxWidth?: number;
|
|
85
|
+
tooltipMinWidth?: number;
|
|
86
|
+
tooltipBorderColor?: string;
|
|
87
|
+
tooltipBGColor?: string;
|
|
88
|
+
tooltipFontColor?: string;
|
|
89
|
+
tooltipFontSize?: string;
|
|
90
|
+
tooltipPadding?: number;
|
|
91
|
+
tooltipOffset?: number;
|
|
92
|
+
highlightOnHover?: boolean;
|
|
93
|
+
enableToolbar?: boolean;
|
|
94
|
+
enableExpandCollapse?: boolean;
|
|
95
|
+
expandCollapseButtonBGColor?: string;
|
|
96
|
+
expandCollapseButtonBorderColor?: string;
|
|
97
|
+
groupLeafNodes?: boolean;
|
|
98
|
+
groupLeafNodesSpacing?: number;
|
|
99
|
+
onNodeClick?: (node: NodeData<T>) => void;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* react wrapper component for ApexTree
|
|
104
|
+
*/
|
|
105
|
+
declare const ApexTreeChart: react.ForwardRefExoticComponent<ApexTreeProps<unknown> & react.RefAttributes<ApexTreeRef>>;
|
|
106
|
+
|
|
107
|
+
export { ApexTreeChart, type ApexTreeProps, type ApexTreeRef, type GraphInstance, type NodeData, type NodeOptions, type TreeDirection };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
type TreeDirection = 'top' | 'bottom' | 'left' | 'right';
|
|
5
|
+
/**
|
|
6
|
+
* node data structure expected by ApexTree
|
|
7
|
+
*/
|
|
8
|
+
interface NodeData<T = unknown> {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly name?: string;
|
|
11
|
+
readonly data?: T;
|
|
12
|
+
readonly options?: NodeOptions;
|
|
13
|
+
readonly children?: Array<NodeData<T>>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* per-node styling options
|
|
17
|
+
*/
|
|
18
|
+
interface NodeOptions {
|
|
19
|
+
nodeBGColor?: string;
|
|
20
|
+
nodeBGColorHover?: string;
|
|
21
|
+
borderColor?: string;
|
|
22
|
+
borderColorHover?: string;
|
|
23
|
+
fontSize?: string;
|
|
24
|
+
fontFamily?: string;
|
|
25
|
+
fontWeight?: string | number;
|
|
26
|
+
fontColor?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* graph instance returned by ApexTree.render()
|
|
30
|
+
*/
|
|
31
|
+
interface GraphInstance {
|
|
32
|
+
changeLayout: (direction?: TreeDirection) => void;
|
|
33
|
+
collapse: (nodeId: string) => void;
|
|
34
|
+
expand: (nodeId: string) => void;
|
|
35
|
+
fitScreen: () => void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* imperative methods exposed via ref
|
|
39
|
+
*/
|
|
40
|
+
interface ApexTreeRef {
|
|
41
|
+
changeLayout: (direction?: TreeDirection) => void;
|
|
42
|
+
collapse: (nodeId: string) => void;
|
|
43
|
+
expand: (nodeId: string) => void;
|
|
44
|
+
fitScreen: () => void;
|
|
45
|
+
getGraph: () => GraphInstance | null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* props for the ApexTree React component
|
|
49
|
+
*/
|
|
50
|
+
interface ApexTreeProps<T = unknown> {
|
|
51
|
+
data: NodeData<T>;
|
|
52
|
+
className?: string;
|
|
53
|
+
style?: CSSProperties;
|
|
54
|
+
width?: number | string;
|
|
55
|
+
height?: number | string;
|
|
56
|
+
direction?: TreeDirection;
|
|
57
|
+
siblingSpacing?: number;
|
|
58
|
+
childrenSpacing?: number;
|
|
59
|
+
containerClassName?: string;
|
|
60
|
+
canvasStyle?: string;
|
|
61
|
+
contentKey?: string;
|
|
62
|
+
nodeWidth?: number;
|
|
63
|
+
nodeHeight?: number;
|
|
64
|
+
nodeTemplate?: (content: unknown) => string;
|
|
65
|
+
nodeStyle?: string;
|
|
66
|
+
nodeClassName?: string;
|
|
67
|
+
nodeBGColor?: string;
|
|
68
|
+
nodeBGColorHover?: string;
|
|
69
|
+
borderWidth?: number;
|
|
70
|
+
borderStyle?: string;
|
|
71
|
+
borderRadius?: string;
|
|
72
|
+
borderColor?: string;
|
|
73
|
+
borderColorHover?: string;
|
|
74
|
+
edgeWidth?: number;
|
|
75
|
+
edgeColor?: string;
|
|
76
|
+
edgeColorHover?: string;
|
|
77
|
+
fontSize?: string;
|
|
78
|
+
fontFamily?: string;
|
|
79
|
+
fontWeight?: string;
|
|
80
|
+
fontColor?: string;
|
|
81
|
+
enableTooltip?: boolean;
|
|
82
|
+
tooltipId?: string;
|
|
83
|
+
tooltipTemplate?: (content: unknown) => string;
|
|
84
|
+
tooltipMaxWidth?: number;
|
|
85
|
+
tooltipMinWidth?: number;
|
|
86
|
+
tooltipBorderColor?: string;
|
|
87
|
+
tooltipBGColor?: string;
|
|
88
|
+
tooltipFontColor?: string;
|
|
89
|
+
tooltipFontSize?: string;
|
|
90
|
+
tooltipPadding?: number;
|
|
91
|
+
tooltipOffset?: number;
|
|
92
|
+
highlightOnHover?: boolean;
|
|
93
|
+
enableToolbar?: boolean;
|
|
94
|
+
enableExpandCollapse?: boolean;
|
|
95
|
+
expandCollapseButtonBGColor?: string;
|
|
96
|
+
expandCollapseButtonBorderColor?: string;
|
|
97
|
+
groupLeafNodes?: boolean;
|
|
98
|
+
groupLeafNodesSpacing?: number;
|
|
99
|
+
onNodeClick?: (node: NodeData<T>) => void;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* react wrapper component for ApexTree
|
|
104
|
+
*/
|
|
105
|
+
declare const ApexTreeChart: react.ForwardRefExoticComponent<ApexTreeProps<unknown> & react.RefAttributes<ApexTreeRef>>;
|
|
106
|
+
|
|
107
|
+
export { ApexTreeChart, type ApexTreeProps, type ApexTreeRef, type GraphInstance, type NodeData, type NodeOptions, type TreeDirection };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {forwardRef,useRef,useMemo,useImperativeHandle,useEffect}from'react';import x from'apextree';import {jsx}from'react/jsx-runtime';function u(c){let{className:e,style:d,data:a,...i}=c,l={};for(let[r,n]of Object.entries(i))n!==void 0&&(l[r]=n);return l}var C=forwardRef(function(e,d){let{data:a,className:i,style:l}=e,r=useRef(null),n=useRef(null),f=useMemo(()=>u(e),[e.width,e.height,e.direction,e.contentKey,e.siblingSpacing,e.childrenSpacing,e.containerClassName,e.canvasStyle,e.nodeWidth,e.nodeHeight,e.nodeTemplate,e.nodeStyle,e.nodeClassName,e.nodeBGColor,e.nodeBGColorHover,e.borderWidth,e.borderStyle,e.borderRadius,e.borderColor,e.borderColorHover,e.edgeWidth,e.edgeColor,e.edgeColorHover,e.fontSize,e.fontFamily,e.fontWeight,e.fontColor,e.enableTooltip,e.tooltipId,e.tooltipTemplate,e.tooltipMaxWidth,e.tooltipMinWidth,e.tooltipBorderColor,e.tooltipBGColor,e.tooltipFontColor,e.tooltipFontSize,e.tooltipPadding,e.tooltipOffset,e.highlightOnHover,e.enableToolbar,e.enableExpandCollapse,e.expandCollapseButtonBGColor,e.expandCollapseButtonBorderColor,e.groupLeafNodes,e.groupLeafNodesSpacing,e.onNodeClick]);return useImperativeHandle(d,()=>({changeLayout:t=>{var o;(o=n.current)==null||o.changeLayout(t);},collapse:t=>{var o;(o=n.current)==null||o.collapse(t);},expand:t=>{var o;(o=n.current)==null||o.expand(t);},fitScreen:()=>{var t;(t=n.current)==null||t.fitScreen();},getGraph:()=>n.current}),[]),useEffect(()=>{if(!r.current||!a)return;r.current.innerHTML="";let t=new x(r.current,f);n.current=t.render(a);},[a,f]),jsx("div",{ref:r,className:i,style:l})});export{C as ApexTreeChart};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/ApexTreeChart.tsx"],"names":["buildOptions","props","_className","_style","_data","options","cleanOptions","key","value","ApexTreeChart","forwardRef","ref","data","className","style","containerRef","useRef","graphRef","useMemo","useImperativeHandle","direction","_a","nodeId","useEffect","tree","ApexTree","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import type { ApexTreeProps } from './types';\n\n/**\n * extracts ApexTree options from React props\n * filters out react-specific props (className, style, data)\n */\nexport function buildOptions<T>(props: ApexTreeProps<T>): Record<string, unknown> {\n const {\n // exclude react-specific props\n className: _className,\n style: _style,\n data: _data,\n // everything else becomes options\n ...options\n } = props;\n\n // remove undefined values to let ApexTree use its defaults\n const cleanOptions: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(options)) {\n if (value !== undefined) {\n cleanOptions[key] = value;\n }\n }\n\n return cleanOptions;\n}\n\n/**\n * shallow comparison of two objects\n * used to detect option changes\n */\nexport function shallowEqual(\n obj1: Record<string, unknown>,\n obj2: Record<string, unknown>\n): boolean {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) {\n return false;\n }\n\n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) {\n return false;\n }\n }\n\n return true;\n}\n","import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react';\nimport ApexTree from 'apextree';\nimport type { ApexTreeProps, ApexTreeRef, GraphInstance } from './types';\nimport { buildOptions } from './utils';\n\n/**\n * react wrapper component for ApexTree\n */\nexport const ApexTreeChart = forwardRef<ApexTreeRef, ApexTreeProps>(\n function ApexTreeChart(props, ref) {\n const { data, className, style } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const graphRef = useRef<GraphInstance | null>(null);\n\n // memoize options to prevent unnecessary re-renders\n const options = useMemo(() => buildOptions(props), [\n props.width,\n props.height,\n props.direction,\n props.contentKey,\n props.siblingSpacing,\n props.childrenSpacing,\n props.containerClassName,\n props.canvasStyle,\n props.nodeWidth,\n props.nodeHeight,\n props.nodeTemplate,\n props.nodeStyle,\n props.nodeClassName,\n props.nodeBGColor,\n props.nodeBGColorHover,\n props.borderWidth,\n props.borderStyle,\n props.borderRadius,\n props.borderColor,\n props.borderColorHover,\n props.edgeWidth,\n props.edgeColor,\n props.edgeColorHover,\n props.fontSize,\n props.fontFamily,\n props.fontWeight,\n props.fontColor,\n props.enableTooltip,\n props.tooltipId,\n props.tooltipTemplate,\n props.tooltipMaxWidth,\n props.tooltipMinWidth,\n props.tooltipBorderColor,\n props.tooltipBGColor,\n props.tooltipFontColor,\n props.tooltipFontSize,\n props.tooltipPadding,\n props.tooltipOffset,\n props.highlightOnHover,\n props.enableToolbar,\n props.enableExpandCollapse,\n props.expandCollapseButtonBGColor,\n props.expandCollapseButtonBorderColor,\n props.groupLeafNodes,\n props.groupLeafNodesSpacing,\n props.onNodeClick,\n ]);\n\n // expose imperative methods via ref\n useImperativeHandle(ref, () => ({\n changeLayout: (direction) => {\n graphRef.current?.changeLayout(direction);\n },\n collapse: (nodeId) => {\n graphRef.current?.collapse(nodeId);\n },\n expand: (nodeId) => {\n graphRef.current?.expand(nodeId);\n },\n fitScreen: () => {\n graphRef.current?.fitScreen();\n },\n getGraph: () => graphRef.current,\n }), []);\n\n // render tree when data or options change\n useEffect(() => {\n if (!containerRef.current || !data) {\n return;\n }\n\n // clear previous content\n containerRef.current.innerHTML = '';\n\n // create new tree instance and render\n const tree = new ApexTree(containerRef.current, options);\n graphRef.current = tree.render(data as any) as GraphInstance;\n }, [data, options]);\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={style}\n />\n );\n }\n);"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-apextree",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "React wrapper for ApexTree - a JavaScript library for creating organizational and hierarchical charts",
|
|
5
|
+
"author": "ApexCharts",
|
|
6
|
+
"license": "See LICENSE in LICENSE",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/apexcharts/react-apextree"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/apexcharts/react-apextree#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/apexcharts/react-apextree/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"react",
|
|
17
|
+
"apextree",
|
|
18
|
+
"tree",
|
|
19
|
+
"chart",
|
|
20
|
+
"organizational-chart",
|
|
21
|
+
"org-chart",
|
|
22
|
+
"hierarchy",
|
|
23
|
+
"diagram",
|
|
24
|
+
"svg"
|
|
25
|
+
],
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.cjs",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"import": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"default": "./dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"require": {
|
|
37
|
+
"types": "./dist/index.d.cts",
|
|
38
|
+
"default": "./dist/index.cjs"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"LICENSE",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"sideEffects": false,
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"dev": "tsup --watch",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"prepublishOnly": "npm run build",
|
|
53
|
+
"demo": "npm run --prefix demo dev",
|
|
54
|
+
"demo:build": "npm run --prefix demo build"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"apextree": ">=1.6.1",
|
|
58
|
+
"react": ">=17.0.0",
|
|
59
|
+
"react-dom": ">=17.0.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/react": "^19.2.7",
|
|
63
|
+
"@types/react-dom": "^19.2.3",
|
|
64
|
+
"apextree": "^1.6.1",
|
|
65
|
+
"react": "^19.2.3",
|
|
66
|
+
"react-dom": "^19.2.3",
|
|
67
|
+
"tsup": "^8.5.1",
|
|
68
|
+
"typescript": "^5.9.3"
|
|
69
|
+
}
|
|
70
|
+
}
|