rsuite
Version:
A suite of react components
153 lines (129 loc) • 4.08 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { useState, useMemo } from 'react';
import slice from 'lodash/slice';
import { shallowEqual, useUpdateEffect } from '../utils';
import { findNodeOfTree } from '../utils/treeUtils';
export function getColumnsAndPaths(data, value, options) {
var childrenKey = options.childrenKey,
valueKey = options.valueKey,
isAttachChildren = options.isAttachChildren;
var columns = [];
var paths = [];
var findNode = function findNode(items) {
var _loop = function _loop(i) {
var children = items[i][childrenKey];
if (shallowEqual(items[i][valueKey], value)) {
return {
v: {
items: items,
active: items[i]
}
};
} else if (children) {
var node = findNode(children);
if (node) {
columns.push(children.map(function (item) {
return _extends({}, item, {
parent: items[i]
});
}));
paths.push(node.active);
return {
v: {
items: items,
active: items[i]
}
};
}
}
};
for (var i = 0; i < items.length; i += 1) {
var _ret = _loop(i);
if (typeof _ret === "object") return _ret.v;
}
return null;
};
var selectedNode = findNode(data);
columns.push(data);
if (selectedNode) {
paths.push(selectedNode.active);
}
if (isAttachChildren) {
var valueToNode = findNodeOfTree(data, function (item) {
return item[valueKey] === value;
});
if (valueToNode !== null && valueToNode !== void 0 && valueToNode[childrenKey]) {
columns.unshift(valueToNode[childrenKey]);
}
}
columns.reverse();
paths.reverse();
return {
columns: columns,
paths: paths
};
}
export function usePaths(props) {
var data = props.data,
valueKey = props.valueKey,
childrenKey = props.childrenKey,
value = props.value;
var _useMemo = useMemo(function () {
return getColumnsAndPaths(data, value, {
valueKey: valueKey,
childrenKey: childrenKey
});
}, [data, value, valueKey, childrenKey]),
columns = _useMemo.columns,
paths = _useMemo.paths; // The columns displayed in the cascading panel.
var _useState = useState(columns),
columnData = _useState[0],
setColumnData = _useState[1]; // The path after cascading data selection.
var _useState2 = useState(paths),
selectedPaths = _useState2[0],
setSelectedPaths = _useState2[1]; // The path corresponding to the selected value.
var _useState3 = useState(paths),
valueToPaths = _useState3[0],
setValueToPaths = _useState3[1];
/**
* Add a list of options to the cascading panel. Used for lazy loading options.
* @param column
* @param index The index of the current column.
*/
function addColumn(column, index) {
setColumnData([].concat(slice(columnData, 0, index), [column]));
}
/**
* Enforce update of columns and paths.
* @param nextValue Selected value
* @param isAttachChildren Whether to attach the children of the selected node.
*/
function enforceUpdate(nextValue, isAttachChildren) {
var _getColumnsAndPaths = getColumnsAndPaths(data, nextValue, {
valueKey: valueKey,
childrenKey: childrenKey,
isAttachChildren: isAttachChildren
}),
columns = _getColumnsAndPaths.columns,
paths = _getColumnsAndPaths.paths;
setColumnData(columns);
setSelectedPaths(paths);
}
useUpdateEffect(function () {
// Update paths when value is updated, then update valueToPaths.
setValueToPaths(paths);
}, [paths]);
useUpdateEffect(function () {
enforceUpdate(value);
}, [data]);
return {
enforceUpdate: enforceUpdate,
columnData: columnData,
valueToPaths: valueToPaths,
selectedPaths: selectedPaths,
setValueToPaths: setValueToPaths,
setColumnData: setColumnData,
setSelectedPaths: setSelectedPaths,
addColumn: addColumn
};
}