Skip to content

Commit

Permalink
feat: Added onlyExpandSearchedNodes prop
Browse files Browse the repository at this point in the history
expandOnlySearchedNodes props is used so the tree only expands search matches and collapses all other nodes. #245.
  • Loading branch information
wuweiweiwu committed Mar 4, 2018
1 parent 32d1db7 commit 2d57928
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.<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`. |
| 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.<div>`(matches: { node: object, path: number[] or string[], treeIndex: number }[]): void`</div> |
| 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`. <div>`({ node: object, prevPath: number[] or string[], prevTreeIndex: number, }): bool`</div> |
Expand Down
11 changes: 10 additions & 1 deletion src/react-sortable-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
removeNode,
insertNode,
find,
toggleExpandedForAll,
} from './utils/tree-data-utils';
import {
memoizedInsertNode,
Expand Down Expand Up @@ -262,6 +263,7 @@ class ReactSortableTree extends Component {
searchQuery,
searchMethod,
searchFocusOffset,
onlyExpandSearchedNodes,
} = props;

// Skip search if no conditions are specified
Expand All @@ -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,
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -855,6 +863,7 @@ ReactSortableTree.defaultProps = {
style: {},
theme: {},
onDragStateChanged: () => {},
onlyExpandSearchedNodes: false,
};

ReactSortableTree.contextTypes = {
Expand Down
74 changes: 74 additions & 0 deletions src/react-sortable-tree.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,80 @@ describe('<SortableTree />', () => {
expect(tree.state.searchFocusTreeIndex).toEqual(2);
});

it('search onlyExpandSearchedNodes should collapse all nodes except matches', () => {
const wrapper = mount(
<SortableTree
treeData={[
{
title: 'a',
children: [{ title: 'b', children: [{ title: 'c' }] }],
},
{
title: 'b',
children: [{ title: 'd', children: [{ title: 'be' }] }],
},
{
title: 'c',
children: [{ title: 'f', children: [{ title: 'dd' }] }],
},
]}
onChange={treeData => 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
Expand Down

0 comments on commit 2d57928

Please sign in to comment.