Components

Content Block

ContentBlock is a container component with a header section for titles and actions, and a content area for displaying information with optional loading and collapsible states.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Volume Breakdown - Outbound"
subtitle="View a breakdown of your outbound volume."
titleAs="h2"
subtitleAs="h3"
>
<Text.SmallBodyCopy>
Here is some content inside the content block.
</Text.SmallBodyCopy>
</ContentBlock>

Properties

Overview

ContentBlock is a structured component that provides a consistent layout for content sections. It includes a header area with title, subtitle, and optional action buttons, followed by a content area. The component is built on top of Container and renders as a semantic section element.

Recipes

Basic content block

The simplest use case includes a title, subtitle, and content.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Analytics Dashboard"
subtitle="Overview of your account performance"
titleAs="h2"
subtitleAs="h3"
>
<Box>
<Text.SmallBodyCopy>
Your analytics data shows positive trends this month.
</Text.SmallBodyCopy>
</Box>
</ContentBlock>

Content block with header actions

Add action buttons or other interactive elements to the header using the headerActions prop.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Volume Breakdown - Outbound"
subtitle="View a breakdown of your outbound volume."
titleAs="h2"
subtitleAs="h3"
headerActions={
<Button appearance="secondary">
<Icon name="square-round-arrow-up-right-outline" mr={200} />
Export
</Button>
}
>
<Text.SmallBodyCopy>
Here is some content inside the content block.
</Text.SmallBodyCopy>
</ContentBlock>

Loading state

Use the isLoading prop to display a loader while content is being fetched.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Loading Data"
subtitle="Please wait while we fetch your information"
titleAs="h2"
subtitleAs="h3"
isLoading={true}
>
<Text.SmallBodyCopy>
This content will not be visible while loading.
</Text.SmallBodyCopy>
</ContentBlock>

Content block with custom content styling

Use the contentProps to customize the content area styling, such as padding or background color.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Customized Content Area"
subtitle="This content block has custom styling applied"
titleAs="h2"
subtitleAs="h3"
contentProps={{
p: 500,
backgroundColor: "neutral.50"
}}
>
<Box>
<Text.SmallBodyCopy>
The content area has custom padding and background.
</Text.SmallBodyCopy>
</Box>
</ContentBlock>

Content block with rich content

The content area can contain any React components, including lists, charts, or forms.

import { ContentBlock,List,ListItem,ListItemContent } from '@sproutsocial/racine'
<ContentBlock
title="Recent Activity"
subtitle="Your latest notifications and updates"
titleAs="h2"
subtitleAs="h3"
>
<List>
<ListItem>
<ListItemContent
iconName="bell-outline"
text="New message received"
aside="2 min ago"
/>
</ListItem>
<ListItem>
<ListItemContent
iconName="circle-check-outline"
text="Report completed"
aside="1 hour ago"
/>
</ListItem>
<ListItem>
<ListItemContent
iconName="circle-exclamation-outline"
text="Action required"
aside="3 hours ago"
/>
</ListItem>
</List>
</ContentBlock>

Multiple header actions

Combine multiple buttons or controls in the header actions area.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Team Dashboard"
subtitle="Manage your team and permissions"
titleAs="h2"
subtitleAs="h3"
headerActions={
<Box display="flex" gap={300}>
<Button appearance="secondary">
<Icon name="filter-outline" mr={200} />
Filter
</Button>
<Button appearance="primary">
<Icon name="plus-outline" mr={200} />
Add Member
</Button>
</Box>
}
>
<Text.SmallBodyCopy>
Team management content goes here.
</Text.SmallBodyCopy>
</ContentBlock>

Collapsible content block

Use isCollapsible to enable collapse/expand behavior. Defaults to open.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Collapsible Section"
subtitle="Click the chevron to toggle"
titleAs="h2"
subtitleAs="h3"
isCollapsible
>
<Text.SmallBodyCopy>
This content can be collapsed and expanded.
</Text.SmallBodyCopy>
</ContentBlock>

Collapsible content block (default closed)

Use defaultOpen={false} to start collapsed.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Initially Collapsed"
subtitle="Expand to see the content"
titleAs="h2"
subtitleAs="h3"
isCollapsible
defaultOpen={false}
>
<Text.SmallBodyCopy>
This content starts hidden.
</Text.SmallBodyCopy>
</ContentBlock>

Collapsible with header actions

Header actions render alongside the trigger and do not toggle the collapse.

import { ContentBlock } from '@sproutsocial/racine'
<ContentBlock
title="Volume Breakdown"
subtitle="Outbound message volume"
titleAs="h2"
subtitleAs="h3"
isCollapsible
headerActions={
<Button appearance="secondary">
<Icon name="square-round-arrow-up-right-outline" mr={200} />
Export
</Button>
}
>
<Text.SmallBodyCopy>
Volume data goes here.
</Text.SmallBodyCopy>
</ContentBlock>

Controlled collapsible

Use isOpen and onOpenChange for controlled mode.

import { ContentBlock } from '@sproutsocial/racine'
function ControlledExample() {
const [open, setOpen] = React.useState(true);
return (
<Box>
<Button onClick={() => setOpen(!open)} mb={400}>
{open ? 'Collapse' : 'Expand'} externally
</Button>
<ContentBlock
title="Controlled Section"
subtitle="Controlled by external button"
titleAs="h2"
subtitleAs="h3"
isCollapsible
isOpen={open}
onOpenChange={setOpen}
>
<Text.SmallBodyCopy>
Controlled content.
</Text.SmallBodyCopy>
</ContentBlock>
</Box>
);
}

Semantic heading levels

Use the titleAs and subtitleAs props to control the semantic heading level based on your page structure.

import { ContentBlock } from '@sproutsocial/racine'
<Box>
<ContentBlock
title="Main Section"
subtitle="This uses h1 and h2"
titleAs="h1"
subtitleAs="h2"
content={
<ContentBlock
title="Subsection"
subtitle="This uses h3 and h4"
titleAs="h3"
subtitleAs="h4"
/>
}
>
<Text.SmallBodyCopy>
Nested content with proper heading hierarchy.
</Text.SmallBodyCopy>
</ContentBlock>
</Box>

Accessibility

  • ContentBlock renders as a semantic section element for proper document structure
  • Use titleAs and subtitleAs props to maintain proper heading hierarchy (h1-h6)
  • The component handles loading states with visual indicators
  • Ensure action buttons in headerActions have appropriate labels
  • When collapsible, the trigger has proper aria-expanded state and header actions remain independently focusable

Best Practices

  • Always provide meaningful titles and subtitles that describe the content
  • Use appropriate heading levels that fit within your page's heading hierarchy
  • Keep header actions concise and relevant to the content block
  • Use the loading state for asynchronous content to provide feedback to users