diff --git a/README.md b/README.md
index 9dad5daf..6456ee1d 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,7 @@ Play with the code on an [example on CodeSandbox](https://codesandbox.io/s/wkxvy
| searchMethod | func | The method used to search nodes. Defaults to [`defaultSearchMethod`](https://github.com/fritz-c/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.
`({ node: object, path: number[] or string[], treeIndex: number, searchQuery: any }): bool`
|
| 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`. |
| searchFocusOffset | number | Outline the <`searchFocusOffset`>th node and scroll to it. |
+| expandOnlySearchedNodes | boolean | Only expand the nodes that match searches. Collapses all other nodes. Defaults to `false`. |
| searchFinishCallback | func | Get the nodes that match the search criteria. Used for counting total matches, etc.`(matches: { node: object, path: number[] or string[], treeIndex: number }[]): void`
|
| dndType | string | String value used by [react-dnd](http://react-dnd.github.io/react-dnd/docs-overview.html) (see overview at the link) for dropTargets and dragSources types. If not set explicitly, a default value is applied by react-sortable-tree for you for its internal use. **NOTE:** Must be explicitly set and the same value used in order for correct functioning of external nodes |
| shouldCopyOnOutsideDrop | func or bool | Return true, or a callback returning true, and dropping nodes to react-dnd drop targets outside of the tree will not remove them from the tree. Defaults to `false`. `({ node: object, prevPath: number[] or string[], prevTreeIndex: number, }): bool`
|
diff --git a/src/react-sortable-tree.js b/src/react-sortable-tree.js
index 81ed7909..6dac1382 100644
--- a/src/react-sortable-tree.js
+++ b/src/react-sortable-tree.js
@@ -17,6 +17,7 @@ import {
removeNode,
insertNode,
find,
+ toggleExpandedForAll,
} from './utils/tree-data-utils';
import {
memoizedInsertNode,
@@ -262,6 +263,7 @@ class ReactSortableTree extends Component {
searchQuery,
searchMethod,
searchFocusOffset,
+ onlyExpandSearchedNodes,
} = props;
// Skip search if no conditions are specified
@@ -282,9 +284,12 @@ class ReactSortableTree extends Component {
return;
}
+ // if onlyExpandSearchedNodes collapse the tree and search
const { treeData: expandedTreeData, matches: searchMatches } = find({
getNodeKey: this.props.getNodeKey,
- treeData,
+ treeData: onlyExpandSearchedNodes
+ ? toggleExpandedForAll({ treeData, expanded: false })
+ : treeData,
searchQuery,
searchMethod: searchMethod || defaultSearchMethod,
searchFocusOffset,
@@ -826,6 +831,9 @@ ReactSortableTree.propTypes = {
// Called to track between dropped and dragging
onDragStateChanged: PropTypes.func,
+
+ // Specify that nodes that do not match search will be collapsed
+ onlyExpandSearchedNodes: PropTypes.bool,
};
ReactSortableTree.defaultProps = {
@@ -855,6 +863,7 @@ ReactSortableTree.defaultProps = {
style: {},
theme: {},
onDragStateChanged: () => {},
+ onlyExpandSearchedNodes: false,
};
ReactSortableTree.contextTypes = {
diff --git a/src/react-sortable-tree.test.js b/src/react-sortable-tree.test.js
index 33e51d44..87c51f0e 100644
--- a/src/react-sortable-tree.test.js
+++ b/src/react-sortable-tree.test.js
@@ -313,6 +313,80 @@ describe('', () => {
expect(tree.state.searchFocusTreeIndex).toEqual(2);
});
+ it('search onlyExpandSearchedNodes should collapse all nodes except matches', () => {
+ const wrapper = mount(
+ wrapper.setProps({ treeData })}
+ onlyExpandSearchedNodes
+ />
+ );
+ wrapper.setProps({ searchQuery: 'be' });
+ expect(wrapper.prop('treeData')).toEqual([
+ {
+ title: 'a',
+ children: [
+ {
+ title: 'b',
+ children: [
+ {
+ title: 'c',
+ expanded: false,
+ },
+ ],
+ expanded: false,
+ },
+ ],
+ expanded: false,
+ },
+ {
+ title: 'b',
+ children: [
+ {
+ title: 'd',
+ children: [
+ {
+ title: 'be',
+ expanded: false,
+ },
+ ],
+ expanded: true,
+ },
+ ],
+ expanded: true,
+ },
+ {
+ title: 'c',
+ children: [
+ {
+ title: 'f',
+ children: [
+ {
+ title: 'dd',
+ expanded: false,
+ },
+ ],
+ expanded: false,
+ },
+ ],
+ expanded: false,
+ },
+ ]);
+ });
+
it('loads using SortableTreeWithoutDndContext', () => {
const HTML5Wrapped = DragDropContext(HTML5Backend)(
SortableTreeWithoutDndContext