afv-library/skills/omnistudio-flexcard-generate/references/best-practices.md

12 KiB

FlexCard Best Practices

Layout Design Patterns

Single Card

Use for displaying summary information about a single record. Group related fields into logical sections.

┌──────────────────────────────────┐
│  Header: Record Name             │
├──────────────────────────────────┤
│  Section 1: Key Details          │
│  ┌────────────┬─────────────┐    │
│  │ Field A    │ Field B     │    │
│  │ Field C    │ Field D     │    │
│  └────────────┴─────────────┘    │
├──────────────────────────────────┤
│  Section 2: Status               │
│  ┌──────────────────────────┐    │
│  │ Status Badge  │ Date     │    │
│  └──────────────────────────┘    │
├──────────────────────────────────┤
│  [Action Button 1] [Action 2]   │
└──────────────────────────────────┘

Guidelines:

  • Limit to 8-10 fields per card to avoid information overload
  • Place the most important fields in the top section
  • Use consistent field alignment (label-left or label-top)
  • Group related fields in the same row when they share context

Card List

Use for displaying a collection of related records. Each card in the list renders from one item in the data source array.

┌──────────────────────────────────┐
│  Card 1: Record A                │
│  Field 1 | Field 2 | [Action]   │
├──────────────────────────────────┤
│  Card 2: Record B                │
│  Field 1 | Field 2 | [Action]   │
├──────────────────────────────────┤
│  Card 3: Record C                │
│  Field 1 | Field 2 | [Action]   │
└──────────────────────────────────┘
  Showing 1-3 of 15  [Next →]

Guidelines:

  • Keep each list card compact (3-5 fields maximum)
  • Include a clear identifier field (Name, Title, or ID) in each card
  • Add pagination when the data source can return more than 10 records
  • Use consistent card height to maintain visual rhythm
  • Provide a "View All" link when the list is truncated

Tabbed Card

Use when a single record has multiple contexts worth displaying. Each tab represents a different state with its own data source or field set.

┌──────────────────────────────────┐
│  [Tab 1: Overview] [Tab 2: History] [Tab 3: Related] │
├──────────────────────────────────┤
│  Tab 1 Content                   │
│  ┌──────────────────────────┐    │
│  │ Fields for this context  │    │
│  └──────────────────────────┘    │
└──────────────────────────────────┘

Guidelines:

  • Limit to 3-5 tabs to avoid horizontal overflow
  • Use concise tab labels (1-2 words)
  • Load non-active tab data lazily (on tab selection)
  • Mark the default active tab based on the most common use case

Flyout Card

Use for progressive disclosure: show a summary, then expand for details on demand.

┌──────────────────────────────────┐
│  Summary: Key Fields  [▼ More]   │
└──────────────────────────────────┘
       ↓ (on click)
┌──────────────────────────────────┐
│  Summary: Key Fields  [▲ Less]   │
├──────────────────────────────────┤
│  Detail Section                  │
│  Additional fields, history,     │
│  related records, etc.           │
└──────────────────────────────────┘

Guidelines:

  • Keep the summary to 2-3 fields that answer "what is this?"
  • Load flyout content on demand, not on initial card render
  • Provide a clear visual indicator for the expand/collapse action
  • Maintain the flyout state if the user scrolls away and returns

Data Source Optimization

Minimize IP Calls

  • Use a single IP that returns all required data rather than multiple IPs for individual fields
  • If the card has multiple data sources, ensure they do not query overlapping data
  • Cache IP responses where the data does not change frequently (use IP caching options)

Input Parameter Efficiency

  • Pass only the parameters the IP needs; do not forward the entire page context
  • Use {recordId} as the primary context parameter for record-level cards
  • Avoid passing large objects as input parameters; pass IDs and let the IP query

Response Structure

  • Design IP responses to match the FlexCard's field mapping structure directly
  • Avoid deep nesting in IP responses when the FlexCard only needs top-level fields
  • Use resultListPath to point directly to the array node in list-type cards

Error Handling in Data Sources

  • Configure a fallback state for when the IP returns an error
  • Set reasonable timeout values for data source calls
  • Log data source errors for debugging without exposing raw error messages to end users

Action Configuration

OmniScript Launch Actions

Consideration Guidance
Parameter mapping Map card data fields to OmniScript input fields explicitly
Pre-population Pass enough context for the OmniScript to pre-fill known values
Return handling Refresh the FlexCard data source after the OmniScript completes
Error states Handle the case where the OmniScript fails or is cancelled

Navigation Actions

Consideration Guidance
Record navigation Use {recordId} merge fields, not hardcoded IDs
URL navigation Use relative URLs for internal Salesforce navigation
External URLs Open in a new tab; warn users if leaving Salesforce
Conditional navigation Disable navigation buttons when the target is invalid

