Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16
4 changes: 4 additions & 0 deletions config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ module.exports = {
resolve: {
// our code can resolve 'xxx' instead of writing 'xxx.jsx'
extensions: ['*', '.js', '.jsx'],
fallback: {
'react/jsx-runtime': 'react/jsx-runtime.js',
'react/jsx-dev-runtime': 'react/jsx-dev-runtime.js',
},
},
module: {
// For every file that match regex in 'test', webpack pipes the code through to loaders
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "script-custom-react-folder-tree",
"version": "5.0.11",
"version": "5.1.0",
"description": "customizable react folder tree library",
"main": "dist/react-folder-tree.bundle.js",
"typings": "index.d.ts",
Expand Down Expand Up @@ -43,7 +43,7 @@
"license": "MIT",
"private": false,
"scripts": {
"prebuild": "del \"dist/\"",
"prebuild": "rimraf dist",
"build": "webpack --config config/webpack.prod.config.js",
"start": "cross-env NODE_ENV=development node scripts/dev-server.js",
"lint": "eslint src/ --ext .js,.jsx",
Expand Down Expand Up @@ -99,10 +99,14 @@
},
"peerDependencies": {
"react": "^16.8.0 || ^17",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^16.8.0 || ^17"
},
"dependencies": {
"prop-types": "^15.7.2",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-icons": "^4.1.0",
"use-tree-state": "1.0.0"
}
Expand Down
19 changes: 16 additions & 3 deletions src/components/FolderTree/FolderTree.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import PropTypes from 'prop-types';
import useTreeState, {
testData,
Expand Down Expand Up @@ -28,6 +30,10 @@ const FolderTree = ({
debug = false,
searchData = null,
showSearchData = false,
dndConfig = {
onDrop: null,
backend: null,
},
}) => {
const options = {
initCheckedStatus,
Expand Down Expand Up @@ -56,6 +62,7 @@ const FolderTree = ({
debug,
searchData,
showSearchData,
dndConfig,
};

/* ----------
Expand All @@ -69,9 +76,11 @@ const FolderTree = ({

return (
<div className='FolderTree'>
<ConfigContext.Provider value={configs}>
<TreeNode key={treeState._id} path={[]} {...treeState} />
</ConfigContext.Provider>
<DndProvider backend={ dndConfig.backend || HTML5Backend } options={ dndConfig.options }>
<ConfigContext.Provider value={configs}>
<TreeNode key={treeState._id} path={[]} {...treeState} />
</ConfigContext.Provider>
</DndProvider>
</div>
);
};
Expand Down Expand Up @@ -104,6 +113,10 @@ FolderTree.propTypes = {
debug: PropTypes.bool,
searchData: PropTypes.object,
showSearchData: PropTypes.bool,
dndConfig: PropTypes.shape({
backend: PropTypes.func,
onDrop: PropTypes.func,
}),
};

export {
Expand Down
11 changes: 10 additions & 1 deletion src/components/SandBox/SandBox.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import FolderTree, { testData } from '../FolderTree/FolderTree';

const makeId = (length) => {
Expand Down Expand Up @@ -63,7 +64,7 @@ const parseTestData = (node) => {
};

/* eslint-disable */
const SandBox = () => {
const SandBox = ({ dndConfig }) => {
const onTreeStateChange = (state, e) => console.log({ state, e });
const [tree, setTree] = useState(null);

Expand All @@ -79,6 +80,7 @@ const SandBox = () => {
!!tree && (
<div className='demo-sandbox'>
<FolderTree
dndConfig={dndConfig}
data={tree}
onChange={onTreeStateChange}
onIconClick={(e, nodeData) => {
Expand Down Expand Up @@ -110,4 +112,11 @@ const SandBox = () => {
);
};

SandBox.propTypes = {
dndConfig: PropTypes.shape({
backend: PropTypes.func,
onDrop: PropTypes.func,
}),
};

export default SandBox;
28 changes: 27 additions & 1 deletion src/components/TreeNode/TreeNode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React, {
useContext,
useState,
} from 'react';
import { useDrag, useDrop } from 'react-dnd';
import { NativeTypes } from 'react-dnd-html5-backend';
import PropTypes from 'prop-types';
import {
AiFillCaretRight,
Expand All @@ -25,6 +27,7 @@ import {
iconClassName,
getDefaultIcon,
} from '../../utils/iconUtils';
import { FileTreeDragTypes } from '../../utils/dnd';

const TreeNode = ({
path,
Expand All @@ -51,13 +54,26 @@ const TreeNode = ({
onIconClick,
showCheckbox,
readOnly,
dndConfig,

searchData,
showSearchData,

debug,
} = useContext(ConfigContext);

const { onDrop } = dndConfig || {};

const [_, drop] = useDrop(() => ({
accept: [FileTreeDragTypes.TREE_NODE, NativeTypes.FILE],
drop: item => {
onDrop?.(item);
},
collect: monitor => ({
isOver: monitor.isOver(),
}),
}), [onDrop]);

const isFolder = !!children;

let matchCount = 0;
Expand All @@ -80,6 +96,14 @@ const TreeNode = ({
...restData,
};

const [__, drag] = useDrag({
type: FileTreeDragTypes.TREE_NODE,
item: nodeData,
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
});

const level = path.length;

const offsetSize = !isFolder ? 0 : iconSize;
Expand Down Expand Up @@ -245,6 +269,7 @@ const TreeNode = ({
return (
<>
<div
ref={ isFolder ? drop : drag }
className={`TreeNode ${
isFolder ? 'TreeNode__folder' : 'TreeNode__file'
} ${isSelected ? 'TreeNode__selected' : ''} ${
Expand Down Expand Up @@ -301,7 +326,8 @@ TreeNode.propTypes = {
name: PropTypes.string.isRequired,
checked: PropTypes.number.isRequired,
isOpen: PropTypes.bool,

fileID: PropTypes.string,
folderID: PropTypes.string,
children: PropTypes.array,
};

Expand Down
5 changes: 5 additions & 0 deletions src/components/TreeNode/TreeNode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const deleteNode = jest.fn();
const addNode = jest.fn();
const toggleOpen = jest.fn();
const onNameClick = jest.fn();
const dndConfig = {
onDrop: null,
backend: null,
};

const render = ({
iconComponents = {},
Expand All @@ -39,6 +43,7 @@ const render = ({
indentPixels,
showCheckbox,
readOnly,
dndConfig,
};

node = mount((
Expand Down
14 changes: 14 additions & 0 deletions src/test/jest-setup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import React from 'react';
import { configure } from 'enzyme';
// import Adapter from 'enzyme-adapter-react-16';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';

configure({ adapter: new Adapter() });

// Mock implementation for the DndProvider component
const DndProvider = ({ children }) => <div>{children}</div>;

jest.mock('react-dnd', () => ({
useDrag: jest.fn((...args) => [{ isDragging: false }, jest.fn()]),
useDrop: jest.fn((...args) => [{ isOver: false }, jest.fn()]),
DndProvider,
}));

jest.mock('react-dnd-html5-backend', () => ({
HTML5Backend: jest.fn(),
}));
7 changes: 7 additions & 0 deletions src/utils/dnd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { HTML5Backend } from 'react-dnd-html5-backend';

export const AppDndBackend = HTML5Backend;

export const FileTreeDragTypes = {
TREE_NODE: 'TREE_NODE',
};
72 changes: 70 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,13 @@
dependencies:
regenerator-runtime "^0.13.4"

"@babel/runtime@^7.9.2":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec"
integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==
dependencies:
regenerator-runtime "^0.13.11"

"@babel/template@^7.14.5", "@babel/template@^7.3.3":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
Expand Down Expand Up @@ -1152,6 +1159,21 @@
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23"
integrity sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==

"@react-dnd/asap@^5.0.1":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-5.0.2.tgz#1f81f124c1cd6f39511c11a881cfb0f715343488"
integrity sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==

"@react-dnd/invariant@^4.0.1":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/invariant/-/invariant-4.0.2.tgz#b92edffca10a26466643349fac7cdfb8799769df"
integrity sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==

"@react-dnd/shallowequal@^4.0.1":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz#d1b4befa423f692fa4abf1c79209702e7d8ae4b4"
integrity sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==

"@sinonjs/commons@^1.7.0":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
Expand Down Expand Up @@ -2901,6 +2923,15 @@ discontinuous-range@1.0.0:
resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=

dnd-core@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-16.0.1.tgz#a1c213ed08961f6bd1959a28bb76f1a868360d19"
integrity sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==
dependencies:
"@react-dnd/asap" "^5.0.1"
"@react-dnd/invariant" "^4.0.1"
redux "^4.2.0"

dns-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
Expand Down Expand Up @@ -3624,7 +3655,7 @@ extsprintf@^1.2.0:
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=

fast-deep-equal@^3.1.1:
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
Expand Down Expand Up @@ -4140,6 +4171,13 @@ he@^1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==

hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies:
react-is "^16.7.0"

hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
Expand Down Expand Up @@ -6802,6 +6840,24 @@ raw-body@2.4.0:
iconv-lite "0.4.24"
unpipe "1.0.0"

react-dnd-html5-backend@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz#87faef15845d512a23b3c08d29ecfd34871688b6"
integrity sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==
dependencies:
dnd-core "^16.0.1"

react-dnd@^16.0.1:
version "16.0.1"
resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-16.0.1.tgz#2442a3ec67892c60d40a1559eef45498ba26fa37"
integrity sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==
dependencies:
"@react-dnd/invariant" "^4.0.1"
"@react-dnd/shallowequal" "^4.0.1"
dnd-core "^16.0.1"
fast-deep-equal "^3.1.3"
hoist-non-react-statics "^3.3.2"

"react-dom@^16.8.0 || ^17":
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
Expand All @@ -6821,7 +6877,7 @@ react-icons@^4.1.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==

react-is@^16.13.1, react-is@^16.8.1, react-is@^16.8.6:
react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
Expand Down Expand Up @@ -6961,6 +7017,13 @@ redent@^1.0.0:
indent-string "^2.1.0"
strip-indent "^1.0.1"

redux@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
dependencies:
"@babel/runtime" "^7.9.2"

reflect.ownkeys@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460"
Expand All @@ -6978,6 +7041,11 @@ regenerate@^1.4.0:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==

regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==

regenerator-runtime@^0.13.4:
version "0.13.7"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
Expand Down