react-native-tree-multi-select
Version:
A super-fast, customizable tree view component for React Native with multi-selection, checkboxes, and search filtering capabilities.
188 lines (184 loc) • 6.94 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
var _reactNative = require("react-native");
var _flashList = require("@shopify/flash-list");
var _treeView = require("../store/treeView.store");
var _helpers = require("../helpers");
var _CheckboxView = require("./CheckboxView");
var _CustomExpandCollapseIcon = require("./CustomExpandCollapseIcon");
var _treeView2 = require("../constants/treeView.constants");
var _shallow = require("zustand/react/shallow");
var _typedMemo = require("../utils/typedMemo");
var _ScrollToNodeHandler = require("../handlers/ScrollToNodeHandler");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const NodeList = (0, _typedMemo.typedMemo)(_NodeList);
var _default = exports.default = NodeList;
function _NodeList(props) {
const {
storeId,
scrollToNodeHandlerRef,
initialScrollNodeID,
treeFlashListProps,
checkBoxViewStyleProps,
indentationMultiplier,
CheckboxComponent,
ExpandCollapseIconComponent,
ExpandCollapseTouchableComponent,
CustomNodeRowComponent
} = props;
const {
expanded,
initialTreeViewData,
updateInnerMostChildrenIds,
searchKeys,
searchText
} = (0, _treeView.useTreeViewStore)(storeId)((0, _shallow.useShallow)(state => ({
expanded: state.expanded,
initialTreeViewData: state.initialTreeViewData,
updateInnerMostChildrenIds: state.updateInnerMostChildrenIds,
searchKeys: state.searchKeys,
searchText: state.searchText
})));
const flashListRef = _react.default.useRef(null);
const [initialScrollIndex, setInitialScrollIndex] = _react.default.useState(-1);
// First we filter the tree as per the search term and keys
const filteredTree = _react.default.useMemo(() => (0, _helpers.getFilteredTreeData)(initialTreeViewData, searchText.trim().toLowerCase(), searchKeys), [initialTreeViewData, searchText, searchKeys]);
// Then we flatten the tree to make it "render-compatible" in a "flat" list
const flattenedFilteredNodes = _react.default.useMemo(() => (0, _helpers.getFlattenedTreeData)(filteredTree, expanded), [filteredTree, expanded]);
// And update the innermost children id -> required to un/select filtered tree
_react.default.useEffect(() => {
const updatedInnerMostChildrenIds = (0, _helpers.getInnerMostChildrenIdsInTree)(filteredTree);
updateInnerMostChildrenIds(updatedInnerMostChildrenIds);
}, [filteredTree, updateInnerMostChildrenIds]);
const nodeRenderer = _react.default.useCallback(({
item
}) => {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Node, {
storeId: storeId,
node: item,
level: item.level || 0,
checkBoxViewStyleProps: checkBoxViewStyleProps,
indentationMultiplier: indentationMultiplier,
CheckboxComponent: CheckboxComponent,
ExpandCollapseIconComponent: ExpandCollapseIconComponent,
ExpandCollapseTouchableComponent: ExpandCollapseTouchableComponent,
CustomNodeRowComponent: CustomNodeRowComponent
});
}, [storeId, CheckboxComponent, ExpandCollapseIconComponent, ExpandCollapseTouchableComponent, CustomNodeRowComponent, checkBoxViewStyleProps, indentationMultiplier]);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ScrollToNodeHandler.ScrollToNodeHandler, {
ref: scrollToNodeHandlerRef,
storeId: storeId,
flashListRef: flashListRef,
flattenedFilteredNodes: flattenedFilteredNodes,
setInitialScrollIndex: setInitialScrollIndex,
initialScrollNodeID: initialScrollNodeID
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_flashList.FlashList, {
ref: flashListRef,
estimatedItemSize: 36,
initialScrollIndex: initialScrollIndex,
removeClippedSubviews: true,
keyboardShouldPersistTaps: "handled",
drawDistance: 50,
ListHeaderComponent: /*#__PURE__*/(0, _jsxRuntime.jsx)(HeaderFooterView, {}),
ListFooterComponent: /*#__PURE__*/(0, _jsxRuntime.jsx)(HeaderFooterView, {}),
...treeFlashListProps,
data: flattenedFilteredNodes,
renderItem: nodeRenderer
})]
});
}
;
function HeaderFooterView() {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: styles.defaultHeaderFooter
});
}
function getValue(isChecked, isIndeterminate) {
if (isIndeterminate) {
return "indeterminate";
} else if (isChecked) {
return true;
} else {
return false;
}
}
const Node = (0, _typedMemo.typedMemo)(_Node);
function _Node(props) {
const {
storeId,
node,
level,
checkBoxViewStyleProps,
indentationMultiplier = _treeView2.defaultIndentationMultiplier,
ExpandCollapseIconComponent = _CustomExpandCollapseIcon.CustomExpandCollapseIcon,
CheckboxComponent = _CheckboxView.CheckboxView,
ExpandCollapseTouchableComponent = _reactNative.TouchableOpacity,
CustomNodeRowComponent
} = props;
const {
isExpanded,
value
} = (0, _treeView.useTreeViewStore)(storeId)((0, _shallow.useShallow)(state => ({
isExpanded: state.expanded.has(node.id),
value: getValue(state.checked.has(node.id),
// isChecked
state.indeterminate.has(node.id) // isIndeterminate
)
})));
const _onToggleExpand = _react.default.useCallback(() => {
(0, _helpers.handleToggleExpand)(storeId, node.id);
}, [storeId, node.id]);
const _onCheck = _react.default.useCallback(() => {
(0, _helpers.toggleCheckboxes)(storeId, [node.id]);
}, [storeId, node.id]);
if (!CustomNodeRowComponent) {
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.nodeCheckboxAndArrowRow, {
paddingStart: level * indentationMultiplier
}],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(CheckboxComponent, {
text: node.name,
onValueChange: _onCheck,
value: value,
...checkBoxViewStyleProps
}), node.children?.length ? /*#__PURE__*/(0, _jsxRuntime.jsx)(ExpandCollapseTouchableComponent, {
style: styles.nodeExpandableArrowTouchable,
onPress: _onToggleExpand,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ExpandCollapseIconComponent, {
isExpanded: isExpanded
})
}) : null]
});
} else {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(CustomNodeRowComponent, {
node: node,
level: level,
checkedValue: value,
isExpanded: isExpanded,
onCheck: _onCheck,
onExpand: _onToggleExpand
});
}
}
;
const styles = _reactNative.StyleSheet.create({
defaultHeaderFooter: {
padding: 5
},
nodeExpandableArrowTouchable: {
flex: 1
},
nodeCheckboxAndArrowRow: {
flex: 1,
flexDirection: "row",
alignItems: "center",
minWidth: "100%"
}
});
//# sourceMappingURL=NodeList.js.map
;