@asup/tree-of-nodes 0.9.0 → 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/README.md +137 -3
- package/dist/cjs/main.js +76 -79
- package/dist/cjs/src/__mocks__/mockNodes.d.ts +4 -0
- package/dist/cjs/src/__mocks__/styleMock.d.ts +2 -0
- package/dist/cjs/src/__tests__/TreeNode.test.d.ts +1 -0
- package/dist/cjs/src/__tests__/TreeOfNodes.test.d.ts +1 -0
- package/dist/cjs/src/__tests__/WordEntry.test.d.ts +1 -0
- package/dist/cjs/{components → src/components}/ContextMenu.d.ts +1 -0
- package/dist/cjs/{components → src/components}/ContextMenuProvider.d.ts +0 -0
- package/dist/cjs/{components → src/components}/TreeNode.d.ts +0 -0
- package/dist/cjs/src/components/TreeOfNodes.d.ts +20 -0
- package/dist/cjs/src/components/TreeOfNodesContext.d.ts +28 -0
- package/dist/cjs/{components → src/components}/WordEntry.d.ts +2 -2
- package/dist/cjs/{components → src/components}/index.d.ts +3 -2
- package/dist/cjs/{main.d.ts → src/main.d.ts} +0 -0
- package/dist/cjs/style.css +1 -0
- package/dist/{esm/main.js → main.js} +63 -66
- package/dist/src/__mocks__/mockNodes.d.ts +4 -0
- package/dist/src/__mocks__/styleMock.d.ts +2 -0
- package/dist/src/__tests__/TreeNode.test.d.ts +1 -0
- package/dist/src/__tests__/TreeOfNodes.test.d.ts +1 -0
- package/dist/src/__tests__/WordEntry.test.d.ts +1 -0
- package/dist/{esm → src}/components/ContextMenu.d.ts +1 -0
- package/dist/{esm → src}/components/ContextMenuProvider.d.ts +0 -0
- package/dist/{esm → src}/components/TreeNode.d.ts +0 -0
- package/dist/src/components/TreeOfNodes.d.ts +20 -0
- package/dist/src/components/TreeOfNodesContext.d.ts +28 -0
- package/dist/{esm → src}/components/WordEntry.d.ts +2 -2
- package/dist/{esm → src}/components/index.d.ts +3 -2
- package/dist/{esm → src}/main.d.ts +0 -0
- package/dist/style.css +1 -0
- package/dist/tree-of-nodes.d.ts +30 -68
- package/package.json +9 -6
- package/dist/cjs/components/TreeOfNodes.d.ts +0 -44
- package/dist/esm/components/TreeOfNodes.d.ts +0 -44
- package/dist/favicon.80afec6c.ico +0 -0
- package/dist/index.8d438033.css +0 -12012
- package/dist/index.8d438033.css.map +0 -1
- package/dist/index.8ffabb7b.js +0 -188309
- package/dist/index.8ffabb7b.js.map +0 -1
- package/dist/index.c9e3402a.css +0 -19
- package/dist/index.c9e3402a.css.map +0 -1
- package/dist/index.d92d26d8.css +0 -12048
- package/dist/index.d92d26d8.css.map +0 -1
- package/dist/index.html +0 -17
- package/dist/public/manifest.webmanifest +0 -1
|
@@ -8,8 +8,7 @@ const ContextMenu = React__default.forwardRef(({ entries, visible, xPos, yPos },
|
|
|
8
8
|
top: `${yPos}px`,
|
|
9
9
|
left: `${xPos}px`,
|
|
10
10
|
}, children: entries.map((e, i) => (jsx("div", { className: 'context-menu-item', onClick: () => {
|
|
11
|
-
|
|
12
|
-
e.action();
|
|
11
|
+
e.action && e.action();
|
|
13
12
|
}, children: e.label ?? '' }, i))) }));
|
|
14
13
|
});
|
|
15
14
|
|
|
@@ -1322,7 +1321,7 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
1322
1321
|
const Spinner = /*#__PURE__*/React.forwardRef(({
|
|
1323
1322
|
bsPrefix,
|
|
1324
1323
|
variant,
|
|
1325
|
-
animation,
|
|
1324
|
+
animation = 'border',
|
|
1326
1325
|
size,
|
|
1327
1326
|
// Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
|
|
1328
1327
|
as: Component = 'div',
|
|
@@ -1485,79 +1484,46 @@ ExclamationCircleFill.defaultProps = {
|
|
|
1485
1484
|
var ExclamationCircleFill$1 = ExclamationCircleFill;
|
|
1486
1485
|
|
|
1487
1486
|
const TreeOfNodesContext = createContext({
|
|
1487
|
+
id: 'tree-of-nodes',
|
|
1488
1488
|
nodeList: [],
|
|
1489
|
-
});
|
|
1490
|
-
const TreeOfNodes = ({ nodeList, roots,
|
|
1491
|
-
// canAddRoot = false,
|
|
1492
|
-
canRemoveRoot = false, canRenameRoot = false, canAddChildren = false, canRemoveChildren = false, canRenameChildren = false, selectedId, handleSelect = () => {
|
|
1493
|
-
return;
|
|
1494
|
-
}, onAdd, onRename, onRemove, }) => {
|
|
1495
|
-
const [expandedNodes, setExpandedNodes] = useState([]);
|
|
1496
|
-
// Change expansion and update context
|
|
1497
|
-
const changeExpand = useCallback((eKey, force) => {
|
|
1498
|
-
const newExpandedNodes = [...expandedNodes];
|
|
1499
|
-
const ix = newExpandedNodes.findIndex((nKey) => nKey === eKey);
|
|
1500
|
-
if ((ix === -1 && force === undefined) || force === true)
|
|
1501
|
-
newExpandedNodes.push(eKey);
|
|
1502
|
-
else
|
|
1503
|
-
newExpandedNodes.splice(ix, 1);
|
|
1504
|
-
setExpandedNodes(newExpandedNodes);
|
|
1505
|
-
}, [expandedNodes]);
|
|
1506
|
-
return (jsx(ContextMenuProvider, { children: jsx(TreeOfNodesContext.Provider, { value: {
|
|
1507
|
-
nodeList,
|
|
1508
|
-
selectedId,
|
|
1509
|
-
handleSelect,
|
|
1510
|
-
expandedNodes,
|
|
1511
|
-
handleExpandClick: (r, f) => changeExpand(r, f),
|
|
1512
|
-
onAddChild: onAdd,
|
|
1513
|
-
onRename,
|
|
1514
|
-
onRemove,
|
|
1515
|
-
}, children: roots.map((r) => (jsx(TreeNode, { id: r, canRemove: canRemoveRoot, canAddChildren: canAddChildren, canRename: canRenameRoot, canRemoveChildren: canRemoveChildren, canRenameChildren: canRenameChildren }, r))) }) }));
|
|
1516
|
-
};
|
|
1489
|
+
});
|
|
1517
1490
|
|
|
1518
1491
|
const WordEntry = React__default.forwardRef(({ id, value, editing, saving, setValue, sendEscape, style }, ref) => {
|
|
1519
|
-
const [currentStyle, setCurrentStyle] = useState({
|
|
1520
|
-
display: 'inline-block',
|
|
1521
|
-
});
|
|
1522
1492
|
WordEntry.displayName = 'WordEntry';
|
|
1493
|
+
const currentStyle = useMemo(() => {
|
|
1494
|
+
return {
|
|
1495
|
+
display: 'inline-block',
|
|
1496
|
+
padding: '1px',
|
|
1497
|
+
paddingLeft: '3px',
|
|
1498
|
+
paddingRight: '3px',
|
|
1499
|
+
border: '1px',
|
|
1500
|
+
borderRadius: '3px',
|
|
1501
|
+
...style,
|
|
1502
|
+
};
|
|
1503
|
+
}, [style]);
|
|
1523
1504
|
const [currentValue, setCurrentValue] = useState(value ?? '');
|
|
1524
1505
|
useEffect(() => {
|
|
1525
1506
|
setCurrentValue(value ?? '');
|
|
1526
1507
|
}, [value]);
|
|
1527
1508
|
const returnData = useCallback(() => {
|
|
1528
|
-
|
|
1529
|
-
return;
|
|
1530
|
-
setValue(currentValue);
|
|
1509
|
+
setValue && setValue(currentValue);
|
|
1531
1510
|
}, [currentValue, setValue]);
|
|
1532
1511
|
const keyPress = useCallback((e) => {
|
|
1533
1512
|
if (e.code === 'Escape') {
|
|
1534
1513
|
setCurrentValue(value ?? '');
|
|
1535
|
-
|
|
1536
|
-
sendEscape();
|
|
1514
|
+
sendEscape && sendEscape();
|
|
1537
1515
|
}
|
|
1538
1516
|
else if (e.code === 'Enter') {
|
|
1539
1517
|
returnData();
|
|
1540
1518
|
}
|
|
1541
1519
|
}, [returnData, sendEscape, value]);
|
|
1542
|
-
useEffect(() => {
|
|
1543
|
-
setCurrentStyle({
|
|
1544
|
-
padding: '1px',
|
|
1545
|
-
paddingLeft: '3px',
|
|
1546
|
-
paddingRight: '3px',
|
|
1547
|
-
border: '1px',
|
|
1548
|
-
borderRadius: '3px',
|
|
1549
|
-
...style,
|
|
1550
|
-
display: 'inline-block',
|
|
1551
|
-
});
|
|
1552
|
-
}, [style]);
|
|
1553
1520
|
// Simple if not editing
|
|
1554
1521
|
if (!editing) {
|
|
1555
|
-
return jsx("span", { style: currentStyle, children: value });
|
|
1522
|
+
return (jsx("span", { style: currentStyle, id: String(id), children: value }));
|
|
1556
1523
|
}
|
|
1557
|
-
return (jsxs("div", { style: currentStyle, id: id
|
|
1524
|
+
return (jsxs("div", { style: currentStyle, id: `${id}-holder`, children: [saving && (jsx(Spinner$1, { id: `${id}-spinner`, size: 'sm', animation: 'border' })), jsx("input", { id: String(id), ref: ref, type: 'text', style: {
|
|
1558
1525
|
lineHeight: '0.75rem',
|
|
1559
|
-
border:
|
|
1560
|
-
margin: !saving && !editing ? '1px' : '',
|
|
1526
|
+
border: '1px dotted black',
|
|
1561
1527
|
width: 'auto',
|
|
1562
1528
|
minWidth: '0',
|
|
1563
1529
|
}, value: currentValue, disabled: saving, onChange: (e) => setCurrentValue(e.currentTarget.value), onBlur: returnData, onKeyDownCapture: keyPress })] }));
|
|
@@ -1570,7 +1536,7 @@ const TreeNode = ({ id, canRemove, canRename, canAddChildren, canRemoveChildren,
|
|
|
1570
1536
|
// Node information
|
|
1571
1537
|
const thisNode = useMemo(() => treeContext.nodeList.find((n) => n.id === id), [id, treeContext.nodeList]);
|
|
1572
1538
|
const childNodes = useMemo(() => treeContext.nodeList.filter((n) => n.parentId === id), [id, treeContext.nodeList]);
|
|
1573
|
-
//
|
|
1539
|
+
// State
|
|
1574
1540
|
const loading = useMemo(() => treeContext.nodeList.findIndex((n) => n.id === id) === -1, [id, treeContext.nodeList]);
|
|
1575
1541
|
const [error, setError] = useState(false);
|
|
1576
1542
|
const [errorText, setErrotText] = useState(null);
|
|
@@ -1618,14 +1584,12 @@ const TreeNode = ({ id, canRemove, canRename, canAddChildren, canRemoveChildren,
|
|
|
1618
1584
|
}, [handleReturn, id, treeContext]);
|
|
1619
1585
|
const deleteThis = useCallback(async () => {
|
|
1620
1586
|
setUpdatingNode(true);
|
|
1621
|
-
if (thisNode === undefined)
|
|
1622
|
-
return;
|
|
1623
1587
|
if (treeContext.onRemove) {
|
|
1624
1588
|
handleReturn(await treeContext.onRemove(id));
|
|
1625
1589
|
}
|
|
1626
1590
|
setUpdatingNode(false);
|
|
1627
|
-
}, [handleReturn, id,
|
|
1628
|
-
//
|
|
1591
|
+
}, [handleReturn, id, treeContext]);
|
|
1592
|
+
// Context actions
|
|
1629
1593
|
const addChild = useCallback(() => {
|
|
1630
1594
|
if (menuContext.set) {
|
|
1631
1595
|
menuContext.set({ visible: false });
|
|
@@ -1658,12 +1622,15 @@ const TreeNode = ({ id, canRemove, canRename, canAddChildren, canRemoveChildren,
|
|
|
1658
1622
|
e.preventDefault();
|
|
1659
1623
|
e.stopPropagation();
|
|
1660
1624
|
const menuItems = [];
|
|
1661
|
-
if (canAddChildren)
|
|
1662
|
-
menuItems.push({ label: 'Add
|
|
1663
|
-
|
|
1625
|
+
if (canAddChildren) {
|
|
1626
|
+
menuItems.push({ label: 'Add', action: addChild });
|
|
1627
|
+
}
|
|
1628
|
+
if (canRename) {
|
|
1664
1629
|
menuItems.push({ label: 'Rename', action: renameThis });
|
|
1665
|
-
|
|
1630
|
+
}
|
|
1631
|
+
if (canRemove && (childNodes === undefined || childNodes.length === 0)) {
|
|
1666
1632
|
menuItems.push({ label: 'Delete', action: removeThis });
|
|
1633
|
+
}
|
|
1667
1634
|
if (typeof menuContext.set === 'function') {
|
|
1668
1635
|
menuContext.set({
|
|
1669
1636
|
visible: true,
|
|
@@ -1683,11 +1650,12 @@ const TreeNode = ({ id, canRemove, canRename, canAddChildren, canRemoveChildren,
|
|
|
1683
1650
|
renameThis,
|
|
1684
1651
|
]);
|
|
1685
1652
|
// Return node
|
|
1686
|
-
return (jsxs("div", { className: '
|
|
1653
|
+
return (jsxs("div", { id: `${treeContext.id}-treenode-${id}`, className: 'treenode', onClickCapture: () => treeContext.handleSelect && treeContext.handleSelect(id), onContextMenuCapture: () => treeContext.handleSelect && treeContext.handleSelect(id), onFocusCapture: () => treeContext.handleSelect && treeContext.handleSelect(id), children: [error ? (jsxs(Fragment, { children: [jsx(ExclamationCircleFill$1, { color: 'var(--bs-danger)' }), ' ', errorText && errorText !== '' ? errorText : 'An unknown error has occured'] })) : loading ? (jsxs(Fragment, { children: [jsx(Spinner$1, { size: 'sm', animation: 'border' }), ' ', "Loading..."] })) : (jsxs("span", { onContextMenu: showMenu, children: [childNodes !== undefined && childNodes.length > 0 ? (!expanded ? (jsx(CaretRightFill$1, { role: 'button', "aria-expanded": false, id: `${treeContext.id}-treenode-caret-${id}`, onClick: () => treeContext.handleExpandClick && treeContext.handleExpandClick(id) })) : (jsx(CaretDownFill$1, { role: 'button', "aria-expanded": true, id: `${treeContext.id}-treenode-caret-${id}`, onClick: () => treeContext.handleExpandClick && treeContext.handleExpandClick(id) }))) : (jsx(CaretRight$1, { role: 'button', "aria-expanded": false, "aria-disabled": true })), thisNode && (jsx(WordEntry, { id: `${treeContext.id}-treenode-entry-${id}`, ref: currentNameRef, value: thisNode.label, editing: renaming, saving: updatingNode, setValue: (ret) => renameNode(ret), sendEscape: () => setRenaming(false), style: {
|
|
1687
1654
|
border: currentBorder,
|
|
1688
1655
|
margin: currentBorder === '' ? '1px' : '',
|
|
1689
1656
|
backgroundColor: currentBorder === '' ? '' : 'lightgrey',
|
|
1690
|
-
} }))
|
|
1657
|
+
} }))] })), childNodes !== undefined &&
|
|
1658
|
+
childNodes.map((h, i) => (jsx("span", { id: `${treeContext.id}-treenode-child-${h.id}`, style: {
|
|
1691
1659
|
marginLeft: '16px',
|
|
1692
1660
|
display: 'block',
|
|
1693
1661
|
maxHeight: expanded ? '99999px' : '0px',
|
|
@@ -1696,11 +1664,40 @@ const TreeNode = ({ id, canRemove, canRename, canAddChildren, canRemoveChildren,
|
|
|
1696
1664
|
visibility: expanded ? 'inherit' : 'hidden',
|
|
1697
1665
|
opacity: expanded ? 1 : 0,
|
|
1698
1666
|
transition: 'visibility .3s, opacity .3s ease-in-out, max-height 0.3s ease-in-out',
|
|
1699
|
-
}, children: jsx(TreeNode, { id: h.id, canRemove: canRemoveChildren, canRename: canRenameChildren, canAddChildren: canAddChildren, canRemoveChildren: canRemoveChildren, canRenameChildren: canRenameChildren }) }, h.id)))
|
|
1667
|
+
}, children: jsx(TreeNode, { id: h.id, canRemove: canRemoveChildren, canRename: canRenameChildren, canAddChildren: canAddChildren, canRemoveChildren: canRemoveChildren, canRenameChildren: canRenameChildren }) }, h.id))), showNewNode && (jsx("div", { children: jsx(WordEntry, { style: { marginLeft: '14px' }, id: `treenode-new-${id}`, ref: newNameRef, editing: true, setValue: (ret) => {
|
|
1700
1668
|
confirmNewNode(ret);
|
|
1701
1669
|
}, saving: savingNewNode, sendEscape: () => {
|
|
1702
1670
|
setShowNewNode(false);
|
|
1703
1671
|
} }) }))] }));
|
|
1704
1672
|
};
|
|
1705
1673
|
|
|
1674
|
+
const TreeOfNodes = ({ id, nodeList, roots,
|
|
1675
|
+
// canAddRoot = false,
|
|
1676
|
+
canRemoveRoot = false, canRenameRoot = false, canAddChildren = false, canRemoveChildren = false, canRenameChildren = false, selectedId, handleSelect = () => {
|
|
1677
|
+
return;
|
|
1678
|
+
}, onAdd, onRename, onRemove, }) => {
|
|
1679
|
+
const [expandedNodes, setExpandedNodes] = useState([]);
|
|
1680
|
+
// Change expansion and update context
|
|
1681
|
+
const changeExpand = useCallback((eKey, force) => {
|
|
1682
|
+
const newExpandedNodes = [...expandedNodes];
|
|
1683
|
+
const ix = newExpandedNodes.findIndex((nKey) => nKey === eKey);
|
|
1684
|
+
if ((ix === -1 && force === undefined) || force === true)
|
|
1685
|
+
newExpandedNodes.push(eKey);
|
|
1686
|
+
else
|
|
1687
|
+
newExpandedNodes.splice(ix, 1);
|
|
1688
|
+
setExpandedNodes(newExpandedNodes);
|
|
1689
|
+
}, [expandedNodes]);
|
|
1690
|
+
return (jsx(ContextMenuProvider, { children: jsx(TreeOfNodesContext.Provider, { value: {
|
|
1691
|
+
id: id,
|
|
1692
|
+
nodeList,
|
|
1693
|
+
selectedId,
|
|
1694
|
+
handleSelect,
|
|
1695
|
+
expandedNodes,
|
|
1696
|
+
handleExpandClick: (r, f) => changeExpand(r, f),
|
|
1697
|
+
onAddChild: onAdd,
|
|
1698
|
+
onRename,
|
|
1699
|
+
onRemove,
|
|
1700
|
+
}, children: roots.map((r) => (jsx(TreeNode, { id: r, canRemove: canRemoveRoot, canAddChildren: canAddChildren, canRename: canRenameRoot, canRemoveChildren: canRemoveChildren, canRenameChildren: canRenameChildren }, r))) }) }));
|
|
1701
|
+
};
|
|
1702
|
+
|
|
1706
1703
|
export { ContextMenu, ContextMenuProvider, TreeNode, TreeOfNodes, WordEntry };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Key } from 'react';
|
|
2
|
+
import { iNodeUpdate, TreeNodeData } from './TreeOfNodesContext';
|
|
3
|
+
interface iTreeOfNodes<T> {
|
|
4
|
+
id: string;
|
|
5
|
+
nodeList: TreeNodeData<T>[];
|
|
6
|
+
roots: Key[];
|
|
7
|
+
selectedId?: Key;
|
|
8
|
+
handleSelect?: (ret: Key) => void;
|
|
9
|
+
onAdd?: (parentId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
10
|
+
onRename?: (childId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
11
|
+
onRemove?: (childId: Key) => Promise<iNodeUpdate>;
|
|
12
|
+
canAddRoot?: boolean;
|
|
13
|
+
canRemoveRoot?: boolean;
|
|
14
|
+
canRenameRoot?: boolean;
|
|
15
|
+
canAddChildren?: boolean;
|
|
16
|
+
canRemoveChildren?: boolean;
|
|
17
|
+
canRenameChildren?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const TreeOfNodes: <T extends unknown>({ id, nodeList, roots, canRemoveRoot, canRenameRoot, canAddChildren, canRemoveChildren, canRenameChildren, selectedId, handleSelect, onAdd, onRename, onRemove, }: iTreeOfNodes<T>) => JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Key } from 'react';
|
|
2
|
+
export interface iNodeUpdate {
|
|
3
|
+
success: boolean;
|
|
4
|
+
ErrorText?: string;
|
|
5
|
+
}
|
|
6
|
+
export type TreeNodeBase = {
|
|
7
|
+
id: Key;
|
|
8
|
+
label: string;
|
|
9
|
+
parentId?: Key;
|
|
10
|
+
};
|
|
11
|
+
export type TreeNodeData<T> = {
|
|
12
|
+
id: Key;
|
|
13
|
+
label: string;
|
|
14
|
+
parentId?: Key;
|
|
15
|
+
data: T;
|
|
16
|
+
};
|
|
17
|
+
export type TreeOfNodesContextData<T> = {
|
|
18
|
+
id: string;
|
|
19
|
+
nodeList: TreeNodeData<T>[];
|
|
20
|
+
selectedId?: Key;
|
|
21
|
+
handleSelect?: (ret: Key) => void;
|
|
22
|
+
expandedNodes?: Key[];
|
|
23
|
+
handleExpandClick?: (ret: Key, force?: boolean) => void;
|
|
24
|
+
onAddChild?: (parentId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
25
|
+
onRename?: (id: Key, newName: string) => Promise<iNodeUpdate>;
|
|
26
|
+
onRemove?: (id: Key) => Promise<iNodeUpdate>;
|
|
27
|
+
};
|
|
28
|
+
export declare const TreeOfNodesContext: import("react").Context<TreeOfNodesContextData<unknown>>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ContextMenu } from './ContextMenu';
|
|
2
2
|
import { ContextMenuProvider } from './ContextMenuProvider';
|
|
3
3
|
import { TreeNode } from './TreeNode';
|
|
4
|
-
import {
|
|
4
|
+
import { TreeOfNodes } from './TreeOfNodes';
|
|
5
|
+
import { iNodeUpdate, TreeNodeBase, TreeNodeData } from './TreeOfNodesContext';
|
|
5
6
|
import { WordEntry } from './WordEntry';
|
|
6
7
|
export { ContextMenu, ContextMenuProvider, TreeNode, TreeOfNodes, WordEntry };
|
|
7
|
-
export type { TreeNodeData, iNodeUpdate };
|
|
8
|
+
export type { TreeNodeBase, TreeNodeData, iNodeUpdate };
|
|
File without changes
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.context-menu{background-color:#fbfdf6;border:1px solid #111418;border-radius:8px;opacity:1;position:absolute;visibility:hidden}.context-menu.visible{visibility:"inherit"}.context-menu-item{color:#111418;cursor:pointer;min-width:80px;padding:0 4px}.context-menu-item:first-child{padding-top:2px}.context-menu-item:last-child{padding-bottom:2px}.context-menu-item:hover{background-color:#fbe9e6}.context-menu-item:hover:first-child{border-radius:6px 6px 0 0}.context-menu-item:hover:last-child{border-radius:0 0 6px 6px}
|
package/dist/tree-of-nodes.d.ts
CHANGED
|
@@ -1,70 +1,32 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
3
|
+
declare const ContextMenu: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
|
|
4
|
+
declare function ContextMenuProvider({ children }: {
|
|
5
|
+
children: any;
|
|
6
|
+
}): any;
|
|
7
|
+
declare function TreeNode({ id, canRemove, canRename, canAddChildren, canRemoveChildren, canRenameChildren, }: {
|
|
8
|
+
id: any;
|
|
9
|
+
canRemove: any;
|
|
10
|
+
canRename: any;
|
|
11
|
+
canAddChildren: any;
|
|
12
|
+
canRemoveChildren: any;
|
|
13
|
+
canRenameChildren: any;
|
|
14
|
+
}): any;
|
|
15
|
+
declare function TreeOfNodes({ id, nodeList, roots, canRemoveRoot, canRenameRoot, canAddChildren, canRemoveChildren, canRenameChildren, selectedId, handleSelect, onAdd, onRename, onRemove, }: {
|
|
16
|
+
id: any;
|
|
17
|
+
nodeList: any;
|
|
18
|
+
roots: any;
|
|
19
|
+
canRemoveRoot?: boolean | undefined;
|
|
20
|
+
canRenameRoot?: boolean | undefined;
|
|
21
|
+
canAddChildren?: boolean | undefined;
|
|
22
|
+
canRemoveChildren?: boolean | undefined;
|
|
23
|
+
canRenameChildren?: boolean | undefined;
|
|
24
|
+
selectedId: any;
|
|
25
|
+
handleSelect?: (() => void) | undefined;
|
|
26
|
+
onAdd: any;
|
|
27
|
+
onRename: any;
|
|
28
|
+
onRemove: any;
|
|
29
|
+
}): any;
|
|
30
|
+
declare const WordEntry: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
|
|
17
31
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
interface TreeNodeProps {
|
|
21
|
-
id: Key;
|
|
22
|
-
indentLevel?: number;
|
|
23
|
-
canRemove?: boolean;
|
|
24
|
-
canRename?: boolean;
|
|
25
|
-
canAddChildren?: boolean;
|
|
26
|
-
canRemoveChildren?: boolean;
|
|
27
|
-
canRenameChildren?: boolean;
|
|
28
|
-
refresh?: () => void;
|
|
29
|
-
}
|
|
30
|
-
declare const TreeNode: ({ id, canRemove, canRename, canAddChildren, canRemoveChildren, canRenameChildren, }: TreeNodeProps) => JSX.Element;
|
|
31
|
-
|
|
32
|
-
declare type TreeNodeData<T> = {
|
|
33
|
-
id: Key;
|
|
34
|
-
label: string;
|
|
35
|
-
parentId?: Key;
|
|
36
|
-
data: T;
|
|
37
|
-
};
|
|
38
|
-
interface iNodeUpdate {
|
|
39
|
-
success: boolean;
|
|
40
|
-
ErrorText?: string;
|
|
41
|
-
}
|
|
42
|
-
interface iTreeOfNodes<T> {
|
|
43
|
-
nodeList: TreeNodeData<T>[];
|
|
44
|
-
roots: Key[];
|
|
45
|
-
selectedId?: Key;
|
|
46
|
-
handleSelect?: (ret: Key) => void;
|
|
47
|
-
onAdd?: (parentId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
48
|
-
onRename?: (childId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
49
|
-
onRemove?: (childId: Key) => Promise<iNodeUpdate>;
|
|
50
|
-
canAddRoot?: boolean;
|
|
51
|
-
canRemoveRoot?: boolean;
|
|
52
|
-
canRenameRoot?: boolean;
|
|
53
|
-
canAddChildren?: boolean;
|
|
54
|
-
canRemoveChildren?: boolean;
|
|
55
|
-
canRenameChildren?: boolean;
|
|
56
|
-
}
|
|
57
|
-
declare const TreeOfNodes: <T extends object>({ nodeList, roots, canRemoveRoot, canRenameRoot, canAddChildren, canRemoveChildren, canRenameChildren, selectedId, handleSelect, onAdd, onRename, onRemove, }: iTreeOfNodes<T>) => JSX.Element;
|
|
58
|
-
|
|
59
|
-
interface WordEntryProps {
|
|
60
|
-
id?: string;
|
|
61
|
-
value?: string;
|
|
62
|
-
editing?: boolean;
|
|
63
|
-
saving?: boolean;
|
|
64
|
-
setValue?: (ret: string) => void;
|
|
65
|
-
sendEscape?: () => void;
|
|
66
|
-
style?: React.CSSProperties;
|
|
67
|
-
}
|
|
68
|
-
declare const WordEntry: React.ForwardRefExoticComponent<WordEntryProps & React.RefAttributes<HTMLInputElement>>;
|
|
69
|
-
|
|
70
|
-
export { ContextMenu, ContextMenuProvider, TreeNode, TreeNodeData, TreeOfNodes, WordEntry, iNodeUpdate };
|
|
32
|
+
export { ContextMenu, ContextMenuProvider, TreeNode, TreeOfNodes, WordEntry };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asup/tree-of-nodes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "REACT Typescript Treeview component",
|
|
5
5
|
"author": "Paul Thomas <@PaulDThomas>",
|
|
6
6
|
"private": false,
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
52
52
|
"husky": "^8.0.1",
|
|
53
53
|
"jest": "^29.2.2",
|
|
54
|
+
"jest-environment-jsdom": "^29.3.0",
|
|
54
55
|
"lint-staged": "^13.0.3",
|
|
55
56
|
"parcel": "^2.7.0",
|
|
56
57
|
"postcss": "^8.4.18",
|
|
@@ -61,15 +62,17 @@
|
|
|
61
62
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
62
63
|
"rollup-plugin-postcss": "^4.0.2",
|
|
63
64
|
"rollup-plugin-terser": "^7.0.2",
|
|
65
|
+
"rollup-plugin-typescript2": "^0.34.1",
|
|
64
66
|
"ts-jest": "^29.0.3",
|
|
65
67
|
"ts-node": "^10.9.1",
|
|
66
|
-
"
|
|
68
|
+
"tslib": "^2.4.1",
|
|
69
|
+
"typescript": "^4.9.3"
|
|
67
70
|
},
|
|
68
71
|
"lint-staged": {
|
|
69
72
|
"**/*": "prettier --write --ignore-unknown"
|
|
70
73
|
},
|
|
71
74
|
"main": "dist/cjs/main.js",
|
|
72
|
-
"module": "dist/
|
|
75
|
+
"module": "dist/main.js",
|
|
73
76
|
"types": "dist/tree-of-nodes.d.ts",
|
|
74
77
|
"files": [
|
|
75
78
|
"dist"
|
|
@@ -93,8 +96,8 @@
|
|
|
93
96
|
]
|
|
94
97
|
},
|
|
95
98
|
"scripts": {
|
|
96
|
-
"build": "rollup -c --configPlugin typescript
|
|
97
|
-
"start": "parcel demo/index.html",
|
|
98
|
-
"test": "jest"
|
|
99
|
+
"build": "rollup -c --configPlugin typescript",
|
|
100
|
+
"start": "parcel demo/index.html --dist-dir demo/dist",
|
|
101
|
+
"test": "jest --watch"
|
|
99
102
|
}
|
|
100
103
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Key } from 'react';
|
|
2
|
-
export declare type TreeNodeBase = {
|
|
3
|
-
id: Key;
|
|
4
|
-
label: string;
|
|
5
|
-
parentId?: Key;
|
|
6
|
-
};
|
|
7
|
-
export declare type TreeNodeData<T> = {
|
|
8
|
-
id: Key;
|
|
9
|
-
label: string;
|
|
10
|
-
parentId?: Key;
|
|
11
|
-
data: T;
|
|
12
|
-
};
|
|
13
|
-
export interface iNodeUpdate {
|
|
14
|
-
success: boolean;
|
|
15
|
-
ErrorText?: string;
|
|
16
|
-
}
|
|
17
|
-
interface iTreeOfNodes<T> {
|
|
18
|
-
nodeList: TreeNodeData<T>[];
|
|
19
|
-
roots: Key[];
|
|
20
|
-
selectedId?: Key;
|
|
21
|
-
handleSelect?: (ret: Key) => void;
|
|
22
|
-
onAdd?: (parentId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
23
|
-
onRename?: (childId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
24
|
-
onRemove?: (childId: Key) => Promise<iNodeUpdate>;
|
|
25
|
-
canAddRoot?: boolean;
|
|
26
|
-
canRemoveRoot?: boolean;
|
|
27
|
-
canRenameRoot?: boolean;
|
|
28
|
-
canAddChildren?: boolean;
|
|
29
|
-
canRemoveChildren?: boolean;
|
|
30
|
-
canRenameChildren?: boolean;
|
|
31
|
-
}
|
|
32
|
-
declare type TreeOfNodesContextData<T> = {
|
|
33
|
-
nodeList: TreeNodeData<T>[];
|
|
34
|
-
selectedId?: Key;
|
|
35
|
-
handleSelect?: (ret: Key) => void;
|
|
36
|
-
expandedNodes?: Key[];
|
|
37
|
-
handleExpandClick?: (ret: Key, force?: boolean) => void;
|
|
38
|
-
onAddChild?: (parentId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
39
|
-
onRename?: (id: Key, newName: string) => Promise<iNodeUpdate>;
|
|
40
|
-
onRemove?: (id: Key) => Promise<iNodeUpdate>;
|
|
41
|
-
};
|
|
42
|
-
export declare const TreeOfNodesContext: import("react").Context<TreeOfNodesContextData<object>>;
|
|
43
|
-
export declare const TreeOfNodes: <T extends object>({ nodeList, roots, canRemoveRoot, canRenameRoot, canAddChildren, canRemoveChildren, canRenameChildren, selectedId, handleSelect, onAdd, onRename, onRemove, }: iTreeOfNodes<T>) => JSX.Element;
|
|
44
|
-
export {};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Key } from 'react';
|
|
2
|
-
export declare type TreeNodeBase = {
|
|
3
|
-
id: Key;
|
|
4
|
-
label: string;
|
|
5
|
-
parentId?: Key;
|
|
6
|
-
};
|
|
7
|
-
export declare type TreeNodeData<T> = {
|
|
8
|
-
id: Key;
|
|
9
|
-
label: string;
|
|
10
|
-
parentId?: Key;
|
|
11
|
-
data: T;
|
|
12
|
-
};
|
|
13
|
-
export interface iNodeUpdate {
|
|
14
|
-
success: boolean;
|
|
15
|
-
ErrorText?: string;
|
|
16
|
-
}
|
|
17
|
-
interface iTreeOfNodes<T> {
|
|
18
|
-
nodeList: TreeNodeData<T>[];
|
|
19
|
-
roots: Key[];
|
|
20
|
-
selectedId?: Key;
|
|
21
|
-
handleSelect?: (ret: Key) => void;
|
|
22
|
-
onAdd?: (parentId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
23
|
-
onRename?: (childId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
24
|
-
onRemove?: (childId: Key) => Promise<iNodeUpdate>;
|
|
25
|
-
canAddRoot?: boolean;
|
|
26
|
-
canRemoveRoot?: boolean;
|
|
27
|
-
canRenameRoot?: boolean;
|
|
28
|
-
canAddChildren?: boolean;
|
|
29
|
-
canRemoveChildren?: boolean;
|
|
30
|
-
canRenameChildren?: boolean;
|
|
31
|
-
}
|
|
32
|
-
declare type TreeOfNodesContextData<T> = {
|
|
33
|
-
nodeList: TreeNodeData<T>[];
|
|
34
|
-
selectedId?: Key;
|
|
35
|
-
handleSelect?: (ret: Key) => void;
|
|
36
|
-
expandedNodes?: Key[];
|
|
37
|
-
handleExpandClick?: (ret: Key, force?: boolean) => void;
|
|
38
|
-
onAddChild?: (parentId: Key, newName: string) => Promise<iNodeUpdate>;
|
|
39
|
-
onRename?: (id: Key, newName: string) => Promise<iNodeUpdate>;
|
|
40
|
-
onRemove?: (id: Key) => Promise<iNodeUpdate>;
|
|
41
|
-
};
|
|
42
|
-
export declare const TreeOfNodesContext: import("react").Context<TreeOfNodesContextData<object>>;
|
|
43
|
-
export declare const TreeOfNodes: <T extends object>({ nodeList, roots, canRemoveRoot, canRenameRoot, canAddChildren, canRemoveChildren, canRenameChildren, selectedId, handleSelect, onAdd, onRename, onRemove, }: iTreeOfNodes<T>) => JSX.Element;
|
|
44
|
-
export {};
|
|
Binary file
|