Expandable Data List
Data Display
Layout
Grid-based master-detail list with expandable child rows, search functionality, and independent parent/child column configurations.
Preview
Click on any row to expand and see child details. Use search to filter across all data.
Owner
Project
Tasks
Due Date
Status
OC
Olivia ChenMarketing Strategy
12
Jan 15, 2024
Completed
PS
Priya SharmaProduct Launch
24
Jan 14, 2024
In Progress
Common Use Cases
Where to use the Expandable Data List
- →Project Tasks: Projects with nested tasks and subtasks
- →Team Workloads: Team members with assigned task breakdowns
- →Sprint Planning: Sprints with user stories and story points
- →Time Tracking: Projects with logged time entries
- →Goal Progress: Quarterly goals with milestone breakdowns
Props
ExpandableDataList component API reference
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | — | Array of parent row objects (required) |
columns | Column[] | — | Parent column configuration with key, header, width, and render function (required) |
childKey | string | 'children' | Key name for child data in parent objects |
childColumns | Column[] | — | Child column configuration (independent from parent columns) |
rowHeight | number | — | Height of parent rows in pixels |
childRowHeight | number | — | Height of child rows in pixels |
showSearch | boolean | true | Enable/disable search functionality |
searchPlaceholder | string | — | Placeholder text for search input |
onRowClick | (row: T) => void | — | Callback for parent row clicks |
onChildRowClick | (child: C, parent: T) => void | — | Callback for child row clicks |
className | string | — | Additional CSS classes |
Usage
Import and implementation example
import { ExpandableDataList } from '@/blocks/data-display/expandable-data-list'
const projectData = [
{
id: 'prj_001',
owner: { name: 'Olivia Chen' },
project: 'Marketing Strategy',
tasks: 12,
status: 'completed',
children: [
{ id: 'tsk_001', description: 'Define target audience', hours: 4.0, status: 'completed' },
{ id: 'tsk_002', description: 'Competitor analysis', hours: 6.0, status: 'completed' },
]
},
]
const parentColumns = [
{
key: 'owner',
header: 'Owner',
width: '200px',
render: (value) => (
<div className="flex items-center gap-3">
<Avatar name={value.name} />
<span>{value.name}</span>
</div>
)
},
{ key: 'project', header: 'Project', width: '1fr' },
{ key: 'tasks', header: 'Tasks', width: '100px' },
{ key: 'status', header: 'Status', width: '140px', render: (value) => <StatusBadge status={value} /> }
]
const childColumns = [
{ key: 'description', header: 'Task', width: '1fr' },
{ key: 'hours', header: 'Hours', width: '100px', render: (v) => `${v.toFixed(1)}h` },
{ key: 'status', header: 'Status', width: '120px', render: (value) => <StatusBadge status={value} /> },
]
export default function Example() {
return (
<ExpandableDataList
data={projectData}
columns={parentColumns}
childKey="children"
childColumns={childColumns}
rowHeight={64}
childRowHeight={52}
searchPlaceholder="Search projects, tasks..."
onRowClick={(row) => console.log('Parent:', row.id)}
onChildRowClick={(child, parent) => console.log('Child:', child.id)}
/>
)
}Features
Built-in functionality
- Flexible grid layout: Custom column widths with CSS Grid
- Independent columns: Parent and child rows can have different column configurations
- Built-in search: Search functionality across all data
- Custom renderers: Custom cell renderers for badges, avatars, and actions
- Click handlers: Separate click handlers for parent and child rows
- Smooth animations: Expandable/collapsible child rows with transitions
- Dark mode: Full dark mode support
Accessibility
Accessibility considerations
ARIA Attributes
Uses semantic table elementsExpandable rows have aria-expanded stateSearch input is properly labeledKeyboard Navigation
| Key | Action |
|---|---|
| Tab | Navigate between rows |
| Enter / Space | Toggle row expansion |
| Arrow Up/Down | Navigate between rows |
Notes
- Focus management when expanding/collapsing
- Search results announced to screen readers
- Child rows inherit parent context