Install
$ agentstack add skill-jaganpro-sf-skills-sf-industry-commoncore-flexcard ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
sf-industry-commoncore-flexcard: OmniStudio FlexCard Creation and Validation
Expert OmniStudio engineer specializing in FlexCard UI components for Salesforce Industries. Generate production-ready FlexCard definitions that display at-a-glance information with declarative data binding, Integration Procedure data sources, conditional rendering, and proper SLDS styling. All FlexCards are validated against a 130-point scoring rubric across 7 categories.
Core Responsibilities
- FlexCard Authoring: Design and build FlexCard definitions with proper layout, states, and field mappings
- Data Source Binding: Configure Integration Procedure data sources with correct field mapping and error handling
- Test Generation: Validate cards against multiple data states (populated, empty, error, multi-record)
- Documentation: Produce deployment-ready documentation with data source lineage and action mappings
Document Map
| Need | Document | Description | |------|----------|-------------| | Best practices | [references/best-practices.md](references/best-practices.md) | Layout patterns, SLDS, accessibility, performance | | Data binding | [references/data-binding-guide.md](references/data-binding-guide.md) | IP sources, field mapping, conditional rendering |
CRITICAL: Orchestration Order
FlexCards sit at the presentation layer of the OmniStudio stack. Ensure upstream components exist before building a FlexCard that depends on them.
sf-industry-commoncore-omnistudio-analyze → sf-industry-commoncore-datamapper → sf-industry-commoncore-integration-procedure → sf-industry-commoncore-omniscript → sf-industry-commoncore-flexcard (you are here)
FlexCards consume data from Integration Procedures and can launch OmniScripts. Build the data layer first, then the presentation layer.
Key Insights
| Insight | Detail | |---------|--------| | Configuration fields | OmniUiCard uses DataSourceConfig for data source bindings and PropertySetConfig for card layout, states, and actions. There is NO Definition field on OmniUiCard in Core namespace. | | Data source binding | Data sources bind to Integration Procedures for live data; the IP must be active and deployed before the FlexCard can retrieve data | | Child card embedding | FlexCards can embed other FlexCards as child cards, enabling composite layouts with shared or independent data sources | | OmniScript launching | FlexCards can launch OmniScripts via action buttons, passing context data from the card's data source into the OmniScript's input | | Designer virtual object | The FlexCard Designer uses OmniFlexCardView as a virtual list object (/lightning/o/OmniFlexCardView/home), separate from the OmniUiCard sObject where card records are stored. Cards created via API may not appear in "Recently Viewed" until opened in the Designer. |
Workflow (5-Phase Pattern)
Phase 1: Requirements Gathering
Before building, clarify these with the stakeholder:
| Question | Why It Matters | |----------|---------------| | What is the card's purpose? | Determines layout type and data density | | Which data sources are needed? | Identifies required Integration Procedures | | What object context does it run in? | Determines record-level vs. list-level display | | What actions should the card expose? | Drives button/link configuration and OmniScript integration | | What layout best fits the use case? | Single card, list, tabbed, or flyout | | Are there conditional display rules? | Fields or sections that appear/hide based on data values |
Phase 2: Design & Layout
Card Layout Options
| Layout Type | Use Case | Description | |-------------|----------|-------------| | Single Card | Record summary | One card displaying fields from a single record | | Card List | Related records | Repeating cards bound to an array data source | | Tabbed Card | Multi-context | Multiple states displayed as tabs within one card | | Flyout Card | Detail on demand | Expandable detail panel triggered from a summary card |
Data Source Configuration
Each FlexCard data source connects to an Integration Procedure (or other source type) and maps response fields to display elements.
FlexCard → Data Source (type: IntegrationProcedure)
→ IP Name + Input Mapping
→ Response Field Mapping → Card Elements
- Map IP response fields to card display elements using
{datasource.fieldName}merge syntax - Configure input parameters to pass record context (e.g.,
{recordId}) to the IP - Set data source order when multiple sources feed the same card
Action Button Design
| Action Type | Purpose | Configuration | |-------------|---------|---------------| | Launch OmniScript | Start a guided process | OmniScript Type + SubType, pass context params | | Navigate | Go to record or URL | Record ID or URL template with merge fields | | Custom Action | Platform event, LWC, etc. | Custom action handler with payload mapping |
Conditional Visibility
- Show/hide fields based on data values using visibility conditions
- Show/hide entire card states based on data source results
- Display empty-state messaging when data source returns no records
Phase 3: Generation & Validation
- Generate the FlexCard definition JSON
- Validate all data source references resolve to active Integration Procedures
- Run the 130-point scoring rubric (see Scoring section below)
- Verify merge field syntax matches IP response structure
- Check accessibility attributes on all interactive elements
Phase 4: Deployment
- Ensure all upstream Integration Procedures are deployed and active
- Deploy the FlexCard metadata (
OmniUiCard) - Activate the FlexCard in the target org
- Embed the FlexCard in the target Lightning page, OmniScript, or parent FlexCard
Phase 5: Testing
Test each FlexCard against multiple data scenarios:
| Scenario | What to Verify | |----------|---------------| | Populated data | All fields render correctly, merge fields resolve | | Empty data | Empty-state message displays, no broken merge fields | | Error state | Graceful handling when IP returns an error or times out | | Multi-record | Card list renders correct number of items, pagination works | | Action buttons | OmniScript launches with correct pre-populated data | | Conditional fields | Visibility rules toggle correctly based on data values | | Mobile | Card layout adapts to smaller viewport widths |
Generation Guardrails
Avoid these patterns when generating FlexCard definitions:
| Anti-Pattern | Why It's Wrong | Correct Approach | |--------------|---------------|-----------------| | Referencing non-existent IP data sources | Card fails to load data at runtime | Verify IP exists and is active before binding | | Hardcoded colors in styles | Breaks SLDS theming and dark mode | Use SLDS design tokens and CSS custom properties | | Missing accessibility attributes | Fails WCAG compliance | Add aria-label, role, and keyboard handlers | | Excessive nested child cards | Performance degrades with deep nesting | Limit to 2 levels of nesting; flatten where possible | | Ignoring empty states | Broken UI when data source returns no records | Configure explicit empty-state messaging | | Hardcoded record IDs | Card breaks across environments | Use merge fields and context-driven parameters |
Scoring Rubric (130 Points)
All FlexCards are validated against 7 categories. Thresholds: ✅ 90+ (Deploy) | ⚠️ 67-89 (Review) | ❌
Retrieve a specific FlexCard by name
sf project retrieve start -m OmniUiCard: -o
Deploy a FlexCard to the target org
sf project deploy start -m OmniUiCard: -o
Retrieve all FlexCards
sf project retrieve start -m OmniUiCard -o
Deploy all OmniStudio metadata (FlexCards + dependencies)
sf project deploy start -m OmniUiCard -m OmniIntegrationProcedure -m OmniScript -o
---
## Data Source Binding
### FlexCard Data Source Configuration
The `DataSourceConfig` field on `OmniUiCard` contains the data source bindings as JSON. The `PropertySetConfig` field contains the card layout, states, and field definitions.
> **IMPORTANT**: There is NO `Definition` field on `OmniUiCard` in Core namespace. Use `DataSourceConfig` for data sources and `PropertySetConfig` for layout.
```json
{
"dataSource": {
"type": "IntegrationProcedures",
"value": {
"ipMethod": "Type_SubType",
"vlocityAsync": false,
"inputMap": {
"recordId": "{recordId}"
},
"resultVar": ""
},
"orderBy": {
"name": "",
"isReverse": ""
},
"contextVariables": []
}
}
Data Source Types
| Type | dataSource.type | When to Use | |------|-------------------|-------------| | Integration Procedure | IntegrationProcedures (plural, capital P) | Primary pattern; calls an IP for live data | | SOQL | SOQL | Direct query (use sparingly; prefer IP for abstraction) | | Apex Remote | ApexRemote | Custom Apex class invocation | | REST | REST | External API call via Named Credential | | Custom | Custom | Custom data provider (pass JSON body directly) |
Field Mapping from IP Response
Map IP response fields to card display elements using merge field syntax:
IP Response: FlexCard Merge Field:
───────────── ─────────────────────
{ "Name": "Acme Corp" } → {Name}
{ "Account": { → {Account.Name}
"Name": "Acme Corp"
}
}
{ "records": [ → {records[0].Name} (single)
{ "Name": "Acme" } or iterate with Card List layout
]
}
Input Parameter Mapping
Pass context from the hosting page into the IP data source:
| Context Variable | Source | Example | |-----------------|--------|---------| | {recordId} | Current record page | Pass to IP to query related data | | {userId} | Running user | Filter data by current user | | {param.customKey} | URL parameter or parent card | Pass from parent FlexCard or URL |
Cross-Skill Integration
| Skill | Relationship to sf-industry-commoncore-flexcard | |-------|---------------------------| | sf-industry-commoncore-integration-procedure | Build the IP data sources that FlexCards consume | | sf-industry-commoncore-omniscript | Build the OmniScripts that FlexCard action buttons launch | | sf-industry-commoncore-datamapper | Build DataRaptors/DataMappers that IPs use under the hood | | sf-industry-commoncore-omnistudio-analyze | Analyze dependency chains across FlexCards, IPs, and OmniScripts | | sf-deploy | Deploy FlexCard metadata along with upstream dependencies | | sf-lwc | Build custom LWC components embedded within FlexCards |
Edge Cases
| Scenario | Handling | |----------|---------| | Empty data | Configure an explicit empty-state with a user-friendly message; do not show raw "No data" or blank card | | Error states | Display a meaningful error message when the IP data source fails; log the error for debugging | | Mobile responsiveness | Use single-column layout for mobile; avoid horizontal scrolling; test at 320px viewport width | | Long text values | Truncate with ellipsis and provide a flyout or tooltip for full text | | Large record sets | Use card list with pagination; limit initial load to 10-25 records | | Null field values | Use conditional visibility to hide fields with null values rather than showing empty labels | | Mixed data freshness | When multiple data sources have different refresh rates, display a "last updated" indicator |
FlexCard vs LWC Decision Guide
| Factor | FlexCard | LWC | |--------|----------|-----| | Build method | Declarative (drag-and-drop) | Code (JS, HTML, CSS) | | Data binding | Integration Procedure merge fields | Wire service, Apex, GraphQL | | Best for | At-a-glance information display | Complex interactive UIs | | Testing | Manual + data state verification | Jest unit tests + manual | | Customization | Limited to OmniStudio framework | Full platform flexibility | | Reuse | Embed as child cards | Import as child components | | When to choose | Standard card layouts with IP data | Custom behavior, animations, complex state |
Dependencies
Required: Target org with OmniStudio (Industries Cloud) license, sf CLI authenticated For Data Sources: Active Integration Procedures deployed to the target org For Actions: Active OmniScripts deployed (if action buttons launch OmniScripts) Scoring: Block deployment if score < 67
Creating FlexCards programmatically: Use REST API (sf api request rest --method POST --body @file.json). Required fields: Name, VersionNumber, OmniUiCardType (e.g., Child). Set DataSourceConfig (JSON string) for data source bindings and PropertySetConfig (JSON string) for card layout. The sf data create record --values flag cannot handle JSON in textarea fields. Activate by updating IsActive=true after creation.
External References
- OmniStudio FlexCards Trailhead - Official learning module
- OmniStudio Developer Guide - Technical reference
- Salesforce Industries Documentation - FlexCard configuration guide
License
MIT License. Copyright (c) 2026 David Ryan (weytani)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Jaganpro
- Source: Jaganpro/sf-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.