Disabled Nodes
Set disabled: true on any node — often driven by a permission check on your side.
Billing
View invoices
Edit payment methods
Export reports
User Management
View users
Invite users
Remove users
Workspace Settings
General settings
Integrations
Danger zone
Show code
const data = [
{ id: "users.remove", label: "Remove users", disabled: true },
];"Remove users" and everything under "Danger zone" above are disabled — their checkboxes are inert and styled at reduced opacity, but the rows stay visible and remain reachable by keyboard navigation, per accessibility best practice (disabled content should be perceivable, not hidden).
| Prop | Type | Default | Description |
|---|---|---|---|
| disabledBehavior.cascadeToChildren | boolean | true | When a node is disabled, treat every descendant as disabled too — for checking and selecting, not just visually. |
| disabledBehavior.allowExpand | boolean | true | Whether a disabled node can still be expanded/collapsed to reveal its (also disabled, if cascading) children. |
Disabled doesn't mean excluded from the count
A disabled node's checked state still participates in its parent's indeterminate calculation — disabling a node hides the ability to change it, not its existing state. If you need to exclude disabled nodes from cascading entirely, filter them out of
selectionPropagation's effective descendant set by pre-processing your data instead.A common pattern: server-driven disabling
Since disabled lives on your own data, it's natural to compute it from a permissions check when you build the tree, rather than as separate TreeKit state:
const data = rawPermissions.map((p) => ({
...p,
disabled: !currentUser.canEdit(p.id),
}));