Files
Krow-workspace/.claude/agent-memory/ui-ux-design/component-patterns.md
Achintha Isuru 9039aa63d6 feat: add benefit history feature with lazy loading and pagination
- Implemented `getBenefitsHistory` method in `HomeRepository` to retrieve paginated benefit history.
- Enhanced `BenefitsOverviewCubit` to manage loading and displaying benefit history.
- Created `BenefitHistoryPage` for full-screen display of benefit history with infinite scroll support.
- Added `BenefitHistoryPreview` widget for expandable history preview in benefit cards.
- Introduced `BenefitHistoryRow` to display individual history records.
- Updated `BenefitsOverviewState` to include history management fields.
- Added new entities and use cases for handling benefit history.
- Created design system documentation for UI patterns and known gaps.
2026-03-18 17:21:30 -04:00

3.3 KiB

name, description, type
name description type
KROW Staff App Component Patterns Established UI patterns, widget conventions, and design decisions confirmed in the KROW staff app codebase project

Card Pattern (standard surface)

Cards use:

  • UiColors.cardViewBackground (white) background
  • Border.all(color: UiColors.border) outline
  • BorderRadius.circular(UiConstants.radiusBase) = 12dp
  • EdgeInsets.all(UiConstants.space4) = 16dp padding

Do NOT use UiColors.bgSecondary as card background — that is for toggles/headers inside cards.

Section Toggle / Expand-Collapse Header

Used for collapsible sections inside cards:

  • Background: UiColors.bgSecondary
  • Radius: UiConstants.radiusMd (6dp)
  • Height: minimum 48dp (touch target)
  • Label: UiTypography.titleUppercase3m.textSecondary for ALL-CAPS labels
  • Trailing: UiIcons.chevronDown animated 180° via AnimatedRotation, 200ms
  • Ripple: InkWell with borderRadius: UiConstants.radiusMd and splash UiColors.primary.withValues(alpha: 0.06)

Shimmer Loading Pattern

Use UiShimmer wrapper + UiShimmerLine / UiShimmerBox / UiShimmerCircle primitives.

  • Base color: UiColors.muted
  • Highlight: UiColors.background
  • For list content: 3 shimmer rows by default
  • Do NOT use fixed height containers for shimmer — let content flow

Status Badge (read-only, non-interactive)

Custom Container with pill shape:

  • borderRadius: UiConstants.radiusFull
  • padding: EdgeInsets.symmetric(horizontal: space2, vertical: 2)
  • Label style: UiTypography.footnote2b
  • Do NOT use the interactive UiChip widget for read-only display

Status color mapping:

  • ACTIVE: bg=tagActive, fg=textSuccess
  • PENDING: bg=tagPending, fg=textWarning
  • INACTIVE/ENDED: bg=tagFreeze, fg=textSecondary
  • ERROR: bg=tagError, fg=textError

Inline Error Banner (inside card)

NOT a full-page error — a compact container inside the widget:

  • bg: UiColors.tagError
  • radius: UiConstants.radiusMd
  • Icon: UiIcons.error at iconMd (20dp), color: UiColors.destructive
  • Title: body2m.textError
  • Retry link: body3r.primary with TextDecoration.underline

Inline Empty State (inside card)

NOT UiEmptyState widget (that is full-page). Use compact inline version:

  • Icon(UiIcons.clock, size: iconXl=32, color: UiColors.iconDisabled)
  • body2r.textSecondary label
  • EdgeInsets.symmetric(vertical: space6) padding

AnimatedSize for Expand/Collapse

AnimatedSize(
  duration: const Duration(milliseconds: 250),
  curve: Curves.easeInOut,
  child: isExpanded ? content : const SizedBox.shrink(),
)

Benefits Feature Structure

Legacy benefits: apps/mobile/legacy/legacy-staff-app/lib/features/profile/benefits/ V2 domain entity: apps/mobile/packages/domain/lib/src/entities/benefits/benefit.dart V2 history entity: needs creation at packages/domain/lib/src/entities/benefits/benefit_history.dart

Benefit history is lazy-loaded per card (not with the initial overview fetch). History state is cached in BLoC as Map<String, AsyncValue<List<BenefitHistory>>> keyed by benefitId.

Screen Page Pattern (overview pages)

Uses CustomScrollView with SliverList for header + SliverPadding wrapping SliverList.separated for content. Bottom padding on content sliver: EdgeInsets.fromLTRB(16, 16, 16, 120) to clear bottom nav bar.