Skip to content
Widget Components

Widget Components

Overview

Aiffinity owns all consumer-facing UI rendering. Providers describe what to show, not how to show it. Your capability descriptor includes a surfaceGuidance object that tells the widget selector which component types best represent your data. The selector then picks the optimal component based on the user's context, screen real estate, and the 7-dimension budget engine.

Each component type has a budget cost (1–3 units) that the budget engine deducts from the user's per-session attention budget. Lower-cost components are preferred when budget is tight.

stat_row

A single metric display with a label, formatted value, and optional trend indicator. Ideal for KPIs, counts, percentages, or any single data point that benefits from at-a-glance readability.

Budget: 1 unit inform warn celebrate

Example payload

{
  "component": "stat_row",
  "objective": "inform",
  "density": "compact",
  "props": {
    "label": "Portfolio Value",
    "value": "$42,180.00",
    "trend": {
      "direction": "up",
      "delta": "+2.4%",
      "period": "24h"
    },
    "icon": "chart.line.uptrend.xyaxis"
  }
}

Props

PropertyTypeRequiredDescription
labelstringRequiredMetric label displayed above or beside the value.
valuestringRequiredFormatted display value. Provider is responsible for formatting (currency, units, etc.).
trendobjectOptionalTrend indicator. Contains direction ("up" | "down" | "flat"), delta (string), and optional period (string).
iconstringOptionalSF Symbol name for a leading icon. Falls back to a default metric icon if omitted.
subtitlestringOptionalSecondary text line below the value. Use for context or comparison.

sparkline

A miniature line chart for time-series data. Renders 7–30 data points as a smooth curve with optional area fill. Best for showing trends over time without requiring axis labels.

Budget: 2 units inform warn

Example payload

{
  "component": "sparkline",
  "objective": "inform",
  "density": "compact",
  "props": {
    "label": "Steps This Week",
    "values": [8420, 6230, 10150, 9800, 7650, 11200, 9400],
    "labels": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
    "currentValue": "9,400",
    "trend": { "direction": "up", "delta": "+12%" },
    "color": "green",
    "fill": true
  }
}

Props

PropertyTypeRequiredDescription
labelstringRequiredChart title displayed above the sparkline.
valuesnumber[]RequiredArray of 7–30 numeric data points. Rendered left-to-right.
labelsstring[]OptionalX-axis labels. If provided, must match the length of values.
currentValuestringOptionalFormatted current/latest value displayed alongside the chart.
trendobjectOptionalSame trend object as stat_row. Shown next to currentValue.
colorstringOptionalSemantic color name: "green", "red", "blue", "orange", "purple". Defaults to "blue".
fillbooleanOptionalWhether to render area fill below the line. Defaults to false.

progress_bar

A horizontal progress indicator with label, percentage, and optional target. Use for goals, quotas, task completion, or any bounded metric.

Budget: 1 unit inform celebrate nudge

Example payload

{
  "component": "progress_bar",
  "objective": "nudge",
  "density": "compact",
  "props": {
    "label": "Weekly Reading Goal",
    "progress": 0.65,
    "displayValue": "65%",
    "target": "5 books",
    "current": "3.25 books",
    "color": "orange"
  }
}

Props

PropertyTypeRequiredDescription
labelstringRequiredProgress bar label.
progressnumberRequiredProgress value between 0.0 and 1.0.
displayValuestringOptionalFormatted progress string (e.g., "65%", "3/5"). If omitted, renders progress * 100 as percentage.
targetstringOptionalTarget description shown beside the bar.
currentstringOptionalCurrent value description.
colorstringOptionalSemantic color for the fill. Defaults to "blue".

ranked_list

An ordered list of items, each with a rank, label, and optional score or badge. Use for leaderboards, top items, recent activity, or any sorted collection.

Budget: 2 units inform celebrate

Example payload

{
  "component": "ranked_list",
  "objective": "inform",
  "density": "standard",
  "props": {
    "title": "Top Repositories This Week",
    "items": [
      { "rank": 1, "label": "aiffinity-core", "value": "142 commits", "badge": "hot" },
      { "rank": 2, "label": "provider-sdk", "value": "87 commits" },
      { "rank": 3, "label": "design-tokens", "value": "54 commits" },
      { "rank": 4, "label": "landing-page", "value": "31 commits" },
      { "rank": 5, "label": "infra-charts", "value": "22 commits" }
    ],
    "maxItems": 5
  }
}

Props

PropertyTypeRequiredDescription
titlestringRequiredList heading.
itemsRankedItem[]RequiredArray of ranked items. Each has rank (number), label (string), optional value (string), optional badge (string), optional imageUrl (string).
maxItemsnumberOptionalMaximum items to display. Defaults to 5. The renderer may truncate further based on density.

