Tree Table - Shadcn UI
A powerful tree table component for Shadcn UI that combines hierarchical tree navigation with table columns, inspired by shadcn-tree-view.
demo.mp4 |
This component extends the original shadcn-tree-view with the following enhancements:
- π Table Layout: Display tree items in a multi-column table format with resizable columns
- π±οΈ Drag Handle Support: Notion-style drag handles for precise row reordering
- π¨ Notion-style Design: Beautiful dark theme with smooth hover and selection states
- π§ Advanced Customization: Full control over column rendering with
renderItemprop - π Precise Spacing Control: Fixed spacing calculations for perfect column alignment
- π Component Separation: Clean separation between
TreeView(base) andTreeTable(enhanced) components - π¦ Exportable Components: Internal components exported for maximum flexibility
- Expand, collapse, and select items
- Multi-column table layout with resizable columns
- Drag handle support (Notion-style)
- Custom item renderer with full control over column content
- Drag & drop support
- Disabled state
- Notion-style dark theme
- Precise spacing and alignment control
- Custom icons per item (default, open, selected)
- Default node & leaf icons per tree view
- Action buttons (e.g. a button to add a new item)
- Click handlers per tree item and per the entire tree view
npx shadcn add "https://raw.githubusercontent.com/patricksclin/shadcn-tree-table/main/schema.json"import { TreeTable, type TreeTableItem } from '@/components/ui/tree-table'
// ... data definition ...
// Standard dragging (entire row)
<TreeTable data={data} />
// Dragging via handle only (Notion-style)
<TreeTable data={data} enableDragHandle={true} />The TreeTable component uses the renderItem prop to render custom table rows:
const renderItem = ({
item,
level,
isSelected,
}: TreeRenderItemParams) => {
const extended = item as TreeTableItem
return (
<div className="grid text-sm" style={rowStyle}>
<div className="flex items-center">
<span>{extended.name}</span>
</div>
<div className="px-3">
<span>{extended.type ?? 'β'}</span>
</div>
{/* More columns... */}
</div>
)
}
<TreeTable data={data} renderItem={renderItem} />You can also use the base TreeView component for simple tree navigation:
import { TreeView, type TreeDataItem } from '@/components/ui/tree-view'
const data: TreeDataItem[] = [
{
id: '1',
name: 'Item 1',
children: [
{
id: '2',
name: 'Item 1.1',
children: [
{
id: '3',
name: 'Item 1.1.1',
},
{
id: '4',
name: 'Item 1.1.2',
},
],
},
{
id: '5',
name: 'Item 1.2 (disabled)',
disabled: true,
},
],
},
{
id: '6',
name: 'Item 2 (draggable)',
draggable: true,
},
]
<TreeView data={data} />This project provides two main components:
TreeView(src/tree-view.tsx): Base tree component with expand/collapse, selection, and drag & dropTreeTable(demo/components/tree-table.tsx): Enhanced component that adds table layout and column management
The TreeTable component:
- Extends
TreeViewfunctionality - Uses custom
AccordionTriggerandTreeLeafcomponents for precise spacing - Implements column resizing and layout management
- Provides Notion-style theming
type TreeTableProps = {
data: TreeTableItem[]
enableDragHandle?: boolean // default: false
}type TreeRenderItemParams = {
item: TreeDataItem
level: number
isLeaf: boolean
isSelected: boolean
isOpen?: boolean
hasChildren: boolean
}
type TreeProps = React.HTMLAttributes<HTMLDivElement> & {
data: TreeDataItem[] | TreeDataItem
initialSelectedItemId?: string
onSelectChange?: (item: TreeDataItem | undefined) => void
expandAll?: boolean
defaultNodeIcon?: React.ComponentType<{ className?: string }>
defaultLeafIcon?: React.ComponentType<{ className?: string }>
onDocumentDrag?: (sourceItem: TreeDataItem, targetItem: TreeDataItem) => void
renderItem?: (params: TreeRenderItemParams) => React.ReactNode
enableDragHandle?: boolean
}interface TreeTableItem extends TreeDataItem {
children?: TreeTableItem[]
type?: string
owner?: string
status?: string
updatedAt?: string
}interface TreeDataItem {
id: string
name: string
icon?: React.ComponentType<{ className?: string }>
selectedIcon?: React.ComponentType<{ className?: string }>
openIcon?: React.ComponentType<{ className?: string }>
children?: TreeDataItem[]
actions?: React.ReactNode
onClick?: () => void
draggable?: boolean
droppable?: boolean
disabled?: boolean
className?: string
}# Install dependencies
pnpm install
# Run demo
cd demo
pnpm dev
# Create schema for tree-table
node scripts/create-schema-tree-table.js- Inspired by shadcn-tree-view by romatallinn
- Based on implementation by WangLarry and bytechase
Licensed under the MIT license, see LICENSE.