Data components

Tree

A folder tree with checkboxes, drag & drop, rename, context menu and buttons that change it.

Nodes

A tree shows nodes: { id, label, children }. A node with children is a folder; expanded: true opens it at the start. Optional: icon, badge, description, disabled, and any data of your own.

Options switch features on: checkboxes (with cascadeCheck, folders check their children), showLines, draggable (drag a node onto / between others), editable (F2 or double-click to rename), contextMenu (right-click), filters and search.

Everything can also be changed from outside: the field and buttons above the tree call api.addTreeNode, updateTreeNode, removeTreeNode, selectTreeNode, setTreeSearch, expandAllTree, ...

Try it

Loading example…
Events0
Use the example — every action it runs shows up here with its data.

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": "row",
    "id": "row-controls",
    "children": [
      {
        "type": "column",
        "id": "c-name",
        "props": {
          "className": "col-12 col-md-4"
        },
        "children": [
          {
            "type": "InputField",
            "id": "item-name",
            "props": {
              "name": "itemName",
              "label": "Item name",
              "placeholder": "Header.js — end with / for a folder"
            }
          }
        ]
      },
      {
        "type": "column",
        "id": "c-find",
        "props": {
          "className": "col-12 col-md-4"
        },
        "children": [
          {
            "type": "InputField",
            "id": "find",
            "props": {
              "name": "find",
              "label": "Find",
              "placeholder": "type to filter",
              "onChange": "findChanged()"
            }
          }
        ]
      },
      {
        "type": "column",
        "id": "c-view",
        "props": {
          "className": "col-12 col-md-4"
        },
        "children": [
          {
            "type": "SelectField",
            "id": "view",
            "props": {
              "name": "view",
              "label": "View",
              "defaultValue": "tree",
              "onChange": "viewChanged()",
              "options": [
                {
                  "label": "Tree",
                  "value": "tree"
                },
                {
                  "label": "Columns",
                  "value": "columns"
                },
                {
                  "label": "Explorer",
                  "value": "explorer"
                }
              ]
            }
          }
        ]
      }
    ]
  },
  {
    "type": "row",
    "id": "row-buttons",
    "children": [
      {
        "type": "column",
        "id": "c-buttons",
        "props": {
          "className": "d-flex flex-wrap gap-2 mb-2"
        },
        "children": [
          {
            "type": "ButtonField",
            "id": "add",
            "props": {
              "text": "+ Add to selected folder",
              "variant": "outline-success",
              "onClick": "addItem()"
            }
          },
          {
            "type": "ButtonField",
            "id": "rename",
            "props": {
              "text": "Rename selected",
              "variant": "outline-primary",
              "onClick": "renameSelected()"
            }
          },
          {
            "type": "ButtonField",
            "id": "delete",
            "props": {
              "text": "Delete selected",
              "variant": "outline-danger",
              "onClick": "deleteSelected()"
            }
          },
          {
            "type": "ButtonField",
            "id": "goto",
            "props": {
              "text": "Go to dates.js",
              "variant": "outline-secondary",
              "onClick": "goToDates()"
            }
          },
          {
            "type": "ButtonField",
            "id": "checked",
            "props": {
              "text": "Show checked",
              "variant": "outline-secondary",
              "onClick": "showChecked()"
            }
          }
        ]
      }
    ]
  },
  {
    "type": "Tree",
    "id": "project",
    "props": {
      "title": "my-app",
      "nodes": [
        {
          "id": "src",
          "label": "src",
          "expanded": true,
          "children": [
            {
              "id": "src/components",
              "label": "components",
              "expanded": true,
              "children": [
                {
                  "id": "src/components/Button.js",
                  "label": "Button.js",
                  "size": 2310
                },
                {
                  "id": "src/components/Card.js",
                  "label": "Card.js",
                  "size": 1874
                },
                {
                  "id": "src/components/Modal.js",
                  "label": "Modal.js",
                  "size": 4120,
                  "badge": "new"
                }
              ]
            },
            {
              "id": "src/utils",
              "label": "utils",
              "children": [
                {
                  "id": "src/utils/format.js",
                  "label": "format.js",
                  "size": 980
                },
                {
                  "id": "src/utils/dates.js",
                  "label": "dates.js",
                  "size": 1430
                }
              ]
            },
            {
              "id": "src/index.js",
              "label": "index.js",
              "size": 640
            }
          ]
        },
        {
          "id": "public",
          "label": "public",
          "children": [
            {
              "id": "public/index.html",
              "label": "index.html",
              "size": 1210
            },
            {
              "id": "public/logo.png",
              "label": "logo.png",
              "size": 15086
            }
          ]
        },
        {
          "id": "config",
          "label": "config",
          "icon": "⚙️",
          "children": [
            {
              "id": "config/prod.json",
              "label": "prod.json",
              "size": 310,
              "disabled": true,
              "description": "read-only"
            }
          ]
        },
        {
          "id": "package.json",
          "label": "package.json",
          "size": 1532
        },
        {
          "id": "README.md",
          "label": "README.md",
          "size": 4890
        }
      ],
      "height": 330,
      "checkboxes": true,
      "cascadeCheck": true,
      "showLines": true,
      "showCount": true,
      "draggable": true,
      "editable": true,
      "searchable": false,
      "filters": [
        {
          "id": "js",
          "label": ".js only",
          "when": {
            "field": "ext",
            "equals": "js"
          }
        }
      ],
      "contextMenu": [
        {
          "label": "Rename",
          "command": "rename"
        },
        {
          "label": "New file here",
          "action": "newFileHere()",
          "when": {
            "field": "branch",
            "equals": true
          }
        },
        {
          "divider": true
        },
        {
          "label": "Delete",
          "action": "deleteNode()"
        }
      ],
      "onSelect": "selected()",
      "onExpand": "toggled()",
      "onCollapse": "toggled()",
      "onCheck": "checked()",
      "onActivate": "opened()",
      "onMove": "moved()",
      "onRename": "renamed()",
      "onNodeFocus": "focused()"
    }
  },
  {
    "type": "P",
    "id": "status",
    "props": {
      "className": "small text-body-secondary mt-2",
      "text": "Select, check, drag, double-click or right-click a node."
    }
  }
]

Options used here

OptionWhat it does
nodes[{ id, label, children, expanded, icon, badge, description, disabled }].
view / viewstree, explorer, columns.
selectionModenone, single, multiple (Ctrl / Shift).
checkboxes / cascadeCheckCheckboxes; folders check their children.
showLines / showIcons / showCountGuide lines, icons, child counts.
draggable / editableDrag to move; rename with F2.
contextMenu{ label, action } or { label, command: "rename" | "open" | "expand" | "reload" | "delete" }, when, divider.
filters / searchableFilter chips (when on node fields, ext is filled in) and a search box.

Events

EventWhen it runsYour action receives
onSelectSelection changes.{ node, selected, nodes }
onExpand / onCollapseA folder opens / closes.{ node, id, path, level }
onCheckA checkbox changes.{ node, checked, checkedIds, checkedNodes }
onActivateDouble-click / Enter on a file.{ node }
onMoveA node is dropped.{ node, target, position, parentId, index } — return false to refuse
onRenameA name is edited.{ node, name, previous } — return false to refuse
onNodeFocus / onNodeClick / onNodeDoubleClick / onContextMenu / onDeleteFocus, clicks, right-click, Delete key.{ node } (onDelete: { ids, nodes })

Tips

  • Keyboard: ↑ ↓ to move, → / ← to open / close, Enter to open, Space to select or check, * to open siblings, F2 to rename, type letters to jump.