FSAI Design System
Components

Card

Compound section container for settings, detail summaries, editable groups, and structured dashboard content.

Overview

Card is the shared section container used across the brand dashboard for:

  • settings sections
  • account and workspace panels
  • editable grouped content
  • summary blocks with actions

It is a compound component with a small but important layout API:

  • Card
  • Card.Header
  • Card.Body
  • Card.Block
  • Card.Footer

In practice, Card is one of the main structural building blocks for dashboard pages.

Basic Usage

<Card>
  <Card.Header>
    <Card.Header.Left>
      <Card.Header.Title>Preferences</Card.Header.Title>
      <Card.Header.Subtitle>
        Adjust the dashboard to your preferences
      </Card.Header.Subtitle>
    </Card.Header.Left>
  </Card.Header>

  <Card.Body>
    <Card.Block>{/* card content */}</Card.Block>
  </Card.Body>
</Card>

This is the standard settings-section pattern used throughout the brand dashboard.

Compound API

Root

PartPurpose
CardRoot card container. Supports as="div" or as="section".
PartPurpose
Card.HeaderTop row for title area and actions.
Card.Header.LeftLeft-side title/subtitle stack.
Card.Header.RightRight-side actions or controls.
Card.Header.TitleStandard card title.
Card.Header.SubtitleStandard subtitle text.
Card.Header.EditActionOpinionated edit/save/cancel control for editable cards.
PartPurpose
Card.BodyMain vertical content area.
Card.FooterFooter row for actions.
Card.TitleSame title component, usable outside the header.
Card.SubtitleSame subtitle component, usable outside the header.

Block Rows

PartPurpose
Card.BlockInner surface for grouped rows or nested content.
Card.Block.LeftMain content region inside a block.
Card.Block.RightSecondary action or metadata region inside a block.

Editable Card Header

Card.Header.EditAction is one of the most important built-in conveniences.

<Card.Header>
  <Card.Header.Left>
    <Card.Header.Title>Domain Settings</Card.Header.Title>
  </Card.Header.Left>
  <Card.Header.Right>
    <Card.Header.EditAction
      isEditing={isEditing}
      onEdit={() => setIsEditing(true)}
      onCancel={() => setIsEditing(false)}
      onSave={handleSave}
      isLoading={isSaving}
    />
  </Card.Header.Right>
</Card.Header>

When onSave is omitted, the save button becomes type="submit", which is useful when the card header controls a surrounding form.

Block Layout Pattern

Card.Block is commonly used for row-style content with a left main region and right action/meta region.

<Card.Block>
  <Card.Block.Left>
    <div>
      <p className="font-medium text-strong">Acme Brand</p>
      <p className="text-subtle text-md">workspace.acme.com</p>
    </div>
  </Card.Block.Left>
  <Card.Block.Right>
    <Button role="button" size="sm" variant="secondary">
      Manage
    </Button>
  </Card.Block.Right>
</Card.Block>

Card.Block changes its internal layout when Card.Block.Left and Card.Block.Right are present, so those slots are worth using rather than rebuilding the row pattern manually each time.

Use Card.Footer for bottom-aligned card actions:

<Card.Footer>
  <Button role="button" variant="secondary">
    Cancel
  </Button>
  <Button role="button" variant="primary">
    Save
  </Button>
</Card.Footer>

Props

Card

PropTypeDefaultDescription
as'div' | 'section''div'Root element type.
classNamestringAdditional root classes.
...htmlPropsHTMLAttributes<HTMLElement>Standard element attributes.

Card.Body

PropTypeDefaultDescription
classNamestringAdditional body classes.
childrenReactNodeRequired body content.

Card.Block

PropTypeDefaultDescription
classNamestringAdditional block classes.
onClick() => voidAdds clickable row behavior and hover styling.
...htmlPropsHTMLAttributes<HTMLDivElement>Standard block props.

Card.Header.EditAction

PropTypeDefaultDescription
isEditingbooleanRequired. Whether the card is in edit mode.
onEdit() => voidRequired. Starts editing.
onCancel() => voidRequired. Cancels editing.
onSave() => voidOptional imperative save handler.
submitLabelstring'Save Changes'Save button label.
isLoadingbooleanLoading state for the save action.
disabledbooleanDisables saving.

Brand Dashboard Usage Patterns

Representative usages:

PatternPathNotes
Settings section cardfsai/apps/brand-dashboard/src/pages/OrganizationSettings/OrganisationSettings.components.tsxCanonical header + edit action + body + block row composition.
Repeated section cardsfsai/apps/brand-dashboard/src/pages/OrganizationSettings/OrganizationSettingsTeam/OrganizationSettingsTeam.tsxMultiple cards used as page sections.
Billing and admin listsfsai/apps/brand-dashboard/src/pages/BillingManagement/BillingManagement.components.tsxCards containing repeated block rows and settings actions.
Footer action cardfsai/apps/brand-dashboard/src/pages/Account/AccountAssociatedOrganizations/AccountAssociatedOrganizations.tsxUses Card.Footer for end-of-card actions.
Subsection headings in bodyfsai/apps/brand-dashboard/src/pages/Account/AccountEvents/AccountEvents.tsxUses Card.Title inside the body, not just in the header.
Dense analytics layoutfsai/apps/brand-dashboard/src/pages/Socials/PostComposer/components/PostAnalyticsContent.tsxOverrides Card.Body spacing for a denser content layout.
Minimal header cardfsai/apps/brand-dashboard/src/components/AgentSalesAssignabilityCard/AgentSalesAssignabilityCard.tsxShows that the header can be simpler than title/subtitle/action.

Important Conventions

  • Card is often the top-level section container on a dashboard page, not just a decorative wrapper.
  • Card.Block.Left and Card.Block.Right are important because Card.Block uses those slots to switch into its standard row layout.
  • Card.Block with onClick gets pointer and hover styling, but you still need to think about keyboard accessibility if the block acts like a navigation or selection surface.
  • Card.Header.EditAction is designed to work well with editable settings cards and form-backed save flows.
  • Card.Title and Card.Subtitle are reusable outside the header, but they still render heading tags, so use them intentionally.
  • Some files in the repo define their own local Card components or use unrelated Card terminology, so make sure you are actually using @fsai/shared-ui when following this API.

Guidelines

  • Do use Card as the default section shell for settings and grouped dashboard content
  • Do use Card.Block for repeated inner rows or grouped sub-surfaces
  • Do use Card.Header.EditAction for standard edit/save/cancel flows
  • Do use as="section" when the card should be a meaningful page section
  • Don't rebuild custom section shells when Card already matches the dashboard pattern

On this page