@scena/react-folder
Version:
<p align="middle" ><img src="https://raw.githubusercontent.com/daybrush/react-folder/master/public/logo.png"/></p> <h2 align="middle">React Folder</h2> <p align="middle"> <a href="https://www.npmjs.com/package/@scena/react-folder" target="_blank"><img src
1,021 lines (1,009 loc) • 37.3 kB
JavaScript
/*
Copyright (c) 2021 Daybrush
name: @scena/react-folder
license: MIT
author: Daybrush
repository: https://github.com/daybrush/react-folder
version: 0.9.3
*/
import { createContext, createRef, createElement, PureComponent } from 'react';
import { isString, isArray, find, hasClass, findIndex, between } from '@daybrush/utils';
import { prefixNames, prefixCSS, refs, ref } from 'framework-utils';
import KeyController from 'keycon';
import Gesto from 'gesto';
import { styled } from 'react-css-styled';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf || {
__proto__: []
} instanceof Array && function (d, b) {
d.__proto__ = b;
} || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
};
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
}
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j];
return r;
}
var PREFIX = "scena-folder-";
var RootFolderContext = createContext(null);
function prefix() {
var classNames = [];
for (var _i = 0; _i < arguments.length; _i++) {
classNames[_i] = arguments[_i];
}
return prefixNames.apply(void 0, __spreadArrays([PREFIX], classNames));
}
function getId(idProperty, info, index, scope) {
return isString(idProperty) ? info[idProperty] : idProperty(info, index, scope);
}
function getName(nameProperty, info, index, scope) {
return isString(nameProperty) ? info[nameProperty] : nameProperty(info, index, scope);
}
function getChildren(childrenProperty, info, scope) {
return isString(childrenProperty) ? info[childrenProperty] : childrenProperty(info, scope);
}
function getPath(pathProperty, id, scope, info, index) {
return isString(pathProperty) ? info[pathProperty] : pathProperty(id, scope, info, index);
}
function isEqualArray(a, b) {
return a.length === b.length && a.every(function (v, i) {
return v === b[i];
});
}
function isArrayContains(arr1, arr2) {
return arr1.every(function (el, i) {
return el === arr2[i];
});
}
var FileManager = /*#__PURE__*/function (_super) {
__extends(FileManager, _super);
function FileManager() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.folderRef = createRef();
return _this;
}
var __proto = FileManager.prototype;
__proto.render = function () {
var _a;
var _b = this.props,
childrenProperty = _b.childrenProperty,
pathProperty = _b.pathProperty,
nameProperty = _b.nameProperty,
idProperty = _b.idProperty,
index = _b.index,
info = _b.info,
scope = _b.scope,
FileComponent = _b.FileComponent,
FoldIcon = _b.FoldIcon,
isPadding = _b.isPadding,
_c = _b.showFoldIcon,
showFoldIcon = _c === void 0 ? true : _c,
gap = _b.gap,
multiselect = _b.multiselect,
selected = _b.selected,
folded = _b.folded,
originalInfos = _b.originalInfos,
pathSeperator = _b.pathSeperator,
passWrapperProps = _b.passWrapperProps,
gapOffset = _b.gapOffset,
preventSelect = _b.preventSelect,
renderOnFolded = _b.renderOnFolded;
var id = getId(idProperty, info, index, scope);
var name = getName(nameProperty, info, index, scope);
var children = getChildren(childrenProperty, info, scope);
var path = getPath(pathProperty, id, scope, info, index);
var pathUrl = path.join(pathSeperator);
var nextScope = __spreadArrays(scope, [id]);
var length = scope.length;
var isFolder = children && children.length > 0;
var gapWidth = gap * (length + 1) + gapOffset;
var isFolded = this.isFolded(pathUrl);
var isSelected = this.isSelected(pathUrl);
var className = prefix("file", isSelected ? "selected" : "");
var style = (_a = {}, _a[isPadding ? "paddingLeft" : "marginLeft"] = gapWidth + "px", _a.width = isPadding ? "100%" : "calc(100% - " + gapWidth + "px)", _a);
var _d = passWrapperProps({
className: className,
style: style,
scope: scope,
name: name,
value: info,
path: path,
gapWidth: gapWidth,
isSelected: isSelected
}) || {},
passedStyle = _d.style,
otherProps = __rest(_d, ["style"]);
if (passedStyle) {
style = __assign(__assign({}, style), passedStyle);
}
return createElement("div", {
className: prefix("property")
}, createElement("div", __assign({
className: className,
"data-file-path": pathUrl,
style: style
}, otherProps), createElement("div", {
className: prefix("file-name")
}, isFolder && FoldIcon && showFoldIcon && createElement(FoldIcon, {
className: prefix("fold-icon", isFolded ? "fold" : ""),
scope: scope,
name: name,
value: info,
path: path,
isSelected: isSelected,
isFolded: isFolded
}), createElement(FileComponent, {
scope: scope,
name: name,
value: info,
path: path
}))), isFolder && (renderOnFolded || !isFolded) && createElement(FolderManager, {
ref: this.folderRef,
scope: nextScope,
infos: children,
FileComponent: FileComponent,
FoldIcon: FoldIcon,
nameProperty: nameProperty,
idProperty: idProperty,
pathProperty: pathProperty,
childrenProperty: childrenProperty,
showFoldIcon: showFoldIcon,
selected: selected,
preventSelect: preventSelect,
folded: folded,
renderOnFolded: renderOnFolded,
isPadding: isPadding,
gap: gap,
gapOffset: gapOffset,
multiselect: multiselect,
originalInfos: originalInfos,
isChild: true,
display: isFolded ? "none" : "block",
pathSeperator: pathSeperator,
passWrapperProps: passWrapperProps
}));
};
__proto.getInfo = function () {
return this.props.info;
};
__proto.isSelected = function (path) {
var selected = this.props.selected;
return selected && selected.indexOf(path) > -1;
};
__proto.isFolded = function (path) {
var folded = this.props.folded;
return folded && folded.indexOf(path) > -1;
};
__proto.findFile = function (targetPathUrl) {
var _a = this.props,
childrenProperty = _a.childrenProperty,
pathProperty = _a.pathProperty,
idProperty = _a.idProperty,
index = _a.index,
info = _a.info,
scope = _a.scope,
pathSeperator = _a.pathSeperator;
var id = getId(idProperty, info, index, scope);
var children = getChildren(childrenProperty, info, scope);
var path = getPath(pathProperty, id, scope, info, index);
var pathUrl = path.join(pathSeperator);
if (targetPathUrl === pathUrl) {
return this;
}
var childFolder = this.folderRef.current;
if (!children || !children.length || !childFolder) {
return null;
}
return childFolder.findFile(targetPathUrl);
};
FileManager.defaultProps = {};
return FileManager;
}(PureComponent);
function DefaultFoldIcon(props) {
return createElement("div", {
className: props.className + " " + prefix("default-fold-icon")
});
}
var FolderElement = styled("div", prefixCSS(PREFIX, "\n{\n position: relative;\n --folder-selected-color: #5bf;\n --folder-border-color: #444;\n --folder-guideline-color: #4af;\n --folder-background-color: #2a2a2a;\n --folder-icon-color: #fff;\n --folder-font-color: #fff;\n background: var(--folder-background-color);\n}\n:host.prevent-select {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n:host :host {\n --folder-selected-color: inherit;\n --folder-border-color: inherit;\n --folder-guideline-color: inherit;\n --folder-background-color: inherit;\n --folder-icon-color: inherit;\n --folder-font-color: inherit;\n}\n.default-fold-icon {\n position: absolute;\n display: inline-block;\n vertical-align: middle;\n width: 15px;\n height: 20px;\n right: 100%;\n top: 50%;\n transform: translateY(-50%);\n}\n.default-fold-icon:before {\n content: \"\";\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n border-top: 4px solid var(--folder-icon-color);\n border-left: 3px solid transparent;\n border-right: 3px solid transparent;\n}\n.default-fold-icon.fold:before {\n border-right: 0;\n border-left: 4px solid var(--folder-icon-color);\n border-top: 3px solid transparent;\n border-bottom: 3px solid transparent;\n}\n.file {\n position: relative;\n box-sizing: border-box;\n border-bottom: 1px solid var(--folder-border-color);\n width: 100%;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n color: var(--folder-font-color);\n}\n.file .file-name {\n position: relative;\n display: inline-block;\n flex: 1;\n}\n.shadows {\n position: absolute;\n pointer-events: none;\n transition: translateY(-50%);\n opacity: 0.5;\n top: 0;\n left: 0;\n width: 100%;\n z-index: 10;\n display: none;\n}\n.file.selected {\n background: var(--folder-selected-color);\n}\n.guideline {\n position: absolute;\n width: 100%;\n height: 4px;\n background: var(--folder-guideline-color);\n transform: translateY(-50%);\n display: none;\n}\n"));
function getCurrentFile(target) {
while (target) {
if (target.hasAttribute("data-file-path")) {
break;
}
target = target.parentElement;
}
return target;
}
var FolderManager = /*#__PURE__*/function (_super) {
__extends(FolderManager, _super);
function FolderManager() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.folderRef = createRef();
_this.shadowRef = createRef();
_this.state = {
shadows: []
};
_this.fileManagers = [];
_this.onDragStart = function (e) {
var clickedFile = getCurrentFile(e.inputEvent.target);
var datas = e.datas;
if (hasClass(e.inputEvent.target, prefix("fold-icon"))) {
e.inputEvent.stopPropagation();
e.stop();
_this.fold(clickedFile);
return false;
}
var fileInfos = _this.flatChildren();
datas.fileMap = _this.flatMap(fileInfos);
datas.fileInfos = fileInfos;
var folderElement = _this.folderRef.current;
if (!_this.props.isMove) {
if (clickedFile) {
_this.onClickFile({
currentTarget: clickedFile,
datas: datas
});
}
e.stop();
return false;
}
var dragCondtion = _this.props.dragCondtion || function () {
return true;
};
if (!dragCondtion(e)) {
e.stop();
return false;
}
var rect = folderElement.getBoundingClientRect();
var offsetX = e.clientX - rect.left;
// const offsetY = e.clientY - rect.top;
datas.offsetX = offsetX;
datas.folderRect = rect;
datas.folderLine = rect.left + rect.width - 10;
e.inputEvent.preventDefault();
e.inputEvent.stopPropagation();
var selected = _this.props.selected;
if (clickedFile && selected.indexOf(clickedFile.getAttribute("data-file-path")) === -1) {
datas.clickedFile = clickedFile;
_this.onClickFile({
currentTarget: clickedFile,
datas: datas
});
return;
}
};
_this.onDrag = function (e) {
var _a, _b, _c;
var clientX = e.clientX,
clientY = e.clientY,
datas = e.datas;
datas.isTop = false;
datas.depth = 0;
datas.targetInfo = null;
datas.prevInfo = null;
datas.nextInfo = null;
var _d = _this.props,
selected = _d.selected,
checkMove = _d.checkMove,
gap = _d.gap,
pathSeperator = _d.pathSeperator;
_this.clearGuideline();
if (!selected || !selected.length) {
return;
}
var fileInfos = datas.fileInfos;
var fileMap = datas.fileMap;
var folderRect = datas.folderRect;
var selectedInfos = selected.map(function (id) {
return fileMap[id];
});
// set shadows
if (!_this.state.shadows.length) {
_this.setState({
shadows: selectedInfos
}, function () {
// datas.offsetY = 0;
_this.updateShadowPosition(folderRect, e);
});
return;
} else {
_this.updateShadowPosition(folderRect, e);
}
var targetElement = getCurrentFile(document.elementFromPoint(datas.folderLine, e.clientY));
if (!targetElement) {
return;
}
var targetPathUrl = targetElement.getAttribute("data-file-path");
var targetRect = targetElement.getBoundingClientRect();
var isTop = targetRect.top + targetRect.height / 2 > clientY;
var targetIndex = findIndex(fileInfos, function (info) {
return info.pathUrl === targetPathUrl;
});
var targetInfo = fileInfos[targetIndex];
var targetDepth = targetInfo.depth;
var distX = clientX - folderRect.left - (targetDepth + 1) * gap;
var depthRange = [0, 0];
var moveInfos = [];
var prevInfo = fileInfos[isTop ? targetIndex - 1 : targetIndex];
var nextInfo = fileInfos[isTop ? targetIndex : targetIndex + 1];
var prevPath = (_a = prevInfo === null || prevInfo === void 0 ? void 0 : prevInfo.path) !== null && _a !== void 0 ? _a : [];
var prevDepth = (_b = prevInfo === null || prevInfo === void 0 ? void 0 : prevInfo.depth) !== null && _b !== void 0 ? _b : 0;
var nextDepth = (_c = nextInfo === null || nextInfo === void 0 ? void 0 : nextInfo.depth) !== null && _c !== void 0 ? _c : 0;
if (!nextInfo && !isTop) {
// last
depthRange = [0, targetDepth + 1];
var _loop_1 = function (depth) {
var movePath = prevPath.slice(0, depth);
var movePathUrl = movePath.join(pathSeperator);
var children = fileInfos.filter(function (info) {
return info.parentPathUrl === movePathUrl;
});
moveInfos.push({
depth: depth,
parentInfo: fileMap[movePathUrl],
prevInfo: children[children.length - 1]
});
};
for (var depth = depthRange[0]; depth <= depthRange[1]; ++depth) {
_loop_1(depth);
}
} else if (!prevInfo && isTop) {
// first
depthRange = [0, 0];
moveInfos.push({
depth: 0
});
} else {
if (prevDepth === nextDepth) {
// same children or append group
depthRange = [prevDepth, prevDepth + 1];
// same children
moveInfos.push({
depth: nextDepth,
prevInfo: prevInfo,
parentInfo: prevInfo.parentFileInfo
});
// append group
moveInfos.push({
depth: nextDepth + 1,
parentInfo: prevInfo
});
} else if (prevDepth < nextDepth) {
depthRange = [nextDepth, nextDepth];
// parent(prev) => target
moveInfos.push({
depth: nextDepth,
parentInfo: prevInfo
});
} else if (prevDepth > nextDepth) {
var prevPath_1 = prevInfo.path;
// last child(prev) => next other group or target
depthRange = [nextDepth, prevDepth + 1];
var _loop_2 = function (depth) {
var movePath = prevPath_1.slice(0, depth + 1);
var movePathUrl = movePath.join(pathSeperator);
var parentPathUrl = prevPath_1.slice(0, depth).join(pathSeperator);
var prevFileInfo = fileInfos.find(function (info) {
return info.pathUrl === movePathUrl;
});
moveInfos.push({
depth: depth,
parentInfo: fileMap[parentPathUrl],
prevInfo: depth > prevDepth ? null : prevFileInfo
});
};
for (var depth = depthRange[0]; depth <= depthRange[1]; ++depth) {
_loop_2(depth);
}
}
}
var selectedPaths = selected.map(function (selectedUrl) {
return selectedUrl.split(pathSeperator);
});
moveInfos = moveInfos.filter(function (_a) {
var _b;
var prevInfo = _a.prevInfo,
parentInfo = _a.parentInfo;
var info = prevInfo || parentInfo;
var movePath = (_b = info === null || info === void 0 ? void 0 : info.path) !== null && _b !== void 0 ? _b : [];
return !selectedPaths.some(function (path, i) {
// 자기 자신 옆에 있는 경우
if ((prevInfo === null || prevInfo === void 0 ? void 0 : prevInfo.pathUrl) === selected[i]) {
return false;
}
// 상위 그룹 또는 자기 자신에 포함되려고 하는 경우
return path.every(function (id, i) {
return id === movePath[i];
});
});
});
if (!moveInfos.length) {
return;
}
var guidelineDepth = between(targetDepth + Math.round((distX > 0 ? distX * 0.2 : distX - gap / 10) / gap), depthRange[0], depthRange[1]);
var passedInfos = moveInfos.filter(function (info) {
return checkMove(info);
}).sort(function (a, b) {
return Math.abs(a.depth - guidelineDepth) - Math.abs(b.depth - guidelineDepth);
});
var moveInfo = passedInfos[0];
if (!moveInfo) {
return;
}
var passedDepth = moveInfo.depth;
var guidelineX = passedDepth ? (passedDepth + 1) * gap : 0;
var guidelineY = targetRect.top - folderRect.top + (isTop ? 0 : targetRect.height);
_this.guidelineElement.style.cssText = "display: block;" + ("top: " + guidelineY + "px;") + ("left: " + guidelineX + "px;") + ("width: calc(100% - " + guidelineX + "px);");
datas.moveInfo = moveInfo;
datas.isTop = isTop;
datas.guidelineDepth = passedDepth;
datas.targetInfo = targetInfo;
datas.prevInfo = prevInfo;
datas.nextInfo = nextInfo;
};
_this.onDragEnd = function (e) {
var _a, _b;
_this.clearGuideline();
var datas = e.datas;
if (!e.isDrag && !datas.clickedFile) {
var currentTarget = getCurrentFile(e.inputEvent.target);
if (currentTarget) {
_this.onClickFile({
currentTarget: currentTarget,
datas: datas
});
}
return;
}
var _c = _this.props,
onMove = _c.onMove,
selected = _c.selected,
pathSeperator = _c.pathSeperator,
folded = _c.folded;
var fileInfos = datas.fileInfos;
var targetInfo = datas.targetInfo;
var moveInfo = datas.moveInfo;
var fileMap = datas.fileMap;
var selectedInfos = selected.map(function (id) {
return fileMap[id];
});
if (targetInfo) {
var prevInfo_1 = moveInfo.prevInfo;
var childrenInfos = _this.getChildrenFileInfos(moveInfo.parentInfo);
if (prevInfo_1) {
var prevPathUrl_1 = prevInfo_1.pathUrl;
var index = findIndex(childrenInfos, function (info) {
return info.pathUrl === prevPathUrl_1;
});
for (; index >= -1; --index) {
if (index === -1) {
prevInfo_1 = null;
} else {
prevInfo_1 = childrenInfos[index];
if (selected.every(function (pathUrl) {
return pathUrl !== prevInfo_1.pathUrl;
})) {
break;
}
}
}
}
var flattenPrevInfo_1 = datas.prevInfo;
if (flattenPrevInfo_1) {
var prevPathUrl_2 = flattenPrevInfo_1.pathUrl;
var index = findIndex(fileInfos, function (info) {
return info.pathUrl === prevPathUrl_2;
});
for (; index >= -1; --index) {
if (index === -1) {
flattenPrevInfo_1 = null;
} else {
flattenPrevInfo_1 = fileInfos[index];
if (selectedInfos.every(function (_a) {
var path = _a.path;
return !isArrayContains(path, flattenPrevInfo_1.path);
})) {
break;
}
}
}
}
childrenInfos = childrenInfos.filter(function (info) {
// 같은 아이템은 패스
return !find(selectedInfos, function (selectedInfo) {
return selectedInfo.pathUrl === info.pathUrl;
});
});
childrenInfos.splice.apply(childrenInfos, __spreadArrays([prevInfo_1 ? childrenInfos.findIndex(function (info) {
return info.pathUrl === prevInfo_1.pathUrl;
}) + 1 : 0, 0], selectedInfos));
var parentPath_1 = (_b = (_a = moveInfo.parentInfo) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : [];
var nextFolded = folded.map(function (pathUrl) {
var fileInfo = fileMap[pathUrl];
if (selected.indexOf(pathUrl) === -1) {
return pathUrl;
}
return __spreadArrays(parentPath_1, [fileInfo.id]).join(pathSeperator);
}).filter(Boolean);
onMove(__assign(__assign({}, moveInfo), {
prevInfo: prevInfo_1,
children: childrenInfos.map(function (info) {
return info.value;
}),
childrenInfos: childrenInfos,
flattenInfos: fileInfos,
flattenPrevInfo: flattenPrevInfo_1,
selected: selected,
selectedInfos: selectedInfos,
nextFolded: nextFolded
}));
}
_this.setState({
shadows: []
}, function () {
_this.shadowRef.current.style.cssText = "display: none";
});
};
_this.onClickFile = function (_a) {
var currentTarget = _a.currentTarget,
datas = _a.datas;
var pathUrl = currentTarget.getAttribute("data-file-path");
var _b = _this.props,
multiselect = _b.multiselect,
onSelect = _b.onSelect,
selected = _b.selected,
pathSeperator = _b.pathSeperator;
var isSelected = false;
var nextSelected;
if (multiselect) {
nextSelected = (selected || []).slice();
var index = nextSelected.indexOf(pathUrl);
if (KeyController.global.shiftKey) {
if (index > -1) {
nextSelected.splice(index, 1);
} else {
isSelected = true;
nextSelected.push(pathUrl);
}
} else {
isSelected = true;
nextSelected = [pathUrl];
}
} else {
isSelected = true;
nextSelected = [pathUrl];
}
nextSelected = _this.flatChildren().map(function (info) {
return info.pathUrl;
}).filter(function (flatPath) {
return nextSelected.indexOf(flatPath) > -1;
});
var selectedPaths = nextSelected.map(function (pathUrl) {
return pathUrl.split(pathSeperator);
});
selectedPaths = selectedPaths.filter(function (path, i) {
return selectedPaths.every(function (path2, j) {
return i === j || !isArrayContains(path2, path);
});
});
nextSelected = selectedPaths.map(function (path) {
return path.join(pathSeperator);
});
var fileMap = datas.fileMap;
var selectedInfos = nextSelected.map(function (id) {
return fileMap[id];
});
if (!isEqualArray(selected, nextSelected)) {
onSelect({
pathUrl: pathUrl,
path: pathUrl.split(pathSeperator),
isSelected: isSelected,
selected: nextSelected,
selectedInfos: selectedInfos
});
}
};
_this.fold = function (target) {
var _a = _this.props,
propsFolded = _a.folded,
pathSeperator = _a.pathSeperator;
var pathUrl = "";
if (target instanceof Element) {
pathUrl = target.getAttribute("data-file-path");
} else if (isArray(target)) {
pathUrl = target.join(pathSeperator);
} else {
pathUrl = target;
}
var folded = __spreadArrays(propsFolded || []);
var onFold = _this.props.onFold;
var index = folded.indexOf(pathUrl);
var isFolded = index > -1;
if (isFolded) {
folded.splice(index, 1);
} else {
folded.push(pathUrl);
}
onFold && onFold({
path: pathUrl.split(pathSeperator),
pathUrl: pathUrl,
isFolded: !isFolded,
folded: folded
});
};
return _this;
}
var __proto = FolderManager.prototype;
__proto.render = function () {
var rendered = this._renderFiles();
if (!this.props.scope.length) {
return createElement(RootFolderContext.Provider, {
value: this
}, rendered);
} else {
return rendered;
}
};
__proto.componentDidMount = function () {
KeyController.setGlobal();
if (!this.props.isChild) {
var folderElement = this.folderRef.current;
this.moveGesto = new Gesto(folderElement, {
container: window,
checkInput: true,
preventDefault: false
}).on("dragStart", this.onDragStart).on("drag", this.onDrag).on("dragEnd", this.onDragEnd);
}
};
__proto.componentWillUnmount = function () {
var _a;
(_a = this.moveGesto) === null || _a === void 0 ? void 0 : _a.unset();
};
__proto.isSelected = function (path) {
var props = this.props;
var selected = props.selected;
var pathUrl = isArray(path) ? path.join(props.pathSeperator) : path;
return selected && selected.indexOf(pathUrl) > -1;
};
__proto.isFolded = function (path) {
var props = this.props;
var pathUrl = isArray(path) ? path.join(props.pathSeperator) : path;
var folded = props.folded;
return folded && folded.indexOf(pathUrl) > -1;
};
__proto.findFileInfo = function (targetPath) {
var targetPathUrl = isString(targetPath) ? targetPath : targetPath.join(this.props.pathSeperator);
var children = this.flatChildren();
return find(children, function (child) {
return child.pathUrl === targetPathUrl;
}) || null;
};
__proto.findFile = function (targetPath) {
var fileManagers = this.fileManagers;
var length = fileManagers.length;
var targetPathUrl = isString(targetPath) ? targetPath : targetPath.join(this.props.pathSeperator);
for (var i = 0; i < length; ++i) {
var file = fileManagers[i].findFile(targetPathUrl);
if (file) {
return file;
}
}
return null;
};
__proto.renderShadows = function () {
var _a = this.props,
FileComponent = _a.FileComponent,
nameProperty = _a.nameProperty,
scope = _a.scope,
isPadding = _a.isPadding,
gap = _a.gap,
passWrapperProps = _a.passWrapperProps,
gapOffset = _a.gapOffset;
if (scope.length) {
return;
}
return createElement("div", {
className: prefix("shadows"),
ref: this.shadowRef
}, this.state.shadows.map(function (info) {
var _a;
var fileScope = info.scope,
infoValue = info.value,
pathUrl = info.pathUrl,
path = info.path,
scope = info.scope,
index = info.index;
var name = getName(nameProperty, infoValue, index, scope);
var gapWidth = gap * (scope.length + 1) + gapOffset;
var className = prefix("file", "selected", "shadow");
var style = (_a = {}, _a[isPadding ? "paddingLeft" : "marginLeft"] = gapWidth + "px", _a.width = isPadding ? "100%" : "calc(100% - " + gapWidth + "px)", _a);
var _b = passWrapperProps({
className: className,
style: style,
scope: scope,
name: name,
value: infoValue,
path: path,
gapWidth: gapWidth,
isSelected: true,
isShadow: true
}) || {},
passedStyle = _b.style,
otherProps = __rest(_b, ["style"]);
if (passedStyle) {
style = __assign(__assign({}, style), passedStyle);
}
return createElement("div", __assign({
key: pathUrl,
className: className,
style: passedStyle
}, otherProps), createElement(FileComponent, {
scope: fileScope,
name: name,
value: infoValue,
path: path
}));
}));
};
__proto.updateShadowPosition = function (rect, e) {
var el = this.shadowRef.current;
if (!el || !this.state.shadows.length) {
return;
}
var datas = e.datas;
el.style.cssText = "display: block;" + ("transform: translate(" + (e.clientX - rect.left - datas.offsetX) + "px, " + (e.clientY - rect.top) + "px) translateY(-50%)");
};
__proto.flatMap = function (children) {
if (children === void 0) {
children = this.flatChildren();
}
var objMap = {};
children.forEach(function (info) {
objMap[info.pathUrl] = info;
});
return objMap;
};
__proto.getChildrenFileInfos = function (parentInfo) {
var _a = this.props,
childrenProperty = _a.childrenProperty,
idProperty = _a.idProperty,
pathProperty = _a.pathProperty,
infos = _a.infos,
pathSeperator = _a.pathSeperator;
var scope = [];
var children = infos;
var parentPath = [];
var parentPathUrl = "";
if (parentInfo) {
scope = __spreadArrays(parentInfo.scope, [parentInfo.id]);
children = getChildren(childrenProperty, parentInfo.value, scope);
parentPathUrl = parentInfo.pathUrl;
parentPath = parentInfo.path;
}
if (children) {
return children.map(function (value, index) {
var id = getId(idProperty, value, index, scope);
var path = getPath(pathProperty, id, scope, value, index);
var depth = scope.length;
return {
id: id,
path: path,
parentPath: parentPath,
parentValue: parentInfo === null || parentInfo === void 0 ? void 0 : parentInfo.value,
parentFileInfo: parentInfo || null,
pathUrl: path.join(pathSeperator),
parentPathUrl: parentPathUrl,
depth: depth,
scope: scope,
value: value,
index: index
};
});
}
return [];
};
__proto.flatChildren = function () {
var _a = this.props,
pathProperty = _a.pathProperty,
idProperty = _a.idProperty,
childrenProperty = _a.childrenProperty,
infos = _a.infos,
folded = _a.folded,
pathSeperator = _a.pathSeperator;
var children = [];
function push(parentFileInfo, parentPathUrl, value, index, scope) {
var id = getId(idProperty, value, index, scope);
var path = getPath(pathProperty, id, scope, value, index);
var pathUrl = path.join(pathSeperator);
var depth = scope.length;
var fileInfo = {
id: id,
path: path,
pathUrl: pathUrl,
parentValue: parentFileInfo === null || parentFileInfo === void 0 ? void 0 : parentFileInfo.value,
parentFileInfo: parentFileInfo,
parentPath: parentPathUrl.split(pathSeperator),
parentPathUrl: parentPathUrl,
depth: depth,
scope: scope,
value: value,
index: index
};
children.push(fileInfo);
var nextScope = __spreadArrays(scope, [id]);
var nextChildren = getChildren(childrenProperty, value, scope);
if (nextChildren && folded.indexOf(pathUrl) === -1) {
nextChildren.forEach(function (nextInfo, nextIndex) {
push(fileInfo, pathUrl, nextInfo, nextIndex, nextScope);
});
}
}
infos.forEach(function (info, index) {
push(null, "", info, index, []);
});
return children;
};
__proto.clearGuideline = function () {
this.guidelineElement.style.display = "none";
};
__proto._renderFiles = function () {
var _this = this;
var _a = this.props,
scope = _a.scope,
gap = _a.gap,
gapOffset = _a.gapOffset,
isPadding = _a.isPadding,
infos = _a.infos,
selected = _a.selected,
folded = _a.folded,
multiselect = _a.multiselect,
FileComponent = _a.FileComponent,
FoldIcon = _a.FoldIcon,
nameProperty = _a.nameProperty,
idProperty = _a.idProperty,
pathProperty = _a.pathProperty,
childrenProperty = _a.childrenProperty,
showFoldIcon = _a.showFoldIcon,
iconColor = _a.iconColor,
fontColor = _a.fontColor,
backgroundColor = _a.backgroundColor,
borderColor = _a.borderColor,
guidelineColor = _a.guidelineColor,
selectedColor = _a.selectedColor,
originalInfos = _a.originalInfos,
display = _a.display,
pathSeperator = _a.pathSeperator,
preventSelect = _a.preventSelect,
passWrapperProps = _a.passWrapperProps,
renderOnFolded = _a.renderOnFolded;
this.fileManagers = this.fileManagers.slice(0, infos.length);
return createElement(FolderElement, {
className: prefix("folder", preventSelect ? "prevent-select" : ""),
ref: this.folderRef,
style: {
"--folder-icon-color": iconColor,
"--folder-background-color": backgroundColor,
"--folder-border-color": borderColor,
"--folder-guideline-color": guidelineColor,
"--folder-selected-color": selectedColor,
"--folder-font-color": fontColor,
display: display || "block"
}
}, (renderOnFolded || display !== "none") && infos.map(function (info, index) {
return createElement(FileManager, {
ref: refs(_this, "fileManagers", index),
key: index,
index: index,
info: info,
scope: scope,
selected: selected,
folded: folded,
FoldIcon: FoldIcon,
FileComponent: FileComponent,
isPadding: isPadding,
gap: gap,
renderOnFolded: renderOnFolded,
preventSelect: preventSelect,
gapOffset: gapOffset,
multiselect: multiselect,
showFoldIcon: showFoldIcon,
nameProperty: nameProperty,
idProperty: idProperty,
childrenProperty: childrenProperty,
pathProperty: pathProperty,
originalInfos: originalInfos || infos,
pathSeperator: pathSeperator,
passWrapperProps: passWrapperProps
});
}), createElement("div", {
className: prefix("guideline"),
ref: ref(this, "guidelineElement")
}), this.renderShadows());
};
FolderManager.defaultProps = {
preventSelect: false,
scope: [],
selected: [],
folded: [],
onMove: function () {},
checkMove: function () {
return true;
},
onSelect: function () {},
gap: 15,
gapOffset: 0,
urlProperty: function (id) {
return id;
},
pathProperty: function (id, scope) {
return __spreadArrays(scope, [id]);
},
idProperty: function (_, index) {
return index;
},
nameProperty: function (_, index) {
return index;
},
childrenProperty: function () {
return [];
},
passWrapperProps: function () {
return {};
},
pathSeperator: "///",
renderOnFolded: true,
FoldIcon: DefaultFoldIcon
};
return FolderManager;
}(PureComponent);
var File = /*#__PURE__*/function (_super) {
__extends(File, _super);
function File() {
return _super !== null && _super.apply(this, arguments) || this;
}
return File;
}(PureComponent);
export default FolderManager;
export { File, PREFIX, RootFolderContext };
//# sourceMappingURL=folder.esm.js.map