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 Chen
Marketing Strategy
12
Jan 15, 2024
Completed
PS
Priya Sharma
Product 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

PropTypeDefaultDescription
dataT[]Array of parent row objects (required)
columnsColumn[]Parent column configuration with key, header, width, and render function (required)
childKeystring'children'Key name for child data in parent objects
childColumnsColumn[]Child column configuration (independent from parent columns)
rowHeightnumberHeight of parent rows in pixels
childRowHeightnumberHeight of child rows in pixels
showSearchbooleantrueEnable/disable search functionality
searchPlaceholderstringPlaceholder text for search input
onRowClick(row: T) => voidCallback for parent row clicks
onChildRowClick(child: C, parent: T) => voidCallback for child row clicks
classNamestringAdditional 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 labeled

Keyboard Navigation

KeyAction
TabNavigate between rows
Enter / SpaceToggle row expansion
Arrow Up/DownNavigate between rows

Notes

  • Focus management when expanding/collapsing
  • Search results announced to screen readers
  • Child rows inherit parent context