File explorer (lazy loading)
An S3-style explorer: folders load from an API page by page as you scroll, with server search.
Load folders from an API
Give a folder hasChildren: true (and no children) — or set lazyRoot: true for the top level — and the tree asks your onLoadChildren action when it opens: { parentId, cursor, pageSize }. Return { children, hasMore, cursor }.
While hasMore is true, the next page loads by itself when the user scrolls to the end — the same token idea as S3's ListObjectsV2 continuation token. Only the rows on screen are drawn, so thousands of files stay fast.
With searchMode: "server" the search box calls onSearch({ query, cursor, pageSize }), paged the same way.
The explorer view
view: "explorer" shows folders on the left and the open folder's contents on the right, with a path bar, sorting columns, and Details / List / Icons layouts. Open logs below and scroll: 300 files load 50 at a time.
Try it
Code
Copy Full page.js into app/your-page/page.js of a Next.js app (withrcube-html, react-bootstrap and Bootstrap's CSS installed) — it runs as is. Or copy only the schema and keep your own page.
[
{
"type": "Tree",
"id": "files",
"props": {
"title": "demo-bucket",
"view": "explorer",
"views": [
"explorer",
"tree",
"columns"
],
"contentView": "details",
"rootLabel": "demo-bucket",
"height": 440,
"nodes": [],
"lazyRoot": true,
"pageSize": 50,
"loadMore": "scroll",
"selectionMode": "multiple",
"searchMode": "server",
"searchPlaceholder": "Search the whole bucket…",
"filters": [
{
"id": "pdf",
"label": "PDF",
"when": {
"field": "ext",
"equals": "pdf"
}
},
{
"id": "images",
"label": "Images",
"when": {
"field": "ext",
"in": [
"jpg",
"png"
]
}
}
],
"columns": [
{
"key": "label",
"title": "Name"
},
{
"key": "size",
"title": "Size",
"format": "bytes",
"width": "110px",
"align": "end"
},
{
"key": "modified",
"title": "Modified",
"format": "datetime",
"width": "180px"
}
],
"contextMenu": [
{
"label": "Open",
"command": "open"
},
{
"label": "Copy path",
"action": "copyPath()"
},
{
"label": "Reload",
"command": "reload",
"when": {
"field": "branch",
"equals": true
}
}
],
"onLoadChildren": "loadChildren()",
"onSearch": "search()",
"onNavigate": "navigated()",
"onActivate": "openFile()",
"onSelect": "selected()",
"onScrollEnd": "scrolledToEnd()"
}
}
]Options used here
| Option | What it does |
|---|---|
hasChildren / lazyRoot | Load a folder's children (or the top level) through onLoadChildren. |
pageSize / loadMore | Items per request; load the next page on scroll or with a button. |
searchMode | client (loaded nodes) or server (onSearch). |
view / contentView / contentPaging | explorer + details / list / icons; scroll or pages. |
columns | Explorer details columns: { key, title, format: "bytes" | "date" | "datetime", width, align }. |
api.setTreeChildren / reloadTreeNode / openTreeFolder / scrollToTreeNode | Drive loading and navigation from code. |
Events
| Event | When it runs | Your action receives |
|---|---|---|
onLoadChildren | A lazy folder opens / more rows are needed. | { node, parentId, cursor, offset, pageSize, more } → { children, hasMore, cursor } |
onSearch | Search text changes (server mode). | { query, cursor, pageSize, filters, folder } → { nodes, hasMore, cursor } |
onNavigate | Another folder opens (explorer / columns). | { node, folder } |
onScrollEnd | The list was scrolled to its end. | { count } |
Tips
- For S3, call your own backend from
onLoadChildren— never put AWS keys in a web page.