action_row

A horizontal row of actionable buttons or links. Each action has a label, URL, and optional icon. Use for quick actions, deep links into your service, or contextual shortcuts.

Budget: 2 units act nudge

Example payload

{
  "component": "action_row",
  "objective": "act",
  "density": "compact",
  "props": {
    "actions": [
      {
        "label": "Open Board",
        "url": "https://trello.com/b/abc123",
        "icon": "rectangle.stack",
        "style": "primary"
      },
      {
        "label": "Create Card",
        "url": "https://trello.com/b/abc123/new-card",
        "icon": "plus.rectangle",
        "style": "secondary"
      },
      {
        "label": "View Activity",
        "url": "https://trello.com/b/abc123/activity",
        "style": "tertiary"
      }
    ]
  }
}

Props

PropertyTypeRequiredDescription
actionsAction[]RequiredArray of 1–4 actions. Each has label (string, required), url (string, required), optional icon (SF Symbol name), optional style ("primary" | "secondary" | "tertiary").

cta_banner

A prominent call-to-action banner with headline, subtitle, and a primary button. Use for onboarding prompts, upgrade offers, feature announcements, or time-sensitive calls to action.

Budget: 3 units act nudge celebrate

Example payload

{
  "component": "cta_banner",
  "objective": "act",
  "density": "standard",
  "props": {
    "headline": "Connect Your Calendar",
    "subtitle": "Get meeting prep cards, smart scheduling suggestions, and automatic context for every call.",
    "button": {
      "label": "Connect Google Calendar",
      "url": "https://api.aiffinity.me/v1/providers/runtime/auth/google-calendar",
      "style": "primary"
    },
    "dismissible": true,
    "icon": "calendar.badge.plus"
  }
}

Props

PropertyTypeRequiredDescription
headlinestringRequiredPrimary banner text. Keep under 60 characters.
subtitlestringOptionalSupporting text. Keep under 140 characters.
buttonobjectRequiredCTA button with label (string), url (string), and optional style ("primary" | "secondary").
dismissiblebooleanOptionalWhether the user can dismiss the banner. Defaults to true.
iconstringOptionalSF Symbol name for a leading icon.

meeting_prep

A pre-meeting context card that shows attendees, agenda items, relevant notes, and quick-access links. Designed to surface 30–60 minutes before a scheduled event.

Budget: 3 units prepare

Example payload

{
  "component": "meeting_prep",
  "objective": "prepare",
  "density": "expanded",
  "props": {
    "title": "Weekly Product Sync",
    "startsAt": "2026-04-04T14:00:00Z",
    "duration": 30,
    "location": "Google Meet",
    "meetingUrl": "https://meet.google.com/abc-defg-hij",
    "attendees": [
      { "name": "Sarah Chen", "role": "Product Lead", "avatarUrl": null },
      { "name": "Marcus Johnson", "role": "Engineering", "avatarUrl": null },
      { "name": "Lisa Park", "role": "Design", "avatarUrl": null }
    ],
    "agenda": [
      "Q2 roadmap review",
      "Provider SDK beta feedback",
      "Widget component catalog status"
    ],
    "notes": "Sarah mentioned wanting to discuss the new onboarding flow. Marcus has a PR ready for the sandbox API.",
    "relatedLinks": [
      { "label": "Q2 Roadmap Doc", "url": "https://notion.so/abc123" },
      { "label": "SDK Beta Tracker", "url": "https://linear.app/xyz" }
    ]
  }
}

Props

PropertyTypeRequiredDescription
titlestringRequiredMeeting title from the calendar event.
startsAtstring (ISO 8601)RequiredMeeting start time in UTC.
durationnumberOptionalDuration in minutes.
locationstringOptionalMeeting location or platform name.
meetingUrlstringOptionalDirect join URL.
attendeesAttendee[]OptionalArray of attendees. Each has name (string), optional role (string), optional avatarUrl (string | null).
agendastring[]OptionalAgenda items as an ordered list of strings.
notesstringOptionalContextual notes generated from prior interactions and memories.
relatedLinksLink[]OptionalRelated documents or resources. Each has label (string) and url (string).

compound_card

A multi-section container that composes several sub-components into a single card. Use for rich dashboards, multi-metric summaries, or any scenario where multiple related data points belong together.

Budget: 3 units inform prepare act

Example payload

