@@ -103,3 +103,98 @@ function App() {
103
103
This feature can programmatically be controlled by pulling a React Ref either from the tree environment
104
104
or the tree itself, and acting on the Ref object. [ Read the documentation on externally interacting
105
105
with the tree via Refs] ( /docs/guides/refs ) to find out more.
106
+
107
+ ## Finding items that are not loaded in
108
+
109
+ The search functionality only searches through items that are currently visible in the tree. This keeps the
110
+ functionality in par with similar tree implementations, where you can directly type into a tree to jump to already
111
+ available items, giving an easier way to scroll through large trees.
112
+
113
+ Searching through all items and expanding potentially hidden items to expose the searched item is a bit more complicated,
114
+ and depends on your data structure to work. Because there are several ways to define a data structure with RCT,
115
+ it is up to you to implement the logic to actually find the item that should be displayed. Once you determined a path
116
+ to the item (i.e. an array of item ids), you can use the ` expandSubsequently(treeId, path) ` function in the
117
+ [ Tree environment ref] ( /docs/api/interfaces/TreeEnvironmentRef ) to expand the tree to the searched item, or use
118
+ the ` expandSubsequently(path) ` function in the [ Tree Ref] ( /docs/api/interfaces/TreeRef ) .
119
+
120
+ Try entering "blackberry" in the example below, and clicking on "Find item":
121
+
122
+ ``` jsx live
123
+ export const CustomFinder = () => {
124
+ const [search , setSearch ] = useState (' ' );
125
+ const tree = useRef (null )
126
+
127
+ const dataProvider = useMemo (
128
+ () =>
129
+ new StaticTreeDataProvider (longTree .items , (item , data ) => ({
130
+ ... item,
131
+ data,
132
+ })),
133
+ []
134
+ );
135
+
136
+ const findItemPath = useCallback (
137
+ async (search , searchRoot = ' root' ) => {
138
+ const item = await dataProvider .getTreeItem (searchRoot);
139
+ if (item .data .toLowerCase ().includes (search .toLowerCase ())) {
140
+ return [item .index ];
141
+ }
142
+ const searchedItems = await Promise .all (
143
+ item .children ? .map (child => findItemPath (search, child)) ?? []
144
+ );
145
+ const result = searchedItems .find (item => item !== null );
146
+ if (! result) {
147
+ return null ;
148
+ }
149
+ return [item .index , ... result];
150
+ },
151
+ [dataProvider]
152
+ );
153
+
154
+ const find = useCallback (
155
+ e => {
156
+ e .preventDefault ();
157
+ if (search) {
158
+ findItemPath (search).then (path => {
159
+ if (path) {
160
+ tree .current
161
+ ? .expandSubsequently (path .slice (0 , path .length - 1 ))
162
+ .then (() => {
163
+ tree .current ? .selectItems ([path[path .length - 1 ]]);
164
+ tree .current ? .focusItem (path[path .length - 1 ]);
165
+ });
166
+ }
167
+ });
168
+ }
169
+ },
170
+ [findItemPath, search]
171
+ );
172
+
173
+ return (
174
+ <>
175
+ < form onSubmit= {find}>
176
+ < input
177
+ value= {search}
178
+ onChange= {e => setSearch (e .target .value )}
179
+ placeholder= " Search..."
180
+ / >
181
+ < button type= " submit" > Find item< / button>
182
+ < / form>
183
+ < UncontrolledTreeEnvironment< string>
184
+ dataProvider= {dataProvider}
185
+ getItemTitle= {item => item .data }
186
+ viewState= {{
187
+ ' tree-1' : {},
188
+ }}
189
+ >
190
+ < Tree
191
+ treeId= " tree-1"
192
+ rootItem= " root"
193
+ treeLabel= " Tree Example"
194
+ ref= {tree}
195
+ / >
196
+ < / UncontrolledTreeEnvironment>
197
+ < / >
198
+ );
199
+ };
200
+ ` ` `
0 commit comments