Skip to main content

Documentation Index

Fetch the complete documentation index at: https://grantmaster.dev/llms.txt

Use this file to discover all available pages before exploring further.

UI Pattern Selection Guide

Quick-reference for choosing the right layout primitive. This is a routing document — for component APIs and detailed rules, follow the See also links in each pattern card.

Decision Flowchart

Comparison Table

PatternBest ForAvoid WhenScreen CoveragePage Context?Component
Bento GridKPI dashboards, role-based widget layoutsSingle-purpose pages, linear contentFull pageN/A (is the page)WidgetGrid
Kanban BoardPipeline views, stage-based workflows, status trackingStatic lists, non-sequential data, dashboardsFull pageN/A (is the page)KanbanBoard
WizardOnboarding, grant applications, multi-step setup< 3 steps or independent fieldsFull pageNo — replaces pageTenantOnboardingWizard, BaseStep
Full-Screen ModalComplex editing, multi-section forms, document reviewSimple forms (≤ 5 fields)~96vw overlayNo — covers pageAppModal size full
DrawerRecord details, settings panels, read-heavy inspectionComplex editing, multi-step flowsSide panel (28rem) / bottom sheetYes — page visibleAppDrawer
PopoverTooltips, contextual help, small menusForms, detail views, anything > 2 actionsSmall floating panelYes — inlinePopover

Pattern Cards

Bento Grid

Use when:
  • Building a role-based dashboard with multiple independent widgets
  • Users need to customise, reorder, or hide content blocks
  • Displaying KPIs, charts, and activity feeds in a scannable layout
  • Content is widget-sized and does not require linear reading order
Don’t use when:
  • The page has a single purpose or linear narrative
  • Content is a form, table, or detail view
Component:
src/components/widgets/WidgetGrid.tsx        — 12-column CSS Grid with dnd-kit drag-and-drop
src/components/DynamicDashboard.tsx           — role-based dashboard shell that consumes WidgetGrid
src/components/widgets/WidgetContainer.tsx    — per-widget wrapper (loading, error, settings)
See also: Widget System — sizes, registry, role templates, rendering

Kanban Board

Use when:
  • Items move through discrete stages or statuses (pipelines, approval queues)
  • Users need spatial awareness of distribution across stages
  • Drag-and-drop stage transitions are the primary interaction
  • The data is naturally columnar by status (e.g. grant pipeline, task board)
Don’t use when:
  • Items don’t have a clear stage/status progression (use a table or Bento Grid)
  • The primary task is data entry or editing (use a form page or modal)
  • There are more than ~7 columns — horizontal scrolling degrades usability
Component:
import { KanbanBoard } from '@/components/ui/KanbanBoard';

<KanbanBoard
  columns={[
    { id: 'identified', label: 'Identified', color: 'bg-slate-500' },
    { id: 'applied', label: 'Applied', color: 'bg-primary-500' },
    { id: 'awarded', label: 'Awarded', color: 'bg-emerald-500' },
  ]}
  items={grants}
  getItemColumn={(grant) => grant.stage}
  getItemId={(grant) => grant.id}
  renderCard={(grant) => <GrantCard grant={grant} />}
  onStageChange={(itemId, fromCol, toCol) => moveGrant(itemId, toCol)}
/>
See also: The component is fully generic — see src/components/ui/KanbanBoard.tsx JSDoc for the full props interface.

Wizard

Use when:
  • The task has 3+ sequential steps with validation between them
  • Progressive disclosure improves comprehension (onboarding, applications)
  • Steps have dependencies — later steps depend on earlier input
  • The user should not see the underlying page during the flow
Don’t use when:
  • Fields are independent and can be filled in any order (use a page or modal)
  • There are fewer than 3 steps (use a standard modal or page form)
Component:
src/features/onboarding/components/pages/TenantOnboardingWizard.tsx  — 8-step admin onboarding
src/components/ApplicationWizard.tsx                                  — grant application (2-pane)
src/components/OnboardingFlow.tsx                                     — 4-step org setup
src/features/onboarding/components/BaseStep.tsx                       — shared step wrapper
See also: CRUD Interaction Matrix — field-count thresholds for modal vs page vs wizard

Full-Screen Modal

Use when:
  • Editing a complex entity with multiple sections or nested sub-entities
  • The user needs full focus without page distractions
  • The form exceeds what fits in a standard lg or xl modal
  • Document review or side-by-side comparison layouts
Don’t use when:
  • The form has ≤ 5 fields (use a standard AppModal)
  • The user needs to reference the page behind (use a Drawer)
  • The task is a multi-step workflow (use a Wizard)
Component:
import { AppModal } from '@/components/ui/modal-system/AppModal';

<AppModal open={open} onOpenChange={setOpen} title="Edit Grant" size="full">
  {/* content */}
</AppModal>
See also: Modal System — all modal variants, sizes, header/footer/copy rules

Drawer

Use when:
  • Inspecting a record’s details while keeping the list or page visible
  • Settings or configuration panels that augment the current view
  • Read-heavy content where the user may return to the page frequently
  • Mobile: bottom sheet for quick actions or previews
Don’t use when:
  • The task requires full focus or complex form editing (use a full-screen modal)
  • The content is a multi-step workflow (use a Wizard)
  • The interaction is a simple confirmation (use ConfirmDialog)
Component:
import { AppDrawer } from '@/components/ui/modal-system/AppDrawer';

<AppDrawer open={open} onOpenChange={setOpen} title="Grant Details">
  {/* content */}
</AppDrawer>
Renders as a side panel (right, 28rem) on desktop and a bottom sheet with swipe-to-dismiss on mobile. See also: Modal System — drawer variant details, responsive behaviour

Popover

Use when:
  • Showing contextual help, definitions, or tooltips on hover/click
  • Small inline menus or date pickers
  • Non-blocking supplementary information
  • Content fits in a small floating panel (default w-72)
Don’t use when:
  • Content requires scrolling or has more than 2-3 actions (use a Drawer)
  • The user needs to fill a form (use a Modal)
  • Information is critical and must not be missed (use SurfaceNotice)
Component:
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover';
// For richer contextual cards:
import { ContextHoverCard } from '@/components/ui/ContextHoverCard';
See also: Design System — tooltip conventions, icon sizes

Cross-Reference Index

Existing DocPatterns Covered
CRUD Interaction MatrixModal vs Page vs Wizard (field-count rules)
Modal SystemFull-Screen Modal, Drawer, ConfirmDialog, DecisionDialog
Widget SystemBento Grid (sizes, registry, role templates)
Surface SystemPage sections, metric grids, toolbars, empty states
Design SystemTokens, buttons, cards, badges, animation rules