{
  "component": "compound_card",
  "objective": "inform",
  "density": "expanded",
  "props": {
    "title": "Shopify Store Overview",
    "branding": {
      "provider": "Shopify",
      "iconUrl": "https://cdn.aiffinity.me/provider-icons/shopify.png",
      "accentColor": "#96BF48"
    },
    "sections": [
      {
        "component": "stat_row",
        "props": {
          "label": "Revenue Today",
          "value": "$1,842.00",
          "trend": { "direction": "up", "delta": "+18%" }
        }
      },
      {
        "component": "sparkline",
        "props": {
          "label": "Orders (7d)",
          "values": [12, 18, 15, 22, 19, 28, 24],
          "color": "green",
          "fill": true
        }
      },
      {
        "component": "action_row",
        "props": {
          "actions": [
            { "label": "View Orders", "url": "https://mystore.myshopify.com/admin/orders", "style": "primary" },
            { "label": "Analytics", "url": "https://mystore.myshopify.com/admin/analytics", "style": "secondary" }
          ]
        }
      }
    ]
  }
}

Props

PropertyTypeRequiredDescription
titlestringRequiredCard heading displayed at the top.
brandingobjectOptionalProvider branding. Contains provider (string), optional iconUrl (string), optional accentColor (hex string).
sectionsSection[]RequiredArray of 1–4 sub-component sections. Each section has component (a valid component type except compound_card) and props (that component's props).

Compound Card Structure

The compound_card component nests other components as sections. This is the only component that supports composition. Key rules:

// Compound card with branding and 3 sections
{
  "component": "compound_card",
  "props": {
    "title": "GitHub Activity",
    "branding": {
      "provider": "GitHub",
      "iconUrl": "https://cdn.aiffinity.me/provider-icons/github.png"
    },
    "sections": [
      { "component": "stat_row", "props": { "label": "Open PRs", "value": "7" } },
      { "component": "stat_row", "props": { "label": "Issues Assigned", "value": "12" } },
      { "component": "action_row", "props": { "actions": [{ "label": "Open GitHub", "url": "https://github.com", "style": "primary" }] } }
    ]
  }
}

Budget Engine

The Aiffinity widget selector uses a 7-dimension budget system to control the density and cognitive load of widgets shown to each user. Every session starts with a budget allocation across all seven dimensions. Each widget consumes budget based on its component type and objective.

Visual

Screen real estate and visual complexity. Charts and expanded cards cost more than compact stat rows.

Range: 0 – 20

Cognitive

Mental processing load. Dense data tables and multi-metric cards require more cognitive effort.

Range: 0 – 20

Action

Decision pressure. CTAs and action rows ask the user to do something, consuming action budget.

Range: 0 – 15

Temporal

Time sensitivity. Meeting prep and time-bound alerts are penalized if shown at the wrong time.

Range: 0 – 15

Novelty

Information freshness. Repeated or stale widgets are deprioritized. New data gets a novelty bonus.

Range: 0 – 10

Social

Social interaction load. Widgets involving other people (meeting prep, shared content) draw from this pool.

Range: 0 – 10

Ambient

Background awareness. Low-urgency ambient context (weather, portfolio, step count) shares this budget.

Range: 0 – 10

Component budget costs

ComponentCostPrimary Dimensions
stat_row1Visual (low), Cognitive (low)
sparkline2Visual (medium), Cognitive (medium)
progress_bar1Visual (low), Cognitive (low), Action (low)
ranked_list2Visual (medium), Cognitive (medium)
action_row2Action (high), Cognitive (low)
cta_banner3Visual (high), Action (high), Cognitive (medium)
meeting_prep3Visual (high), Cognitive (high), Social (high), Temporal (high)
compound_card3Visual (high), Cognitive (high)

Surface Guidance

Your capability descriptor includes a surfaceGuidance object that tells the widget selector how to render your data. The selector uses this guidance alongside the budget engine and user context to choose the optimal component and placement.

{
  "surfaceGuidance": {
    "intent": "ambient_context",
    "placement": ["home_widgets", "daily_brief"],
    "components": ["stat_row", "sparkline"]
  }
}

Fields

FieldTypeDescription
intent string The purpose of this widget. One of: "ambient_context", "active_task", "social_context", "time_sensitive", "milestone", "call_to_action".
placement string[] Where this widget can appear. Options: "home_widgets", "daily_brief", "aiffinity_screen", "chat_context", "notification".
components string[] Preferred component types, in order of preference. The selector picks the first component that fits within the current budget.

The components array should list your preferred types in descending order of richness. For example, ["compound_card", "sparkline", "stat_row"] tells the selector to try a compound card first, fall back to a sparkline if budget is tight, and use a stat row as a last resort.