Brik Design System
Components

Data section

Page-side wrapper for a titled block of read-mode data. Pairs heading + subtitle + actions slot.

DataSection is the page analog to SheetSection. Where SheetSection uses an uppercase label heading appropriate inside a sheet, DataSection uses a real section title in the page outline. Pairs a heading-tier title with optional subtitle + actions slot (typically a [View]/[Edit] toggle), then yields the body to whatever composes inside — usually a <FieldGrid> of <Field>s.

Use it for

  • Read-mode page sections on detail views (Identity / Brand / Services / Locations on a company page)
  • Settings page sections with a per-section View/Edit toggle
  • Any page-level grouping where the section title is part of the page outline

For Sheet body sections, use SheetSection. For tabular data inside a section, compose a Table inside DataSection's body.

Import

import { DataSection } from '@brikdesigns/bds';

Variants

Title only

<DataSection title="Identity">
  <FieldGrid columns={2}>
    <Field label="Business Name">Brik Designs</Field>
    <Field label="Industry">Design Services</Field>
  </FieldGrid>
</DataSection>

Title + subtitle

<DataSection
  title="Brand Voice"
  subtitle="Confident, direct, occasionally playful. Never corporate."
>
  <Field label="Approved CTAs">
    <BulletList items={['Book a consultation', 'Start your project']} />
  </Field>
</DataSection>

With actions

The canonical Read-Mode Page composition — each section has a [View] [Edit] button group in the actions slot.

<DataSection
  title="Identity"
  actions={
    <ButtonGroup>
      <Button size="sm" variant="secondary" onClick={openInViewMode}>View</Button>
      <Button size="sm" variant="secondary" onClick={openInEditMode}>Edit</Button>
    </ButtonGroup>
  }
>
  <FieldGrid columns={2}>
    <Field label="Business Name">{client.name}</Field>
    <Field label="Industry">{client.industry}</Field>
    <Field label="Care Philosophy">
      <p>{client.carePhilosophy}</p>
    </Field>
    <Field label="Secondary Categories">
      <BulletList items={client.secondaryCategories} />
    </Field>
  </FieldGrid>
</DataSection>

Single-button actions

<DataSection
  title="Linked Accounts"
  actions={<Button size="sm" variant="primary">Connect</Button>}
>
  ...
</DataSection>

Title element override

Default title renders as <h2> — the common case is one DataSection sibling of the page's <h1>. Use titleAs="h3" only when nested under an existing <h2>.

<DataSection title="Service line health" titleAs="h3">
  ...
</DataSection>

Pattern: read-mode page

Consecutive DataSections show a divider automatically — the sibling combinator handles it. Don't place a <Divider /> between DataSections manually.

<DataSection title="Identity" actions={<ViewEditToggle ... />}>
  <FieldGrid columns={2}>
    <Field label="Business Name">{client.name}</Field>
    <Field label="Industry">{client.industry}</Field>
  </FieldGrid>
</DataSection>

<DataSection title="Locations" actions={<ViewEditToggle ... />}>
  <FieldGrid columns={3}>
    {locations.map((l) => <Field key={l.id} label={l.name}>{l.address}</Field>)}
  </FieldGrid>
</DataSection>

<DataSection title="Services" actions={<ViewEditToggle ... />}>
  <FieldGrid columns={2}>
    <Field label="Care Philosophy">
      <p>{client.carePhilosophy}</p>
    </Field>
    <Field label="Secondary Categories">
      <BulletList items={client.secondaryCategories} />
    </Field>
  </FieldGrid>
</DataSection>

Rules

Don't use DataSection inside a Sheet. Use SheetSection there — the two are siblings, not substitutes. DataSection's title is part of the page outline; SheetSection's heading is an uppercase label inside the sheet.

  • title is a real heading. Default <h2>. It IS part of the page outline. Use titleAs="h3" only when nested under an <h2>.
  • Title ≠ heading. The BEM class is __title (role); the HTML element (h2 / h3) is picked by outline position, not by the class name.
  • actions is a slot, not a label. Put a <ButtonGroup> or <Button> in it.
  • Don't nest DataSection inside DataSection. Use Field or FieldGrid inside one section instead.
  • Empty per-field content is a Field concern. Field renders "Not set" inline when its children are empty — don't hand-roll a placeholder inside DataSection.

When not to use

  • Don't use DataSection for non-page-level sections — the heading is part of the page outline; misuse pollutes the outline.
  • Don't use DataSection without a title. The component's job is "titled section" — if you need a wrapper without title semantics, use a plain <section> or Card.

Accessibility

  • Renders a <section> with the title as <h2> (or <h3>) — proper landmark + outline.
  • Subtitle renders as a <p> directly below the heading.
  • Actions slot keeps its own semantics (Button is a button, link is a link).
  • Auto-divider between consecutive sections is border-top: var(--border-width-sm) solid var(--border-muted) — visual only, not announced.

API

PropTypeDefault
titlestring
subtitleReactNode
actionsReactNode
childrenReactNode
spacing'md' | 'lg''lg'
titleAs'h2' | 'h3''h2'

Plus standard <section> HTML attributes (excluding title).

On this page