diff --git a/Demo2.gif b/Demo2.gif new file mode 100644 index 0000000..6d98d44 Binary files /dev/null and b/Demo2.gif differ diff --git a/README.md b/README.md index 738e85c..5afbff1 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ A basic tree file system that allows customisation ### 1 Demo +Version 1.1.0 +![](Demo2.gif) + +Version 1.0.6 ![](Demo.gif) You can also try out [here](https://tharain.github.io/react-tree-file-system/) @@ -230,7 +234,8 @@ interface Node { | value | The Tree structure given in [point 4](#tree) | Node[] | undefined | | fileOnClick | Called when file is clicked | (event, indexes: number[], value: Node) => void | undefined | | folderOnClick | Called when folder is clicked | (event, indexes: number[], state: boolean, value: Node) => void | undefined | -| onDrag | Called when something is dragged on folder | (event, fromIndexes, toIndexes) => void | undefined | +| onDrop | Called when something is dragged on folder [Replace onDrag] | (event, fromIndexes, toIndexes) => void | undefined | +| onDrag | Called when something is dragged on folder [Depreciated] | (event, fromIndexes, toIndexes) => void | undefined | | folderIcon | Replace the default folder icon | JSX.Element | undefined | | fileIcon | Replace the default file icon | JSX.Element | undefined | | style | customize the general style | React.CSSProperties | undefined | diff --git a/index.css b/index.css index 9ce0ee8..fead32b 100644 --- a/index.css +++ b/index.css @@ -8,7 +8,7 @@ white-space: nowrap; } -.tree_file_system_node:focus { +.tree_file_system_node:hover { background: #DDD; } diff --git a/lib/components/Tree/index.d.ts b/lib/components/Tree/index.d.ts index 1bfd528..7246dd2 100644 --- a/lib/components/Tree/index.d.ts +++ b/lib/components/Tree/index.d.ts @@ -3,11 +3,14 @@ interface Props { value: Node[]; fileOnClick: (event: React.SyntheticEvent, indexes: number[], value: Node) => void; folderOnClick: (event: React.SyntheticEvent, indexes: number[], state: boolean, value: Node) => void; + onDrop?: (fromIndexes: number[], toIndexes: number[]) => void; onDrag?: (fromIndexes: number[], toIndexes: number[]) => void; folderIcon?: JSX.Element; fileIcon?: JSX.Element; style?: React.CSSProperties; isDraggable?: boolean; + selected?: string; + selectedClassName?: string; } interface Node { title: string; @@ -15,7 +18,9 @@ interface Node { isLocked?: boolean; isHidden?: boolean; children?: Node[]; + style?: React.CSSProperties; + className?: string; [extra: string]: any; } -declare const Tree: ({ value, fileOnClick, folderOnClick, fileIcon, folderIcon, style, isDraggable, onDrag }: Props) => JSX.Element; +declare const Tree: ({ value, fileOnClick, folderOnClick, fileIcon, folderIcon, style, isDraggable, onDrop, onDrag, selected, selectedClassName }: Props) => JSX.Element; export default Tree; diff --git a/lib/components/Tree/index.js b/lib/components/Tree/index.js index 5346a13..f0f6073 100644 --- a/lib/components/Tree/index.js +++ b/lib/components/Tree/index.js @@ -21,14 +21,14 @@ Object.defineProperty(exports, "__esModule", { value: true }); var React = require("react"); var react_fontawesome_1 = require("@fortawesome/react-fontawesome"); var free_regular_svg_icons_1 = require("@fortawesome/free-regular-svg-icons"); -var renderChildren = function (children, indexes, fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable) { - return (React.createElement("div", { key: indexes[indexes.length - 1] + "_child", className: "tree_file_system_children" }, renderParent(children, indexes, fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable))); +var renderChildren = function (children, indexes, fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName) { + return (React.createElement("div", { key: indexes[indexes.length - 1] + "_child", className: "tree_file_system_children" }, renderParent(children, indexes, fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName))); }; -var renderParent = function (parent, indexes, fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable) { +var renderParent = function (parent, indexes, fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName) { if (indexes === void 0) { indexes = []; } var rend = []; parent.sort(function (a, b) { return a.title.localeCompare(b.title); }).forEach(function (p, i) { - rend.push(React.createElement("div", { key: i + "_node", draggable: isDraggable, onDragStart: function (e) { + rend.push(React.createElement("div", { key: i + "_node", draggable: isDraggable, style: p.style, onDragStart: function (e) { var newIndexes = __spreadArrays(indexes, [i]); e.dataTransfer.setData('react_tree_file_system_from', newIndexes.join(',')); }, onDrop: function (e) { @@ -37,12 +37,12 @@ var renderParent = function (parent, indexes, fileOnClick, folderOnClick, onDrag var ids = e.dataTransfer.getData("react_tree_file_system_from").split(',').filter(function (x) { return x !== ''; }).map(function (x) { return Number(x); }); var newIndexes = __spreadArrays(indexes, [i]); if (!newIndexes.slice(0, ids.length).join(',').startsWith(ids.join(','))) { - onDrag && onDrag(ids, newIndexes); + onDrop ? onDrop(ids, newIndexes) : onDrag && onDrag(ids, newIndexes); } } }, onDragOver: function (e) { e.preventDefault(); - }, role: "button", className: "tree_file_system_node", onClick: function (event) { + }, role: "button", className: "tree_file_system_node " + (__spreadArrays(indexes, [i]).join(',') === selected && (selectedClassName || 'tree_file_system_node_selected')) + " " + p.className, onClick: function (event) { var newIndexes = __spreadArrays(indexes, [i]); if (!p.children || ((p.children && p.children.length === 0) && p.type !== 'folder')) { fileOnClick && fileOnClick(event, newIndexes, __assign({}, p)); @@ -57,13 +57,13 @@ var renderParent = function (parent, indexes, fileOnClick, folderOnClick, onDrag p.title))); if (p.isOpen) { var newIndexes = __spreadArrays(indexes, [i]); - rend.push(renderChildren(p.children || [], newIndexes, fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable)); + rend.push(renderChildren(p.children || [], newIndexes, fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)); } }); return rend; }; var Tree = function (_a) { - var value = _a.value, fileOnClick = _a.fileOnClick, folderOnClick = _a.folderOnClick, fileIcon = _a.fileIcon, folderIcon = _a.folderIcon, style = _a.style, isDraggable = _a.isDraggable, onDrag = _a.onDrag; - return React.createElement("div", { style: __assign({}, style) }, renderParent(value, [], fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable)); + var value = _a.value, fileOnClick = _a.fileOnClick, folderOnClick = _a.folderOnClick, fileIcon = _a.fileIcon, folderIcon = _a.folderIcon, style = _a.style, isDraggable = _a.isDraggable, onDrop = _a.onDrop, onDrag = _a.onDrag, selected = _a.selected, selectedClassName = _a.selectedClassName; + return React.createElement("div", { style: __assign({}, style) }, renderParent(value, [], fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)); }; exports.default = Tree; diff --git a/package.json b/package.json index dd36ede..dd5c73a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-tree-file-system", - "version": "1.0.6", + "version": "1.1.0", "description": "To initialize a simple customizable tree view for file system for React", "main": "index.js", "scripts": { diff --git a/src/components/Tree/index.tsx b/src/components/Tree/index.tsx index ed4f64c..83d3014 100644 --- a/src/components/Tree/index.tsx +++ b/src/components/Tree/index.tsx @@ -6,6 +6,7 @@ interface Props { value: Node[], fileOnClick: (event: React.SyntheticEvent, indexes: number[], value: Node) => void, folderOnClick: (event: React.SyntheticEvent, indexes: number[], state: boolean, value: Node) => void, + onDrop?: (fromIndexes: number[], toIndexes: number[]) => void, onDrag?: (fromIndexes: number[], toIndexes: number[]) => void, folderIcon?: JSX.Element, fileIcon?: JSX.Element, @@ -31,6 +32,7 @@ const renderChildren = ( indexes: number[], fileOnClick?: (event: React.SyntheticEvent, indexes: number[], value: Node) => void, folderOnClick?: (event: React.SyntheticEvent, indexes: number[], state: boolean, value: Node) => void, + onDrop?: (fromIndexes: number[], toIndexes: number[]) => void, onDrag?: (fromIndexes: number[], toIndexes: number[]) => void, fileIcon?: JSX.Element, folderIcon?: JSX.Element, @@ -40,7 +42,7 @@ const renderChildren = ( ) => { return (
- {renderParent(children, indexes, fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)} + {renderParent(children, indexes, fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)}
) } @@ -50,6 +52,7 @@ const renderParent = ( indexes: number[] = [], fileOnClick?: (event: React.SyntheticEvent, indexes: number[], value: Node) => void, folderOnClick?: (event: React.SyntheticEvent, indexes: number[], state: boolean, value: Node) => void, + onDrop?: (fromIndexes: number[], toIndexes: number[]) => void, onDrag?: (fromIndexes: number[], toIndexes: number[]) => void, fileIcon?: JSX.Element, folderIcon?: JSX.Element, @@ -74,7 +77,7 @@ const renderParent = ( const ids = e.dataTransfer.getData("react_tree_file_system_from").split(',').filter(x=>x !== '').map(x => Number(x)); const newIndexes = [...indexes, i]; if(!newIndexes.slice(0,ids.length).join(',').startsWith(ids.join(','))) { - onDrag && onDrag(ids, newIndexes); + onDrop ? onDrop(ids, newIndexes) : onDrag && onDrag(ids, newIndexes); } } }} @@ -104,12 +107,12 @@ const renderParent = ( if(p.isOpen) { const newIndexes = [...indexes, i]; - rend.push(renderChildren(p.children || [], newIndexes, fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)); + rend.push(renderChildren(p.children || [], newIndexes, fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)); } }) return rend; } -const Tree = ({ value, fileOnClick, folderOnClick, fileIcon, folderIcon, style, isDraggable, onDrag, selected, selectedClassName }: Props) =>
{renderParent(value, [], fileOnClick, folderOnClick, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)}
; +const Tree = ({ value, fileOnClick, folderOnClick, fileIcon, folderIcon, style, isDraggable, onDrop, onDrag, selected, selectedClassName }: Props) =>
{renderParent(value, [], fileOnClick, folderOnClick, onDrop, onDrag, fileIcon, folderIcon, isDraggable, selected, selectedClassName)}
; export default Tree; diff --git a/src/demo/App.jsx b/src/demo/App.jsx index 43a09a2..386e886 100644 --- a/src/demo/App.jsx +++ b/src/demo/App.jsx @@ -139,12 +139,13 @@ This is a demo of the file system. isDraggable style={{ padding: 20, borderTop: '2px solid black' }} value={this.state.defaultTree} - onDrag={(fromIndexes, toIndexes) => { + onDrop={(fromIndexes, toIndexes) => { this.setState(prevState => { const extractData = getRecursiveItem(prevState.defaultTree, fromIndexes, 0); const extraData = recursivelySetChild(prevState.defaultTree, toIndexes, 0, extractData); const newData = popRecursiveItem(prevState.defaultTree, fromIndexes, 0); return { + selected: toIndexes.join(','), defaultTree: newData } })