Skip to content

Badges, Chips & Banners

Three families for status communication:

FamilyUse
StatusBadgeSmall status pill — entity status, severity, count
CdxChipFilter / token chip — single-line, dismissible, selectable
BannerFull-width status notice — page-level alerts, success / warning / critical / info
UnderConstructionOverlayApp-wide flagged-feature banner

StatusBadge

Named StatusBadge (not Badge) to avoid collision with Flutter's built-in Badge widget.

A configurable pill with shape, size, color scheme, and optional icon / child / onTap / tooltip.

Color schemes

StatusBadgeColorScheme is a sealed strategy. Use a named factory or construct one inline.

dart
StatusBadge.primary(label: 'Active', icon: FluentIcons.checkmark_24_regular)
StatusBadge.secondary(label: 'Pending')
StatusBadge.tertiary(label: 'Review')
StatusBadge.error(label: 'Failed', icon: FluentIcons.error_circle_24_regular)
StatusBadge.neutral(label: 'Archived')

// Tinted around any base color (subtle bg + faint border + full-strength fg)
StatusBadge.tinted(
  CdxConfig.of(context).warningOf(Theme.of(context).colorScheme),
  label: 'Expiring soon',
  shape: StatusBadgeShape.pill,
)

// Compact tinted — for inline metadata (BETA, v0.1.2, tags)
StatusBadge.compact(
  CdxConfig.of(context).infoOf(Theme.of(context).colorScheme),
  label: 'BETA',
)

// Count pill — neutral pill with the count as label
StatusBadge.count(unreadCount)

Shapes

dart
enum StatusBadgeShape { rectangle, pill, rounded }
ShapeRadius
rectanglecontrolBorderRadius (4)
pill999 (fully rounded)
roundedcontainerBorderRadius (8)

Sizes

dart
enum StatusBadgeSize { small, medium }
SizeText styleIcon
smalllabelSmall w60016 px
mediumbodySmall w50018 px

Custom colors

For a one-off palette, build a StatusBadgeColors:

dart
StatusBadge(
  label: 'Custom',
  colorScheme: const StatusBadgeColorScheme.explicit(StatusBadgeColors(
    background: Color(0xfff3e8ff),
    foreground: Color(0xff6d28d9),
    border: Color(0xffa78bfa),
  )),
)

CdxChip

The canonical filter / token chip across CDX. Two recurring shapes covered by one widget:

dart
// Filter chip
CdxChip(
  label: 'Active',
  icon: FluentIcons.checkmark_24_regular,
  selected: filter.activeOnly,
  onTap: () => filter.toggleActive(),
)

// Dismissible token (pairs the chip with CdxDismissAffordance internally)
CdxChip(
  label: assignee.name,
  onDeleted: () => removeAssignee(assignee),
  deleteTooltip: 'Remove ${assignee.name}',
)

// Combined — selectable AND dismissible
CdxChip(
  label: 'Urgent',
  selected: tag.selected,
  onTap: () => toggleTag(tag),
  onDeleted: () => removeTag(tag),
)

Density

dart
enum CdxChipSize { small, regular, compact }
SizeVerticalText styleUse
smalltightlabelSmallInline metadata, dense lists (default)
regularroomierlabelMediumStandard chip rows that need more breathing room
compactaligns to compactControlSize (32 px)labelMediumWhen chips share a row with compact form controls

Rich labels

For mixed-style spans (bold field name + value, async-loading entity name), pass a labelBuilder:

dart
CdxChip(
  label: '...',                          // ignored when labelBuilder is set
  labelBuilder: (context) => Text.rich(TextSpan(children: [
    const TextSpan(text: 'Site: ', style: TextStyle(fontWeight: FontWeight.w600)),
    TextSpan(text: site.name),
  ])),
)

Full-width status banner card. Five named factories cover the standard severities; pass backgroundColor / foregroundColor to override.

dart
Banner.warning(
  message: 'Equipment requires calibration before next batch.',
  trailing: TextButton(onPressed: _openCalibration, child: const Text('Calibrate')),
)

Banner.critical(message: 'Unable to reach inventory service.')
Banner.success(message: 'Batch released successfully.')
Banner.info(message: 'New comments on this lot.')
Banner.neutral(message: 'Audit completed last week.')

BannerType palette pulls from CdxConfig:

TypeBackgroundForeground
warningwarningContainerOfonWarningContainerOf
criticalcriticalContainerOf (= errorContainer)onCriticalContainerOf
successsuccessContainerOfonSuccessContainerOf
infosecondaryContaineronSecondaryContainer
neutralneutralContainerOfonNeutralContainerOf

UnderConstructionOverlay

App-wide registry for "under construction" banners on partially-built pages. Bootstrap toggles flags; child widgets wrap themselves and render the banner only when enabled.

dart
// At app startup
UnderConstructionController.enable('settings.reports', message: 'Custom reports launching next sprint.');
UnderConstructionController.disable('inbox.batch-actions');

// In the widget tree
UnderConstructionOverlay(
  id: 'settings.reports',
  child: ReportsSettingsPage(),
)

When the controller has no entry for id, the banner is hidden and the child renders directly.

ParamDefault
idrequired — controller key
defaultMessage'Under construction'
defaultSubtitle"We're still polishing this area. Check back soon."
iconFluentIcons.wrench_24_regular
expandChildtrue (Expanded(child))
  • Theming — status palette resolvers
  • ButtonsButton.toggle is a chip-like alternative for boolean filters
  • Cards — embed StatusBadge in CompactCard.content