Action Button Placement

  • Place primary actions at the bottom of the card or in the card header
  • Limit to 2-3 actions per card; use a "More Actions" overflow menu for additional actions
  • Use descriptive button labels ("Submit Claim", not "Submit" or "Go")
  • Visually distinguish primary actions (filled button) from secondary actions (outline button)

SLDS Compliance for Styling

Required Practices

  • Use SLDS design tokens for all colors, spacing, font sizes, and border radii
  • Use slds-card or slds-tile patterns for card containers
  • Use slds-grid and slds-col for multi-column layouts within cards
  • Apply slds-text-heading_small and related text utilities for consistent typography

Color Usage

Correct:  Use SLDS token  →  var(--slds-g-color-brand-base-50)
Wrong:    Hardcoded hex    →  #0176d3
Wrong:    Hardcoded rgb    →  rgb(1, 118, 211)
  • Status indicators: use slds-badge with appropriate color variants
  • Background colors: use slds-box with slds-theme_shade or slds-theme_default
  • Text colors: rely on inherited SLDS text colors; override only when necessary

Spacing

  • Use SLDS spacing utilities: slds-m-top_small, slds-p-around_medium, etc.
  • Maintain consistent spacing between card sections (use slds-m-bottom_medium)
  • Do not use pixel values directly; map to the SLDS spacing scale

Dark Mode Compatibility

  • All colors must come from SLDS CSS custom properties (--slds-g-color-*)
  • Test card rendering in both light and dark modes
  • Avoid background images that only work on light backgrounds
  • Use currentColor for icon fills so they adapt to the text color

Accessibility Requirements

Interactive Elements

  • Every button must have an aria-label or visible text label
  • Links must have descriptive text (not "Click here" or "Learn more" without context)
  • Icon-only buttons require aria-label describing the action

Keyboard Navigation

  • All action buttons must be focusable via Tab key
  • Buttons must activate on Enter and Space key presses
  • Tab order must follow the visual reading order (top-to-bottom, left-to-right)
  • Flyout expand/collapse must be keyboard accessible

Screen Reader Support

  • Use semantic heading elements for card titles and section headers
  • Data fields should have associated labels readable by screen readers
  • Status indicators must convey meaning through text, not color alone
  • Dynamic content updates should use aria-live regions

Color Contrast

  • Text on card backgrounds must meet WCAG 2.1 AA contrast ratio (4.5:1)
  • Interactive element boundaries must have 3:1 contrast against their background
  • Do not use color as the sole method of conveying information (add icons or text)

Performance with Large Data Sets

Data Volume Guidelines

Record Count Recommended Approach
1-5 Load all records in a single card list
6-25 Load with pagination (show 5-10 per page)
26-100 Server-side pagination via IP; load one page at a time
100+ Reconsider the UX; use search/filter instead of browsing

Rendering Performance

  • Limit child card nesting to 2 levels maximum
  • Avoid rendering more than 25 cards simultaneously in a card list
  • Use conditional visibility to hide sections rather than rendering and hiding with CSS
  • Lazy-load tab content and flyout details on user interaction

Data Source Performance

  • Set appropriate IP cache durations for data that does not change frequently
  • Avoid chaining multiple IPs when a single IP can return all needed data
  • Use resultListPath to avoid client-side data transformation
  • Monitor IP execution times; optimize IPs that take longer than 2 seconds

Child Card Composition

When to Use Child Cards

  • The parent card displays summary data and the child card shows related detail
  • Multiple cards share a common layout pattern that should be defined once
  • Different sections of a card require independent data sources

Composition Guidelines

  • Pass data from parent to child via input parameters, not global variables
  • Keep child cards self-contained: they should work independently for testing
  • Limit nesting to 2 levels (parent → child → grandchild maximum)
  • Document the parent-child data flow in the FlexCard's description

Data Flow Pattern

Parent FlexCard
  ├── Data Source: IP_GetAccountSummary
  │     └── Passes {AccountId} to child
  └── Child FlexCard: AccountContacts
        └── Data Source: IP_GetContacts
              └── Input: {AccountId} from parent

Avoiding Composition Anti-Patterns

Anti-Pattern Problem Solution
Deep nesting (3+ levels) Performance degradation, hard to debug Flatten the structure; combine data in the IP
Shared mutable state Child cards modifying parent data Use one-way data flow (parent → child only)
Duplicate data sources Same IP called by parent and child Consolidate into parent data source; pass results down
Tightly coupled children Child card cannot function without parent Design children to accept input parameters and work standalone