@nosferatu500/react-sortable-tree
Advanced tools
Comparing version 4.2.0 to 4.2.1
@@ -1622,7 +1622,8 @@ import { jsx, jsxs } from 'react/jsx-runtime'; | ||
const newState = {}; | ||
const newInstanceProps = { ...instanceProps }; | ||
const isTreeDataEqual = isEqual(instanceProps.treeData, nextProps.treeData); | ||
instanceProps.treeData = nextProps.treeData; | ||
newInstanceProps.treeData = nextProps.treeData; | ||
if (!isTreeDataEqual) { | ||
if (instanceProps.ignoreOneTreeUpdate) { | ||
instanceProps.ignoreOneTreeUpdate = false; | ||
newInstanceProps.ignoreOneTreeUpdate = false; | ||
} else { | ||
@@ -1652,5 +1653,5 @@ newState.searchFocusTreeIndex = void 0; | ||
} | ||
instanceProps.searchQuery = nextProps.searchQuery; | ||
instanceProps.searchFocusOffset = nextProps.searchFocusOffset; | ||
newState.instanceProps = { ...instanceProps, ...newState.instanceProps }; | ||
newInstanceProps.searchQuery = nextProps.searchQuery; | ||
newInstanceProps.searchFocusOffset = nextProps.searchFocusOffset; | ||
newState.instanceProps = { ...newInstanceProps, ...newState.instanceProps }; | ||
return newState; | ||
@@ -1657,0 +1658,0 @@ } |
317
index.js
@@ -22,3 +22,2 @@ 'use strict'; | ||
}) => treeIndex; | ||
const getReactElementText = parent => { | ||
@@ -28,14 +27,10 @@ if (typeof parent === 'string') { | ||
} | ||
if (parent === undefined || typeof parent !== 'object' || !parent.props || !parent.props.children || typeof parent.props.children !== 'string' && typeof parent.props.children !== 'object') { | ||
return ''; | ||
} | ||
if (typeof parent.props.children === 'string') { | ||
return parent.props.children; | ||
} | ||
return parent.props.children.map(child => getReactElementText(child)).join(''); | ||
}; | ||
const stringSearch = (key, searchQuery, node, path, treeIndex) => { | ||
@@ -49,10 +44,7 @@ if (typeof node[key] === 'function') { | ||
} | ||
if (typeof node[key] === 'object') { | ||
return getReactElementText(node[key]).includes(searchQuery); | ||
} | ||
return node[key] && String(node[key]).includes(searchQuery); | ||
}; | ||
const defaultSearchMethod = ({ | ||
@@ -81,3 +73,2 @@ node, | ||
})] : []; | ||
if (currentIndex === targetIndex) { | ||
@@ -90,3 +81,2 @@ return { | ||
} | ||
if (!node?.children || ignoreCollapsed && node?.expanded !== true) { | ||
@@ -97,6 +87,4 @@ return { | ||
} | ||
let childIndex = currentIndex + 1; | ||
const childCount = node.children.length; | ||
for (let i = 0; i < childCount; i += 1) { | ||
@@ -112,10 +100,7 @@ const result = getNodeDataAtTreeIndexOrNextIndex({ | ||
}); | ||
if (result.node) { | ||
return result; | ||
} | ||
childIndex = result.nextIndex; | ||
} | ||
return { | ||
@@ -125,3 +110,2 @@ nextIndex: childIndex | ||
}; | ||
const getDescendantCount = ({ | ||
@@ -139,3 +123,2 @@ node, | ||
}; | ||
const walkDescendants = ({ | ||
@@ -163,6 +146,4 @@ callback, | ||
}; | ||
if (!isPseudoRoot) { | ||
const callbackResult = callback(selfInfo); | ||
if (callbackResult === false) { | ||
@@ -172,10 +153,7 @@ return false; | ||
} | ||
if (!node.children || node.expanded !== true && ignoreCollapsed && !isPseudoRoot) { | ||
return currentIndex; | ||
} | ||
let childIndex = currentIndex; | ||
const childCount = node.children.length; | ||
if (typeof node.children !== 'function') { | ||
@@ -193,3 +171,2 @@ for (let i = 0; i < childCount; i += 1) { | ||
}); | ||
if (childIndex === false) { | ||
@@ -200,6 +177,4 @@ return false; | ||
} | ||
return childIndex; | ||
}; | ||
const mapDescendants = ({ | ||
@@ -216,3 +191,4 @@ callback, | ||
}) => { | ||
const nextNode = { ...node | ||
const nextNode = { | ||
...node | ||
}; | ||
@@ -230,3 +206,2 @@ const selfPath = isPseudoRoot ? [] : [...path, getNodeKey({ | ||
}; | ||
if (!nextNode.children || nextNode.expanded !== true && ignoreCollapsed && !isPseudoRoot) { | ||
@@ -238,6 +213,4 @@ return { | ||
} | ||
let childIndex = currentIndex; | ||
const childCount = nextNode.children.length; | ||
if (typeof nextNode.children !== 'function') { | ||
@@ -259,3 +232,2 @@ nextNode.children = nextNode.children.map((child, i) => { | ||
} | ||
return { | ||
@@ -266,3 +238,2 @@ node: callback(selfInfo), | ||
}; | ||
const getVisibleNodeCount = ({ | ||
@@ -275,6 +246,4 @@ treeData | ||
} | ||
return 1 + node.children.reduce((total, currentNode) => total + traverse(currentNode), 0); | ||
}; | ||
return treeData.reduce((total, currentNode) => total + traverse(currentNode), 0); | ||
@@ -290,3 +259,2 @@ }; | ||
} | ||
const result = getNodeDataAtTreeIndexOrNextIndex({ | ||
@@ -304,7 +272,5 @@ targetIndex, | ||
}); | ||
if (result.node) { | ||
return result; | ||
} | ||
return undefined; | ||
@@ -321,3 +287,2 @@ }; | ||
} | ||
walkDescendants({ | ||
@@ -345,3 +310,2 @@ callback, | ||
} | ||
return mapDescendants({ | ||
@@ -368,3 +332,4 @@ callback, | ||
node | ||
}) => ({ ...node, | ||
}) => ({ | ||
...node, | ||
expanded | ||
@@ -386,3 +351,2 @@ }), | ||
const RESULT_MISS = 'RESULT_MISS'; | ||
const traverse = ({ | ||
@@ -400,3 +364,2 @@ isPseudoRoot = false, | ||
} | ||
if (pathIndex >= path.length - 1) { | ||
@@ -408,9 +371,6 @@ return typeof newNode === 'function' ? newNode({ | ||
} | ||
if (!node.children) { | ||
throw new Error('Path referenced children of node with no children.'); | ||
} | ||
let nextTreeIndex = currentTreeIndex + 1; | ||
for (let i = 0; i < node.children.length; i += 1) { | ||
@@ -422,15 +382,14 @@ const result = traverse({ | ||
}); | ||
if (result !== RESULT_MISS) { | ||
if (result) { | ||
return { ...node, | ||
return { | ||
...node, | ||
children: [...node.children.slice(0, i), result, ...node.children.slice(i + 1)] | ||
}; | ||
} | ||
return { ...node, | ||
return { | ||
...node, | ||
children: [...node.children.slice(0, i), ...node.children.slice(i + 1)] | ||
}; | ||
} | ||
nextTreeIndex += 1 + getDescendantCount({ | ||
@@ -441,6 +400,4 @@ node: node.children[i], | ||
} | ||
return RESULT_MISS; | ||
}; | ||
const result = traverse({ | ||
@@ -454,7 +411,5 @@ node: { | ||
}); | ||
if (result === RESULT_MISS) { | ||
throw new Error('No node found at the given path.'); | ||
} | ||
return result.children; | ||
@@ -476,2 +431,3 @@ }; | ||
}; | ||
const removeNode = ({ | ||
@@ -512,3 +468,2 @@ treeData, | ||
let foundNodeInfo; | ||
try { | ||
@@ -531,4 +486,4 @@ changeNodeAtPath({ | ||
}); | ||
} catch {} | ||
} catch { | ||
} | ||
return foundNodeInfo; | ||
@@ -554,3 +509,2 @@ }; | ||
} | ||
let insertedTreeIndex; | ||
@@ -568,28 +522,23 @@ let hasBeenAdded = false; | ||
const key = path ? path[path.length - 1] : undefined; | ||
if (hasBeenAdded || key !== parentKey) { | ||
return node; | ||
} | ||
hasBeenAdded = true; | ||
const parentNode = { ...node | ||
const parentNode = { | ||
...node | ||
}; | ||
if (expandParent) { | ||
parentNode.expanded = true; | ||
} | ||
if (!parentNode.children) { | ||
insertedTreeIndex = treeIndex + 1; | ||
return { ...parentNode, | ||
return { | ||
...parentNode, | ||
children: [newNode] | ||
}; | ||
} | ||
if (typeof parentNode.children === 'function') { | ||
throw new TypeError('Cannot add to children defined by a function'); | ||
} | ||
let nextTreeIndex = treeIndex + 1; | ||
for (let i = 0; i < parentNode.children.length; i += 1) { | ||
@@ -601,6 +550,6 @@ nextTreeIndex += 1 + getDescendantCount({ | ||
} | ||
insertedTreeIndex = nextTreeIndex; | ||
const children = addAsFirstChild ? [newNode, ...parentNode.children] : [...parentNode.children, newNode]; | ||
return { ...parentNode, | ||
return { | ||
...parentNode, | ||
children | ||
@@ -610,7 +559,5 @@ }; | ||
}); | ||
if (!hasBeenAdded) { | ||
throw new Error('No node found with the given key.'); | ||
} | ||
return { | ||
@@ -621,3 +568,2 @@ treeData: changedTreeData, | ||
}; | ||
const addNodeAtDepthAndIndex = ({ | ||
@@ -641,3 +587,2 @@ targetDepth, | ||
})]; | ||
if (currentIndex >= minimumTreeIndex - 1 || isLastChild && !(node.children && node.children.length > 0)) { | ||
@@ -650,3 +595,4 @@ if (typeof node.children === 'function') { | ||
} : {}; | ||
const nextNode = { ...node, | ||
const nextNode = { | ||
...node, | ||
...extraNodeProps, | ||
@@ -664,3 +610,2 @@ children: node.children ? [newNode, ...node.children] : [newNode] | ||
} | ||
if (currentDepth >= targetDepth - 1) { | ||
@@ -673,7 +618,5 @@ if (!node.children || typeof node.children === 'function' || node.expanded !== true && ignoreCollapsed && !isPseudoRoot) { | ||
} | ||
let childIndex = currentIndex + 1; | ||
let insertedTreeIndex; | ||
let insertIndex; | ||
for (let i = 0; i < node.children.length; i += 1) { | ||
@@ -685,3 +628,2 @@ if (childIndex >= minimumTreeIndex) { | ||
} | ||
childIndex += 1 + getDescendantCount({ | ||
@@ -692,3 +634,2 @@ node: node.children[i], | ||
} | ||
if (insertIndex === null || insertIndex === undefined) { | ||
@@ -701,8 +642,7 @@ if (childIndex < minimumTreeIndex && !isLastChild) { | ||
} | ||
insertedTreeIndex = childIndex; | ||
insertIndex = node.children.length; | ||
} | ||
const nextNode = { ...node, | ||
const nextNode = { | ||
...node, | ||
children: [...node.children.slice(0, insertIndex), newNode, ...node.children.slice(insertIndex)] | ||
@@ -718,3 +658,2 @@ }; | ||
} | ||
if (!node.children || typeof node.children === 'function' || node.expanded !== true && ignoreCollapsed && !isPseudoRoot) { | ||
@@ -726,3 +665,2 @@ return { | ||
} | ||
let insertedTreeIndex; | ||
@@ -733,3 +671,2 @@ let pathFragment; | ||
let newChildren = node.children; | ||
if (typeof newChildren !== 'function') { | ||
@@ -740,3 +677,2 @@ newChildren = newChildren.map((child, i) => { | ||
} | ||
const mapResult = addNodeAtDepthAndIndex({ | ||
@@ -763,3 +699,2 @@ targetDepth, | ||
} | ||
childIndex = mapResult.nextIndex; | ||
@@ -769,4 +704,4 @@ return mapResult.node; | ||
} | ||
const nextNode = { ...node, | ||
const nextNode = { | ||
...node, | ||
children: newChildren | ||
@@ -778,3 +713,2 @@ }; | ||
}; | ||
if (insertedTreeIndex !== null && insertedTreeIndex !== undefined) { | ||
@@ -785,6 +719,4 @@ result.insertedTreeIndex = insertedTreeIndex; | ||
} | ||
return result; | ||
}; | ||
const insertNode = ({ | ||
@@ -810,3 +742,2 @@ treeData, | ||
} | ||
const insertResult = addNodeAtDepthAndIndex({ | ||
@@ -827,7 +758,5 @@ targetDepth, | ||
}); | ||
if (!('insertedTreeIndex' in insertResult)) { | ||
throw new Error('No suitable position found to insert.'); | ||
} | ||
const treeIndex = insertResult.insertedTreeIndex; | ||
@@ -852,3 +781,2 @@ return { | ||
} | ||
const flattened = []; | ||
@@ -874,8 +802,5 @@ walk({ | ||
} | ||
const childrenToParents = {}; | ||
for (const child of flatData) { | ||
const parentKey = getParentKey(child); | ||
if (parentKey in childrenToParents) { | ||
@@ -887,20 +812,17 @@ childrenToParents[parentKey].push(child); | ||
} | ||
if (!(rootKey in childrenToParents)) { | ||
return []; | ||
} | ||
const trav = parent => { | ||
const parentKey = getKey(parent); | ||
if (parentKey in childrenToParents) { | ||
return { ...parent, | ||
return { | ||
...parent, | ||
children: childrenToParents[parentKey].map(child => trav(child)) | ||
}; | ||
} | ||
return { ...parent | ||
return { | ||
...parent | ||
}; | ||
}; | ||
return childrenToParents[rootKey].map(child => trav(child)); | ||
@@ -915,7 +837,5 @@ }; | ||
} | ||
if (typeof node.children === 'function') { | ||
return depth + 1; | ||
} | ||
return node.children.reduce((deepest, child) => Math.max(deepest, getDepth(child, depth + 1)), depth); | ||
@@ -933,3 +853,2 @@ }; | ||
let matchCount = 0; | ||
const trav = ({ | ||
@@ -953,4 +872,4 @@ isPseudoRoot = false, | ||
const hasChildren = node.children && typeof node.children !== 'function' && node.children.length > 0; | ||
if (!isPseudoRoot && searchMethod({ ...extraInfo, | ||
if (!isPseudoRoot && searchMethod({ | ||
...extraInfo, | ||
node, | ||
@@ -962,11 +881,9 @@ searchQuery | ||
} | ||
matchCount += 1; | ||
isSelfMatch = true; | ||
} | ||
let childIndex = currentIndex; | ||
const newNode = { ...node | ||
const newNode = { | ||
...node | ||
}; | ||
if (hasChildren) { | ||
@@ -979,3 +896,2 @@ newNode.children = newNode.children.map(child => { | ||
}); | ||
if (mapResult.node.expanded) { | ||
@@ -986,10 +902,7 @@ childIndex = mapResult.treeIndex; | ||
} | ||
if (mapResult.matches.length > 0 || mapResult.hasFocusMatch) { | ||
matches = [...matches, ...mapResult.matches]; | ||
if (mapResult.hasFocusMatch) { | ||
hasFocusMatch = true; | ||
} | ||
if (expandAllMatchPaths && mapResult.matches.length > 0 || (expandAllMatchPaths || expandFocusMatchPaths) && mapResult.hasFocusMatch) { | ||
@@ -999,19 +912,17 @@ newNode.expanded = true; | ||
} | ||
return mapResult.node; | ||
}); | ||
} | ||
if (!isPseudoRoot && !newNode.expanded) { | ||
matches = matches.map(match => ({ ...match, | ||
matches = matches.map(match => ({ | ||
...match, | ||
treeIndex: undefined | ||
})); | ||
} | ||
if (isSelfMatch) { | ||
matches = [{ ...extraInfo, | ||
matches = [{ | ||
...extraInfo, | ||
node: newNode | ||
}, ...matches]; | ||
} | ||
return { | ||
@@ -1024,3 +935,2 @@ node: matches.length > 0 ? newNode : node, | ||
}; | ||
const result = trav({ | ||
@@ -1056,5 +966,5 @@ node: { | ||
}; | ||
const NodeRendererDefault = function (props) { | ||
props = { ...defaultProps$3, | ||
props = { | ||
...defaultProps$3, | ||
...props | ||
@@ -1092,3 +1002,2 @@ }; | ||
let handle; | ||
if (canDrag) { | ||
@@ -1111,3 +1020,2 @@ handle = typeof node.children === 'function' && node.expanded ? jsxRuntime.jsx("div", { | ||
} | ||
const isDraggedDescendant = draggedNode && isDescendant(draggedNode, node); | ||
@@ -1119,3 +1027,2 @@ const isLandingPadActive = !didDrop && isDragging; | ||
}; | ||
if (rowDirection === 'rtl') { | ||
@@ -1127,3 +1034,2 @@ buttonStyle = { | ||
} | ||
return jsxRuntime.jsxs("div", { | ||
@@ -1195,5 +1101,5 @@ style: { | ||
}; | ||
const PlaceholderRendererDefault = function (props) { | ||
props = { ...defaultProps$2, | ||
props = { | ||
...defaultProps$2, | ||
...props | ||
@@ -1218,6 +1124,6 @@ }; | ||
}; | ||
class TreeNodeComponent extends React.Component { | ||
render() { | ||
const props = { ...defaultProps$1, | ||
const props = { | ||
...defaultProps$1, | ||
...this.props | ||
@@ -1249,6 +1155,4 @@ }; | ||
const scaffold = []; | ||
for (const [i, lowerSiblingCount] of lowerSiblingCounts.entries()) { | ||
let lineClass = ''; | ||
if (lowerSiblingCount > 0) { | ||
@@ -1267,3 +1171,2 @@ if (listIndex === 0) { | ||
} | ||
scaffold.push(jsxRuntime.jsx("div", { | ||
@@ -1275,6 +1178,4 @@ style: { | ||
}, `pre_${1 + i}`)); | ||
if (treeIndex !== listIndex && i === swapDepth) { | ||
let highlightLineClass = ''; | ||
if (listIndex === swapFrom + swapLength - 1) { | ||
@@ -1287,3 +1188,2 @@ highlightLineClass = 'rst__highlightBottomLeftCorner'; | ||
} | ||
const style = rowDirection === 'rtl' ? { | ||
@@ -1302,3 +1202,2 @@ width: scaffoldBlockPxWidth, | ||
} | ||
const style = rowDirection === 'rtl' ? { | ||
@@ -1310,8 +1209,7 @@ right: scaffoldBlockPxWidth * scaffoldBlockCount | ||
let calculatedRowHeight = rowHeight; | ||
if (typeof rowHeight === 'function') { | ||
calculatedRowHeight = rowHeight(treeIndex, _node, _path); | ||
} | ||
return connectDropTarget(jsxRuntime.jsxs("div", { ...otherProps, | ||
return connectDropTarget(jsxRuntime.jsxs("div", { | ||
...otherProps, | ||
style: { | ||
@@ -1333,3 +1231,2 @@ height: `${calculatedRowHeight}px` | ||
} | ||
} | ||
@@ -1341,5 +1238,5 @@ | ||
}; | ||
const TreePlaceholder = props => { | ||
props = { ...defaultProps, | ||
props = { | ||
...defaultProps, | ||
...props | ||
@@ -1355,3 +1252,4 @@ }; | ||
return connectDropTarget(jsxRuntime.jsx("div", { | ||
children: React.Children.map(children, child => React.cloneElement(child, { ...otherProps | ||
children: React.Children.map(children, child => React.cloneElement(child, { | ||
...otherProps | ||
})) | ||
@@ -1362,3 +1260,2 @@ })); | ||
let rafId = 0; | ||
const nodeDragSourcePropInjection = (connect, monitor) => ({ | ||
@@ -1370,3 +1267,2 @@ connectDragSource: connect.dragSource(), | ||
}); | ||
const wrapSource = (el, startDrag, endDrag, dndType) => { | ||
@@ -1395,3 +1291,2 @@ const nodeDragSource = { | ||
}; | ||
const propInjection = (connect, monitor) => { | ||
@@ -1406,3 +1301,2 @@ const dragged = monitor.getItem(); | ||
}; | ||
const wrapPlaceholder = (el, treeId, drop, dndType) => { | ||
@@ -1430,7 +1324,5 @@ const placeholderDropTarget = { | ||
}; | ||
const getTargetDepth = (dropTargetProps, monitor, component, canNodeHaveChildren, treeId, maxDepth) => { | ||
let dropTargetDepth = 0; | ||
const rowAbove = dropTargetProps.getPrevRow(); | ||
if (rowAbove) { | ||
@@ -1444,16 +1336,11 @@ const { | ||
const aboveNodeCannotHaveChildren = !canNodeHaveChildren(node); | ||
if (aboveNodeCannotHaveChildren) { | ||
path = path.slice(0, -1); | ||
} | ||
dropTargetDepth = Math.min(path.length, dropTargetProps.path.length); | ||
} | ||
let blocksOffset; | ||
let dragSourceInitialDepth = (monitor.getItem().path || []).length; | ||
if (monitor.getItem().treeId !== treeId) { | ||
dragSourceInitialDepth = 0; | ||
if (component) { | ||
@@ -1470,5 +1357,3 @@ const relativePosition = component.node.getBoundingClientRect(); | ||
} | ||
let targetDepth = Math.min(dropTargetDepth, Math.max(0, dragSourceInitialDepth + blocksOffset - 1)); | ||
if (typeof maxDepth !== 'undefined' && maxDepth !== undefined) { | ||
@@ -1479,6 +1364,4 @@ const draggedNode = monitor.getItem().node; | ||
} | ||
return targetDepth; | ||
}; | ||
const canDrop = (dropTargetProps, monitor, canNodeHaveChildren, treeId, maxDepth, treeRefcanDrop, draggingTreeData, treeReftreeData, getNodeKey) => { | ||
@@ -1488,3 +1371,2 @@ if (!monitor.isOver()) { | ||
} | ||
const rowAbove = dropTargetProps.getPrevRow(); | ||
@@ -1494,7 +1376,5 @@ const abovePath = rowAbove ? rowAbove.path : []; | ||
const targetDepth = getTargetDepth(dropTargetProps, monitor, undefined, canNodeHaveChildren, treeId, maxDepth); | ||
if (targetDepth >= abovePath.length && typeof aboveNode.children === 'function') { | ||
return false; | ||
} | ||
if (typeof treeRefcanDrop === 'function') { | ||
@@ -1514,6 +1394,4 @@ const { | ||
} | ||
return true; | ||
}; | ||
const wrapTarget = (el, canNodeHaveChildren, treeId, maxDepth, treeRefcanDrop, drop, dragHover, dndType, draggingTreeData, treeReftreeData, getNodeKey) => { | ||
@@ -1536,16 +1414,14 @@ const nodeDropTarget = { | ||
const draggedNode = monitor.getItem().node; | ||
const needsRedraw = dropTargetProps.node !== draggedNode || targetDepth !== dropTargetProps.path.length - 1; | ||
const needsRedraw = | ||
dropTargetProps.node !== draggedNode || | ||
targetDepth !== dropTargetProps.path.length - 1; | ||
if (!needsRedraw) { | ||
return; | ||
} | ||
cancelAnimationFrame(rafId); | ||
rafId = requestAnimationFrame(() => { | ||
const item = monitor.getItem(); | ||
if (!item || !monitor.isOver()) { | ||
return; | ||
} | ||
dragHover({ | ||
@@ -1576,3 +1452,2 @@ node: draggedNode, | ||
const argsArray = keysArray.map(key => args[key]); | ||
if (argsArray.length !== savedArgsArray.length || argsArray.some((arg, index) => arg !== savedArgsArray[index]) || keysArray.some((key, index) => key !== savedKeysArray[index])) { | ||
@@ -1583,7 +1458,5 @@ savedArgsArray = argsArray; | ||
} | ||
return savedResult; | ||
}; | ||
}; | ||
const memoizedInsertNode = memoize(insertNode); | ||
@@ -1594,9 +1467,11 @@ const memoizedGetFlatDataFromTree = memoize(getFlatDataFromTree); | ||
let treeIdCounter = 1; | ||
const mergeTheme = props => { | ||
const merged = { ...props, | ||
style: { ...props.theme.style, | ||
const merged = { | ||
...props, | ||
style: { | ||
...props.theme.style, | ||
...props.style | ||
}, | ||
innerStyle: { ...props.theme.innerStyle, | ||
innerStyle: { | ||
...props.theme.innerStyle, | ||
...props.innerStyle | ||
@@ -1613,3 +1488,2 @@ } | ||
}; | ||
for (const propKey of Object.keys(overridableDefaults)) { | ||
@@ -1620,6 +1494,4 @@ if (props[propKey] === undefined) { | ||
} | ||
return merged; | ||
}; | ||
class ReactSortableTree extends React.Component { | ||
@@ -1639,3 +1511,2 @@ static search(props, state, seekIndex, expand, singleSearch) { | ||
} = state; | ||
if (!searchQuery && !searchMethod) { | ||
@@ -1645,3 +1516,2 @@ if (searchFinishCallback) { | ||
} | ||
return { | ||
@@ -1651,3 +1521,2 @@ searchMatches: [] | ||
} | ||
const newState = { | ||
@@ -1671,3 +1540,2 @@ instanceProps: {} | ||
}); | ||
if (expand) { | ||
@@ -1677,13 +1545,9 @@ newState.instanceProps.ignoreOneTreeUpdate = true; | ||
} | ||
if (searchFinishCallback) { | ||
searchFinishCallback(searchMatches); | ||
} | ||
let searchFocusTreeIndex; | ||
if (seekIndex && searchFocusOffset !== undefined && searchFocusOffset < searchMatches.length) { | ||
searchFocusTreeIndex = searchMatches[searchFocusOffset].treeIndex; | ||
} | ||
newState.searchMatches = searchMatches; | ||
@@ -1693,3 +1557,2 @@ newState.searchFocusTreeIndex = searchFocusTreeIndex; | ||
} | ||
static loadLazyChildren(props, state) { | ||
@@ -1719,3 +1582,5 @@ const { | ||
node: oldNode | ||
}) => oldNode === node ? { ...oldNode, | ||
}) => | ||
oldNode === node ? { | ||
...oldNode, | ||
children: childrenArray | ||
@@ -1730,3 +1595,2 @@ } : oldNode, | ||
} | ||
constructor(props) { | ||
@@ -1783,3 +1647,2 @@ super(props); | ||
} | ||
componentDidMount() { | ||
@@ -1791,3 +1654,2 @@ ReactSortableTree.loadLazyChildren(this.props, this.state); | ||
} | ||
static getDerivedStateFromProps(nextProps, prevState) { | ||
@@ -1798,8 +1660,10 @@ const { | ||
const newState = {}; | ||
const newInstanceProps = { | ||
...instanceProps | ||
}; | ||
const isTreeDataEqual = isEqual__default["default"](instanceProps.treeData, nextProps.treeData); | ||
instanceProps.treeData = nextProps.treeData; | ||
newInstanceProps.treeData = nextProps.treeData; | ||
if (!isTreeDataEqual) { | ||
if (instanceProps.ignoreOneTreeUpdate) { | ||
instanceProps.ignoreOneTreeUpdate = false; | ||
newInstanceProps.ignoreOneTreeUpdate = false; | ||
} else { | ||
@@ -1810,3 +1674,2 @@ newState.searchFocusTreeIndex = undefined; | ||
} | ||
newState.draggingTreeData = undefined; | ||
@@ -1822,6 +1685,6 @@ newState.draggedNode = undefined; | ||
} | ||
instanceProps.searchQuery = nextProps.searchQuery; | ||
instanceProps.searchFocusOffset = nextProps.searchFocusOffset; | ||
newState.instanceProps = { ...instanceProps, | ||
newInstanceProps.searchQuery = nextProps.searchQuery; | ||
newInstanceProps.searchFocusOffset = nextProps.searchFocusOffset; | ||
newState.instanceProps = { | ||
...newInstanceProps, | ||
...newState.instanceProps | ||
@@ -1831,3 +1694,2 @@ }; | ||
} | ||
componentDidUpdate(prevProps, prevState) { | ||
@@ -1841,10 +1703,7 @@ if (this.state.dragging !== prevState.dragging && this.props.onDragStateChanged) { | ||
} | ||
componentWillUnmount() { | ||
this.clearMonitorSubscription(); | ||
} | ||
handleDndMonitorChange() { | ||
const monitor = this.props.dragDropManager.getMonitor(); | ||
if (!monitor.isDragging() && this.state.draggingTreeData) { | ||
@@ -1856,3 +1715,2 @@ setTimeout(() => { | ||
} | ||
getRows(treeData) { | ||
@@ -1865,3 +1723,2 @@ return memoizedGetFlatDataFromTree({ | ||
} | ||
startDrag = ({ | ||
@@ -1897,3 +1754,2 @@ path | ||
} | ||
this.setState(({ | ||
@@ -1923,3 +1779,4 @@ draggingTreeData, | ||
node | ||
}) => ({ ...node, | ||
}) => ({ | ||
...node, | ||
expanded: true | ||
@@ -1938,3 +1795,2 @@ }), | ||
} = this.state; | ||
if (!dropResult) { | ||
@@ -1955,3 +1811,2 @@ this.setState({ | ||
let shouldCopy = this.props.shouldCopyOnOutsideDrop; | ||
if (typeof shouldCopy === 'function') { | ||
@@ -1964,5 +1819,3 @@ shouldCopy = shouldCopy({ | ||
} | ||
let treeData = this.state.draggingTreeData || instanceProps.treeData; | ||
if (shouldCopy) { | ||
@@ -1974,3 +1827,4 @@ treeData = changeNodeAtPath({ | ||
node: copyNode | ||
}) => ({ ...copyNode | ||
}) => ({ | ||
...copyNode | ||
}), | ||
@@ -1980,3 +1834,2 @@ getNodeKey: this.props.getNodeKey | ||
} | ||
this.props.onChange(treeData); | ||
@@ -2002,10 +1855,7 @@ this.props.onMoveNode({ | ||
} = this.props; | ||
if (canNodeHaveChildren) { | ||
return canNodeHaveChildren(node); | ||
} | ||
return true; | ||
}; | ||
toggleChildrenVisibility({ | ||
@@ -2023,3 +1873,4 @@ node: targetNode, | ||
node | ||
}) => ({ ...node, | ||
}) => ({ | ||
...node, | ||
expanded: !node.expanded | ||
@@ -2037,3 +1888,2 @@ }), | ||
} | ||
moveNode({ | ||
@@ -2072,3 +1922,2 @@ node, | ||
} | ||
renderRow(row, { | ||
@@ -2143,3 +1992,2 @@ listIndex, | ||
} | ||
render() { | ||
@@ -2168,3 +2016,2 @@ const { | ||
let swapLength; | ||
if (draggedNode && draggedMinimumTreeIndex !== undefined) { | ||
@@ -2188,5 +2035,3 @@ const addedResult = memoizedInsertNode({ | ||
} | ||
const matchKeys = {}; | ||
for (const [i, { | ||
@@ -2197,3 +2042,2 @@ path | ||
} | ||
if (searchFocusTreeIndex !== undefined) { | ||
@@ -2205,6 +2049,4 @@ this.listRef.current.scrollToIndex({ | ||
} | ||
let containerStyle = style; | ||
let list; | ||
if (rows.length === 0) { | ||
@@ -2241,3 +2083,2 @@ const Placeholder = this.treePlaceholderRenderer; | ||
} | ||
return jsxRuntime.jsx("div", { | ||
@@ -2249,5 +2090,3 @@ className: classnames('rst__tree', className, rowDirectionClass), | ||
} | ||
} | ||
ReactSortableTree.defaultProps = { | ||
@@ -2283,3 +2122,2 @@ canDrag: true, | ||
}; | ||
const SortableTreeWithoutDndContext = function (props) { | ||
@@ -2289,3 +2127,4 @@ return jsxRuntime.jsx(reactDnd.DndContext.Consumer, { | ||
dragDropManager | ||
}) => dragDropManager === undefined ? undefined : jsxRuntime.jsx(ReactSortableTree, { ...props, | ||
}) => dragDropManager === undefined ? undefined : jsxRuntime.jsx(ReactSortableTree, { | ||
...props, | ||
dragDropManager: dragDropManager | ||
@@ -2295,3 +2134,2 @@ }) | ||
}; | ||
const SortableTree = function (props) { | ||
@@ -2301,3 +2139,4 @@ return jsxRuntime.jsx(reactDnd.DndProvider, { | ||
backend: reactDndHtml5Backend.HTML5Backend, | ||
children: jsxRuntime.jsx(SortableTreeWithoutDndContext, { ...props | ||
children: jsxRuntime.jsx(SortableTreeWithoutDndContext, { | ||
...props | ||
}) | ||
@@ -2304,0 +2143,0 @@ }); |
{ | ||
"name": "@nosferatu500/react-sortable-tree", | ||
"version": "4.2.0", | ||
"version": "4.2.1", | ||
"description": "Drag-and-drop sortable component for nested data and hierarchies", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
@@ -103,3 +103,3 @@ # Note: TypeScript support (included from v4) | ||
| onChange<br/>_(required)_ | func | Called whenever tree data changed. Just like with React input elements, you have to update your own component's data to see the changes reflected.<div>`( treeData: object[] ): void`</div> | | ||
| getNodeKey<br/>_(recommended)_ | func | Specify the unique key used to identify each node and generate the `path` array passed in callbacks. With a setting of `getNodeKey={({ node }) => node.id}`, for example, in callbacks this will let you easily determine that the node with an `id` of `35` is (or has just become) a child of the node with an `id` of `12`, which is a child of ... and so on. It uses [`defaultGetNodeKey`](https://github.com/nosferatu500/react-sortable-tree/blob/master/src/utils/default-handlers.js) by default, which returns the index in the tree (omitting hidden nodes).<div>`({ node: object, treeIndex: number }): string or number`</div> | | ||
| getNodeKey<br/>_(recommended)_ | func | Specify the unique key used to identify each node and generate the `path` array passed in callbacks. With a setting of `getNodeKey={({ node }) => node.id}`, for example, in callbacks this will let you easily determine that the node with an `id` of `35` is (or has just become) a child of the node with an `id` of `12`, which is a child of ... and so on. It uses [`defaultGetNodeKey`](./src/utils/default-handlers.ts) by default, which returns the index in the tree (omitting hidden nodes).<div>`({ node: object, treeIndex: number }): string or number`</div> | | ||
| generateNodeProps | func | Generate an object with additional props to be passed to the node renderer. Use this for adding buttons via the `buttons` key, or additional `style` / `className` settings.<div>`({ node: object, path: number[] or string[], treeIndex: number, lowerSiblingCounts: number[], isSearchMatch: bool, isSearchFocus: bool }): object`</div> | | ||
@@ -115,3 +115,3 @@ | onMoveNode | func | Called after node move operation. <div>`({ treeData: object[], node: object, nextParentNode: object, prevPath: number[] or string[], prevTreeIndex: number, nextPath: number[] or string[], nextTreeIndex: number }): void`</div> | | ||
| theme | object | Set an all-in-one packaged appearance for the tree. See the [Themes](#themes) section for more information. | | ||
| searchMethod | func | The method used to search nodes. Defaults to [`defaultSearchMethod`](https://github.com/nosferatu500/react-sortable-tree/blob/master/src/utils/default-handlers.js), which uses the `searchQuery` string to search for nodes with matching `title` or `subtitle` values. NOTE: Changing `searchMethod` will not update the search, but changing the `searchQuery` will.<div>`({ node: object, path: number[] or string[], treeIndex: number, searchQuery: any }): bool`</div> | | ||
| searchMethod | func | The method used to search nodes. Defaults to [`defaultSearchMethod`](./src/utils/default-handlers.ts), which uses the `searchQuery` string to search for nodes with matching `title` or `subtitle` values. NOTE: Changing `searchMethod` will not update the search, but changing the `searchQuery` will.<div>`({ node: object, path: number[] or string[], treeIndex: number, searchQuery: any }): bool`</div> | | ||
| searchQuery | string or any | Used by the `searchMethod` to highlight and scroll to matched nodes. Should be a string for the default `searchMethod`, but can be anything when using a custom search. Defaults to `null`. | | ||
@@ -128,4 +128,4 @@ | searchFocusOffset | number | Outline the <`searchFocusOffset`>th node and scroll to it. | | ||
| scaffoldBlockPxWidth | number | The width of the blocks containing the lines representing the structure of the tree. Defaults to `44`. | | ||
| nodeContentRenderer | any | Override the default component ([`NodeRendererDefault`](https://github.com/nosferatu500/react-sortable-tree/blob/master/src/node-renderer-default.js)) for rendering nodes (but keep the scaffolding generator). This is a last resort for customization - most custom styling should be able to be solved with `generateNodeProps`, a `theme` or CSS rules. If you must use it, is best to copy the component in `node-renderer-default.js` to use as a base, and customize as needed. | | ||
| placeholderRenderer | any | Override the default placeholder component ([`PlaceholderRendererDefault`](https://github.com/nosferatu500/react-sortable-tree/blob/master/src/placeholder-renderer-default.js)) which is displayed when the tree is empty. This is an advanced option, and in most cases should probably be solved with a `theme` or custom CSS instead. | | ||
| nodeContentRenderer | any | Override the default component ([`NodeRendererDefault`](./src/node-renderer-default.tsx)) for rendering nodes (but keep the scaffolding generator). This is a last resort for customization - most custom styling should be able to be solved with `generateNodeProps`, a `theme` or CSS rules. If you must use it, is best to copy the component in `node-renderer-default.tsx` to use as a base, and customize as needed. | | ||
| placeholderRenderer | any | Override the default placeholder component ([`PlaceholderRendererDefault`](./src/placeholder-renderer-default.tsx)) which is displayed when the tree is empty. This is an advanced option, and in most cases should probably be solved with a `theme` or custom CSS instead. | | ||
## Data Helper Functions | ||
@@ -135,3 +135,3 @@ | ||
Want to perform add/remove operations on the tree data without creating your own recursive function? | ||
Check out the helper functions exported from [`tree-data-utils.js`](https://github.com/nosferatu500/react-sortable-tree/blob/master/src/utils/tree-data-utils.js). | ||
Check out the helper functions exported from [`tree-data-utils.ts`](./src/utils/tree-data-utils.ts). | ||
@@ -138,0 +138,0 @@ - **`getTreeFromFlatData`**: Convert flat data (like that from a database) into nested tree data. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7604
247358