npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@affinda/react

v0.0.29

Published

React components for Affinda UI - built on web components with Stencil.

Readme

@affinda/react

React components for Affinda UI - built on web components with Stencil.

Installation

npm install @affinda/react @affinda/css
# or
pnpm add @affinda/react @affinda/css

Quick Start

1. Import Styles and Initialize Components

// In your main.tsx or index.tsx
import '@affinda/css'; // Loads reset, fonts, tokens, base styles
import { defineCustomElements } from '@affinda/wc/loader';

// Initialize web components
defineCustomElements();

2. Use Components

import { AfButton, AfNavbar, AfNavItem } from '@affinda/react';

function App() {
  return (
    <div>
      {/* AfNavbar displays the default Affinda logo automatically */}
      <AfNavbar>
        <div slot="start">
          <AfNavItem href="/products">Products</AfNavItem>
        </div>
        <AfButton slot="button" variant="primary">Get Started</AfButton>
      </AfNavbar>
    </div>
  );
}

3. Load NeuSans Font (Recommended)

Affinda components use the NeuSans font family. To get the authentic Affinda look:

  1. Obtain NeuSans font files (contact Affinda or your design team)
  2. Add @font-face declarations in your global CSS:
@font-face {
  font-family: 'NeuSans';
  font-style: normal;
  font-weight: 500; /* Book weight for headings */
  src: url('/fonts/NeuSans-Book.woff2') format('woff2');
}

@font-face {
  font-family: 'NeuSans';
  font-style: normal;
  font-weight: 400; /* Regular weight */
  src: url('/fonts/NeuSans-Regular.woff2') format('woff2');
}

Don't have NeuSans? The components will gracefully fall back to Inter and system fonts.

Usage

⚠️ Theme Container Requirement: Always wrap your components in a theme-providing container like AfSection or AfCard. These containers establish theme context via CSS custom properties that child components (AfHeading, AfText, AfButton, etc.) consume for their colors.

<AfSection theme="white">
  <AfHeading level="1">Title</AfHeading>
  <AfText>Content with proper colors</AfText>
</AfSection>

Available Components

Components are organized by complexity level. Always compose from these levels — don't write custom HTML/CSS for layouts that components already handle.

Atoms (Basic Building Blocks)

  • AfButton - Primary buttons with variants and icons
  • AfIconButton - Icon-only buttons
  • AfHeading - Typography headings (H1-H6) with theme support
  • AfText - Body text components with theme support
  • AfTag - Categorization labels with sand and light variants
  • AfSection - Page sections with consistent spacing and themes ⭐ provides theme context
  • AfCard - Content cards with optional backgrounds and photo variants ⭐ provides theme context
  • AfContainer - Layout containers with max-width
  • AfIconBox - Themed container for displaying an icon with rounded background
  • AfLogo - Affinda logo component
  • AfLogoWell - Rounded container for client logos
  • AfAspectRatio - Maintain aspect ratios for media
  • AfColorSwatch - Display color swatches

Molecules (Composed from Atoms)

  • AfButtonGroup - Group multiple buttons together
  • AfTypographyLockup - Composite heading + text + button layouts
  • AfIconText - AfIconBox + AfTypographyLockup for feature items with icons
  • AfFeatureCard - AfCard + image + AfTypographyLockup for feature showcase
  • AfIllustratedCard - AfCard + illustration slot
  • AfNavItem - Navigation items
  • AfNavCard - Navigation card with icon and description
  • AfTestimonial - Customer testimonials with background images, stats, and quotes
  • AfTestimonialStat - Individual statistics within testimonials
  • AfFooterColumn - Navigation column for footer
  • AfFooterLink - Styled link for footer navigation
  • AfSocialLink - Circular social media icon link
  • AfContactItem - Label/value pair for contact info
  • AfPaperclipDecoration - Decorative paperclip vector for hero sections

Organisms (Page Sections)

  • AfNavbar - Navigation bar with mobile hamburger menu
  • AfFeatureGrid - Responsive CSS grid container for feature cards/items
  • AfFeatureAccordion - Expandable accordion with auto-cycling timer
  • AfGridCallout - Image + heading + AfIconText grid for feature sections
  • AfSplitSection - Two-column layouts with image and content
  • AfClientCarousel - Infinite scrolling carousel for client logos
  • AfTestimonialCarousel - Carousel for sliding between testimonials
  • AfInPageBanner - Call-to-action banner card with illustration ⭐ provides theme context
  • AfFooter - Slot-based footer layout component

Quick Start Components

AfSection

The section component provides consistent spacing and backgrounds for page sections.

import { AfSection, AfHeading, AfText } from '@affinda/react';

<AfSection padding="default" theme="mist-green" container={true}>
  <AfHeading level="2" align="center">Work smarter, grow faster</AfHeading>
  <AfText variant="large" align="center">Feature content here...</AfText>
</AfSection>

Props:

  • padding: "tight" (48px) | "default" (96px) | "loose" (120px)
  • theme: "white" | "inkwell" | "mist-green" | "soft-clay" (default: "white")
  • container: boolean - Auto-wraps content in Container

Theme inheritance: Child components (AfHeading, AfText, AfButton) automatically inherit the section's theme colors. No manual theme props needed on children!

AfCard

Cards support themed backgrounds and photo backgrounds. Use the theme prop for consistent styling with theme inheritance.

import { AfCard, AfHeading, AfText } from '@affinda/react';

// Themed card (recommended) - children inherit theme colors automatically
<AfCard theme="mist-green">
  <AfHeading level="3">Automate any document with 99%+ accuracy</AfHeading>
  <AfText variant="large">Extract any information...</AfText>
  <img src="screenshot.webp" alt="Feature" />
</AfCard>

// Dark themed card
<AfCard theme="inkwell">
  <AfHeading level="3">Build models in minutes</AfHeading>
  <AfText variant="large">Affinda is the only AI platform...</AfText>
</AfCard>

// Photo background card (for custom backgrounds)
<AfCard backgroundImage="photo.jpg" darkOverlay={true}>
  <AfHeading level="3">Build models in minutes</AfHeading>
  <AfText variant="large">Affinda is the only AI platform...</AfText>
</AfCard>

Props:

  • theme: "white" | "inkwell" | "mist-green" | "soft-clay" (recommended)
  • backgroundColor: CSS color or variable (legacy, use theme instead)
  • backgroundImage: URL to background image
  • darkOverlay: boolean - Applies gradient overlay for text readability on photos

AfPaperclipDecoration

Decorative SVG paperclip graphic for hero sections.

Use with AfSection and position absolutely within the section:

import { AfSection, AfContainer, AfTypographyLockup, AfPaperclipDecoration } from '@affinda/react';

<AfSection theme="inkwell" padding="loose" style={{ position: 'relative', overflow: 'hidden' }}>
  <AfPaperclipDecoration 
    style={{ 
      position: 'absolute', 
      bottom: -80,    // Adjust to move vertically
      right: -800,    // Adjust to move horizontally
      zIndex: 0
    }} 
  />
  <AfContainer style={{ position: 'relative', zIndex: 1 }}>
    {/* Hero content */}
  </AfContainer>
</AfSection>

Positioning Tips:

  • Negative values move the decoration outside the viewport (creating a partial reveal effect)
  • bottom: Controls vertical position (negative = move down/off-screen)
  • right: Controls horizontal position (negative = move right/off-screen)
  • Start with bottom: -80, right: -800 and adjust to taste
  • Set overflow: hidden on the section to clip the decoration

Component Guide

When to Use Each Component

Layout & Structure

AfContainer

  • Use for all page sections to maintain consistent max-width and horizontal padding
  • Creates responsive layouts that don't span the full viewport on large screens
  • Best practice: Wrap each major section of your page in an AfContainer
<AfContainer>
  <AfHeading level="2">Section Title</AfHeading>
  <AfText>Section content goes here...</AfText>
</AfContainer>

AfAspectRatio

  • Maintain consistent dimensions for images, videos, or media
  • Prevents layout shift during content loading
  • Common ratios: 16/9 (video), 1/1 (square), 4/3 (legacy video)
<AfAspectRatio ratio="16/9">
  <img src="video-thumbnail.jpg" alt="Preview" />
</AfAspectRatio>

AfCard

  • Group related content with visual separation
  • Use for feature highlights, product listings, or content previews
  • Supports borders and elevation for depth
<AfCard>
  <AfHeading level="3">Feature Title</AfHeading>
  <AfText>Feature description...</AfText>
</AfCard>

Typography

AfHeading

  • Use semantic heading levels (1-6) for SEO and accessibility
  • Level 1: Page title (use once per page)
  • Level 2: Major sections
  • Level 3-4: Subsections
  • Never skip heading levels
<AfHeading level="1">Page Title</AfHeading>
<AfHeading level="2">Section Title</AfHeading>
<AfHeading level="3">Subsection</AfHeading>

AfText

  • Use for all body text, descriptions, and paragraphs
  • Variants: default, small, large
  • Automatically uses NeuSans font
<AfText variant="large">Introductory paragraph with emphasis</AfText>
<AfText>Standard body text</AfText>
<AfText variant="small">Fine print or captions</AfText>

AfTypographyLockup

  • Composite component for hero sections and major content blocks
  • Automatically handles heading + description + buttons layout
  • Supports different breakpoints and alignments
  • Use for: Hero sections, feature highlights, CTAs
<AfTypographyLockup
  headingSize={1}
  textAlignment="center"
  buttonAlignment="horizontal"
>
  <AfHeading level="1">Automate Your Workflow</AfHeading>
  <AfText slot="description">Extract data from documents in seconds</AfText>
  <AfButtonGroup slot="buttons" direction="horizontal">
    <AfButton variant="primary">Get Started</AfButton>
    <AfButton variant="secondary">Learn More</AfButton>
  </AfButtonGroup>
</AfTypographyLockup>

Buttons & Actions

AfButton

  • Primary actions: Use variant="primary" (sparingly, 1-2 per screen)
  • Secondary actions: Use variant="secondary"
  • Sizes: small, default
  • Can include icons in left or right slots
  • Buttons automatically inherit theme colors from parent AfSection/AfCard
<AfButton variant="primary">Sign Up Now</AfButton>
<AfButton variant="secondary">Learn More</AfButton>

AfButtonGroup

  • Group related buttons with consistent spacing
  • Maintains visual hierarchy and alignment
<AfButtonGroup>
  <AfButton variant="primary">Save</AfButton>
  <AfButton variant="secondary">Cancel</AfButton>
</AfButtonGroup>

AfIconButton

  • Use for toolbar actions, navigation controls, or when space is limited
  • Always include aria-label for accessibility
  • Common uses: Close buttons, navigation arrows, menu toggles
import { AfIconButton, Close, Menu } from '@affinda/react';

<AfIconButton variant="secondary" aria-label="Close dialog">
  <Close size={24} />
</AfIconButton>

<AfIconButton variant="tertiary" size="small" aria-label="Toggle menu">
  <Menu size={20} />
</AfIconButton>

Tags

AfTag

  • Use for categorization, topics, filters, or metadata display
  • Variants: sand (default - soft-clay/tan) or light (mist-green)
  • Sizes: x-small, small (default), large
  • Can be clickable links with href prop
<AfTag>AI</AfTag>
<AfTag variant="light">OCR</AfTag>
<AfTag variant="sand" size="large" href="/topics/ml">Machine Learning</AfTag>

Navigation

AfNavbar

⚠️ IMPORTANT: The AfNavbar component uses slots for positioning elements. Items placed as direct children will not be visible. You must wrap them in divs with the appropriate slot attribute.

Site-wide navigation header with responsive design and mobile menu support.

Layout Behavior:

The Navbar renders two elements:

  1. A spacer element that sits in normal document flow and reserves vertical space
  2. A fixed navbar that floats above the page content

This prevents page content from being hidden behind the navbar. The spacer automatically adjusts its height at different breakpoints:

  • Desktop: 100px
  • Tablet (≤1024px): 88px
  • Mobile (≤991px): 72px

Props:

  • showDefaultLogo (boolean, default: true) - Whether to show the default Affinda logo when no logo slot content is provided
  • theme: "white" | "inkwell" | "mist-green" | "soft-clay" - Sets the spacer background color to match the section below the navbar

Slots:

  • logo - Brand logo (left side) - optional, defaults to Affinda logo
  • start - Primary navigation links (center-left)
  • end - Secondary navigation and actions (right side)
  • button - Call-to-action button (far right)
<AfNavbar>
  {/* Start slot - main navigation items */}
  <div slot="start">
    <AfNavItem hierarchy="primary" variant="01" href="/platform">
      Platform
    </AfNavItem>
    <AfNavItem hierarchy="primary" variant="01" href="/solutions">
      Solutions
    </AfNavItem>
    <AfNavItem hierarchy="primary" variant="01" href="/pricing">
      Pricing
    </AfNavItem>
  </div>
  
  {/* End slot - secondary navigation */}
  <div slot="end">
    <AfNavItem hierarchy="primary" variant="02" href="/contact">
      Talk to us
    </AfNavItem>
    <AfNavItem hierarchy="primary" variant="02" href="/login">
      Log in
    </AfNavItem>
  </div>
  
  {/* Button slot - CTA */}
  <AfButton slot="button" variant="primary" size="default">
    Try for free
  </AfButton>
</AfNavbar>

AfNavItem

  • Individual navigation links
  • Hierarchy: primary (main nav), secondary (utility nav)
  • Variant: "01" (primary links), "02" (secondary/utility links)
  • Variant: Controls visual style

Feature Showcase

AfFeatureAccordion

  • Expandable accordion for showcasing product features
  • Auto-cycles through items with a visual progress timer
  • Displays accompanying images that change with each item
  • Timer resets when user clicks an item
  • Must be wrapped in an AfSection which provides theme context and padding
import { AfSection, AfFeatureAccordion } from '@affinda/react';

<AfSection theme="mist-green" padding="default">
  <AfFeatureAccordion
    heading="Give AI agents your paperwork"
    items={JSON.stringify([
      {
        title: "Automate document processing with 99%+ accuracy",
        description: "Extract any information from any document with industry-leading precision.",
        imageUrl: "https://example.com/feature1.jpg",
        imageAlt: "Document automation"
      },
      {
        title: "Build models in minutes, not months",
        description: "Affinda learns instantly from every interaction.",
        imageUrl: "https://example.com/feature2.jpg",
        imageAlt: "Fast model building"
      }
    ])}
    cycleInterval={6000}
    autoCycle={true}
  />
</AfSection>

Props:

  • heading: Section heading text
  • items: JSON string array of accordion items (title, description, imageUrl, imageAlt)
  • cycleInterval: Auto-cycle interval in milliseconds (default: 6000)
  • autoCycle: Enable/disable auto-cycling (default: true)

Section Props (wrapper):

  • theme: "white" | "inkwell" | "mist-green" | "soft-clay" - Sets background and typography colors
  • padding: "tight" | "default" | "loose" - Vertical spacing (default: "default")

AfInPageBanner

  • Call-to-action banner card with illustration and decorative wave background
  • Place inside a neutral (white) AfSection to show off its themed background
  • Use getIllustrationUrlByScene() from @affinda/illustrations for theme-matched illustrations
import { AfSection, AfInPageBanner } from '@affinda/react';
import { getIllustrationUrlByScene } from '@affinda/illustrations';

<AfSection padding="default" theme="white" container={true}>
  <AfInPageBanner
    theme="mist-green"
    heading="See what our AI agents can do for you"
    description="Upload your documents and watch our AI agents get to work."
    primaryButtonText="Try for free"
    primaryButtonUrl="https://app.affinda.com/auth/register"
    secondaryButtonText="Talk to us"
    secondaryButtonUrl="/contact"
    illustrationUrl={getIllustrationUrlByScene('automate', 'mist-green')}
  />
</AfSection>

Props:

  • theme: "white-ivory" | "inkwell" | "mist-green" | "soft-clay" (default: "mist-green") - Sets background and typography colors
  • heading: Banner heading text
  • description: Description text below heading
  • primaryButtonText: Text for primary CTA button
  • primaryButtonUrl: URL for primary button
  • secondaryButtonText: Text for secondary button (optional)
  • secondaryButtonUrl: URL for secondary button
  • illustrationUrl: Illustration image URL. Use getIllustrationUrlByScene(scene, theme) from @affinda/illustrations for theme-matched illustrations. Available scenes: 'document-raise', 'thinking', 'shapes', 'team-leader', 'grow-business', 'document-type', 'industries', 'accuracy', 'intelligence', 'page-turn', 'automate'
  • showWaveDecoration: Whether to show the decorative wave overlay (default: true)

Social Proof & Testimonials

AfTestimonial

  • Showcase customer success stories with rich media
  • Include: background image, logo, quote, attribution, and statistics
  • Use within AfTestimonialCarousel for multiple testimonials
<AfTestimonial
  backgroundImage="https://example.com/background.jpg"
  logoImage="https://example.com/company-logo.png"
  quote="Affinda transformed our document processing workflow."
  attribution="– Jane Doe, CEO, Company Name"
  readMoreLink="https://example.com/case-study"
>
  <AfTestimonialStat slot="stats" value="95%" description="reduction in processing time" />
  <AfTestimonialStat slot="stats" value="10×" description="increase in throughput" />
</AfTestimonial>

AfTestimonialCarousel

  • Wrap with AfSection for theming and AfContainer for layout (like other components)
  • Automatically handles navigation between multiple testimonials
  • Includes progress indicator
<AfSection padding="default" theme="white" container>
  <AfTestimonialCarousel>
    <AfTestimonial {...testimonial1Props}>
      <AfTestimonialStat slot="stats" value="95%" description="processing time reduction" />
      <AfTestimonialStat slot="stats" value="10×" description="throughput increase" />
    </AfTestimonial>
    <AfTestimonial {...testimonial2Props}>
      <AfTestimonialStat slot="stats" value="99%" description="accuracy rate" />
    </AfTestimonial>
  </AfTestimonialCarousel>
</AfSection>

AfTestimonialStat

  • Display key metrics within testimonials
  • Use slot="stats" on each stat to position correctly
  • Use 2-4 stats per testimonial for best impact
  • Optional accent border for qualitative statements
<AfTestimonialStat slot="stats" value="99%" description="accuracy rate" />
<AfTestimonialStat 
  slot="stats"
  value="" 
  description="Reduced manual errors significantly" 
  accentBorder={true} 
/>

Branding

AfLogo

  • Affinda logo component with consistent sizing
  • Use in AfNavbar and footer
  • Renders as inline SVG for crisp display at any size
<AfLogo />

AfColorSwatch

  • Display color palettes or design tokens
  • Useful for style guides and documentation
<AfColorSwatch color="#C6D5D1" label="Mist Green" />

Icons

All Affinda icons are also exported:

import {
  AccountIcon,
  ArrowRightIcon,
  CheckCircleIcon,
  MenuIcon
} from '@affinda/react';

Example Usage

Basic AfButton

import { AfButton } from '@affinda/react';

function App() {
  return (
    <AfButton variant="primary" size="default">
      Click me
    </AfButton>
  );
}

AfButton with Icons

import { AfButton, ArrowRightIcon } from '@affinda/react';

function App() {
  return (
    <AfButton variant="primary">
      <svg slot="icon-left">
        <ArrowRightIcon />
      </svg>
      Get Started
      <svg slot="icon-right">
        <ArrowRightIcon />
      </svg>
    </AfButton>
  );
}

AfTypographyLockup

import { AfTypographyLockup, AfButton } from '@affinda/react';

function Hero() {
  return (
    <AfTypographyLockup
      headingSize={1}
      breakpoint="desktop"
      textAlignment="center"
      buttonAlignment="vertical"
    >
      <h1>Welcome to Affinda</h1>
      <p slot="description">
        Extract data from documents with AI-powered accuracy
      </p>
      <AfButton slot="buttons" variant="primary">Get Started</AfButton>
      <AfButton slot="buttons" variant="secondary">Learn More</AfButton>
    </AfTypographyLockup>
  );
}

Navigation

import { AfNavbar, AfNavItem, AfButton } from '@affinda/react';

function Header() {
  return (
    // AfNavbar displays the default Affinda logo automatically
    <AfNavbar>
      <div slot="start">
        <AfNavItem hierarchy="primary" variant="01" href="/">
          Home
        </AfNavItem>
        <AfNavItem hierarchy="primary" variant="01" href="/products">
          Products
        </AfNavItem>
      </div>
      <div slot="end">
        <AfNavItem hierarchy="primary" variant="02" href="/docs">
          Documentation
        </AfNavItem>
      </div>
      <AfButton slot="button" variant="primary">Get Started</AfButton>
    </AfNavbar>
  );
}

Accessing Affinda Colors

Colors are available from the @affinda/tokens package (automatically installed as a dependency):

// Via CSS custom properties
import '@affinda/tokens/tokens.css';

const MyComponent = () => (
  <div style={{
    backgroundColor: 'var(--colour-brand-mist-green)',
    color: 'var(--colour-brand-inkwell)'
  }}>
    Affinda branded content
  </div>
);
// Via JavaScript
import { tokens } from '@affinda/tokens';

const MyComponent = () => (
  <div style={{
    backgroundColor: tokens.color.brand.mistGreen.value,
    color: tokens.color.brand.inkwell.value
  }}>
    Affinda branded content
  </div>
);

Available Affinda Colors

Brand Colors:

  • Mist Green: #C6D5D1 - var(--colour-brand-mist-green)
  • Inkwell: #14343B - var(--colour-brand-inkwell)
  • Soft Clay: #B09670 - var(--colour-brand-soft-clay)
  • Ice: #A6FFF8 - var(--colour-brand-ice)
  • Azure: #7FE2D4 - var(--colour-brand-azure)
  • Ivory Paper: #FFF9E1 - var(--colour-brand-ivory-paper)
  • White: #FFFFFF - var(--colour-brand-white)

Tints: Each color has tints from 20 (lightest) to 800 (darkest)

  • var(--colour-tints-mist-green-20) through var(--colour-tints-mist-green-800)
  • var(--colour-tints-inkwell-20) through var(--colour-tints-inkwell-800)
  • And more...

See the @affinda/tokens documentation for the complete color palette.

TypeScript Support

Full TypeScript type definitions are included for all components and props.

Custom Styling

All components accept a style prop for applying inline CSS styles directly to the component's root element:

import { AfButton, AfSection, AfHeading } from '@affinda/react';

// Apply custom styles to any component
<AfButton variant="primary" style={{ marginTop: '20px', opacity: 0.9 }}>
  Custom Styled Button
</AfButton>

<AfSection theme="white" style={{ borderRadius: '16px', boxShadow: '0 4px 12px rgba(0,0,0,0.1)' }}>
  <AfHeading level="2">Styled Section</AfHeading>
</AfSection>

The style prop is passed through to the web component's host element, allowing you to override or extend component styles as needed.

Common UI Patterns

Use these component combinations for common marketing page patterns. Always check this section before writing custom CSS or HTML.

Grid of Feature Items with Icons

import { AfSection, AfFeatureGrid, AfIconText } from '@affinda/react';

<AfSection theme="mist-green" container={true}>
  <AfFeatureGrid columns={4} mobileLayout="list">
    <AfIconText icon="time" headingSize={4}>
      Fast Processing
      <span slot="description">Process documents in seconds.</span>
    </AfIconText>
    <AfIconText icon="verification-01" headingSize={4}>
      High Accuracy
      <span slot="description">99%+ extraction accuracy.</span>
    </AfIconText>
    <AfIconText icon="security-01" headingSize={4}>
      Secure & Compliant
      <span slot="description">Enterprise-grade security.</span>
    </AfIconText>
    <AfIconText icon="code" headingSize={4}>
      Easy Integration
      <span slot="description">Works with your existing systems.</span>
    </AfIconText>
  </AfFeatureGrid>
</AfSection>

Grid of Feature Cards with Images

import { AfFeatureGrid, AfFeatureCard } from '@affinda/react';

<AfFeatureGrid columns={3} mobileLayout="scroll">
  <AfFeatureCard theme="mist-green" cardSize="flexible" imageSrc="/feature1.jpg">
    Extract Any Document
    <span slot="body">AI-powered extraction for all document types.</span>
  </AfFeatureCard>
  <AfFeatureCard theme="soft-clay" cardSize="flexible" imageSrc="/feature2.jpg">
    Validate Automatically
    <span slot="body">Built-in validation catches errors.</span>
  </AfFeatureCard>
</AfFeatureGrid>

Grouped Buttons

import { AfButtonGroup, AfButton } from '@affinda/react';

<AfButtonGroup direction="horizontal" gap="16px">
  <AfButton variant="primary">Get Started</AfButton>
  <AfButton variant="secondary">Learn More</AfButton>
</AfButtonGroup>

Feature Section with Image + Grid of Items

import { AfSection, AfGridCallout, AfIconText, AfButton } from '@affinda/react';

<AfSection theme="white" container={true}>
  <AfGridCallout imageSrc="/team.jpg" imagePosition="left" columns={2}>
    Why Choose Affinda
    <span slot="description">Industry-leading AI for document processing.</span>
    
    <AfIconText slot="items" icon="sparkle" headingSize={4}>
      AI-Powered
      <span slot="description">State-of-the-art machine learning.</span>
    </AfIconText>
    <AfIconText slot="items" icon="security-01" headingSize={4}>
      Enterprise Security
      <span slot="description">SOC 2 Type II certified.</span>
    </AfIconText>
    
    <AfButton slot="cta" variant="primary">Learn More</AfButton>
  </AfGridCallout>
</AfSection>

Icons in Feature Lists

import { AfIconBox, AfIconText } from '@affinda/react';

// Standalone icons
<AfIconBox icon="verification-01" size="default" />

// Icon + text combinations
<AfIconText icon="time" headingSize={4}>
  Fast Processing
  <span slot="description">Documents processed in seconds.</span>
</AfIconText>

Hero Section (Recipe)

Hero sections are composed from AfSection + AfContainer + AfTypographyLockup:

import { AfSection, AfContainer, AfTypographyLockup, AfHeading, AfText, AfButtonGroup, AfButton } from '@affinda/react';

<AfSection theme="inkwell" padding="loose" style={{ minHeight: '80vh' }}>
  <AfContainer>
    <AfTypographyLockup headingSize={1} textAlignment="center">
      <AfHeading level="1">Document Automation</AfHeading>
      <AfText slot="description" variant="large">
        Extract data from any document with AI.
      </AfText>
      <AfButtonGroup slot="buttons" direction="horizontal" gap="16px">
        <AfButton variant="primary">Start Free Trial</AfButton>
        <AfButton variant="secondary">Watch Demo</AfButton>
      </AfButtonGroup>
    </AfTypographyLockup>
  </AfContainer>
</AfSection>

This composition pattern gives you full control over each layer while maintaining consistent spacing and theme inheritance.


For AI Agents

When generating Affinda UI code:

Component Selection (Critical!)

Always use existing components instead of custom CSS/HTML. Before writing any layout code, check if a component exists for your use case.

| If you need... | Use this component | |----------------|-------------------| | Grid of items | AfFeatureGrid | | Card with icon + text | AfIconText | | Standalone icon | AfIconBox | | Card with photo/screenshot | AfFeatureCard | | Card with @affinda/illustrations | AfIllustratedCard | | Button group | AfButtonGroup | | Heading + description + buttons | AfTypographyLockup | | Section with image + feature grid | AfGridCallout | | Two-column layout | AfSplitSection | | Responsive grid container | AfFeatureGrid with mobileLayout prop |

Available Icons

Use icons from @affinda/icons with AfIconBox or AfIconText. Never use emoji.

Common icons:

  • time - speed/performance
  • verification-01 - accuracy/checking
  • security-01, security-02 - security/compliance
  • sparkle - AI/magic
  • productivity - efficiency
  • code - integration/API
  • document-upload - documents
  • lending-01, lending-02 - lending industry
  • check-circle - success/checkmarks
  • data - data/analytics
  • gear - settings/configuration
// Use with AfIconBox
<AfIconBox icon="verification-01" size="default" />

// Use with AfIconText
<AfIconText icon="sparkle" headingSize={4}>
  AI-Powered Processing
  <span slot="description">State-of-the-art machine learning.</span>
</AfIconText>

Theme System (Important!)

Use the 4-value theme system on container components. Child components inherit colors automatically:

<AfSection theme="inkwell">
  <AfHeading level="2">Title</AfHeading>  {/* Automatically light text */}
  <AfText>Content</AfText>                {/* Automatically light text */}
  <AfButton variant="primary">Action</AfButton>  {/* Automatically themed */}
</AfSection>

Available themes: "white" | "inkwell" | "mist-green" | "soft-clay" | "white-ivory"

Theme Override

Use AfThemeOverride to explicitly set a theme for child components, overriding any inherited theme from parent containers. This is useful when you need specific components to use a different theme than their container.

<AfSection theme="inkwell">
  <AfHeading level="1">Inherits inkwell theme</AfHeading>
  
  {/* Override just this button to use white theme colors */}
  <AfThemeOverride theme="white">
    <AfButton variant="secondary">Uses white theme</AfButton>
  </AfThemeOverride>
</AfSection>

You can also wrap multiple components:

<AfSection theme="mist-green">
  <AfThemeOverride theme="inkwell">
    <AfHeading level="2">Dark heading on green background</AfHeading>
    <AfText>Dark text styling</AfText>
  </AfThemeOverride>
</AfSection>

Note: AfThemeOverride only sets the CSS custom properties for child component colors — it does NOT change the background color. The visual background remains from the parent container.

Self-Theming Components (No Section Wrapper!)

Some components provide their own themed backgrounds. Do NOT wrap these in a Section — they handle their own background color and spacing.

| Component | Provides Own Background | Correct Usage | |-----------|------------------------|---------------| | AfClientCarousel | Yes | Use directly, set theme prop to match adjacent section | | AfInPageBanner | Yes | Wrap in neutral AfSection theme="white" to show contrast |

<AfClientCarousel theme="inkwell">...</AfClientCarousel>

AfClientCarousel Theme Matching

When using AfClientCarousel, set its theme prop to match the section above it for visual continuity. This creates a seamless transition between sections.

{/* Hero section using composition pattern */}
<AfSection theme="inkwell" padding="loose">
  <AfContainer>
    <AfTypographyLockup headingSize={1} textAlignment="center">
      {/* Hero content */}
    </AfTypographyLockup>
  </AfContainer>
</AfSection>
<AfClientCarousel theme="inkwell">
  {/* Logo wells - theme matches preceding section */}
</AfClientCarousel>

AfSplitSection Theme Context

AfSplitSection creates a two-tone background split at 50%. By default, child content inherits the top theme's colors. When content visually sits in the bottom half, wrap it with AfThemeOverride to use the appropriate theme colors:

<AfSplitSection topTheme="inkwell" bottomTheme="white">
  {/* Header in top half - uses inherited inkwell theme (light text) */}
  <AfHeading level="2">Dark Header</AfHeading>
  
  {/* Card in bottom half - override to white theme for proper contrast */}
  <AfThemeOverride theme="white">
    <AfCard theme="white">
      <AfHeading level="3">Card Content</AfHeading>
      <AfButton variant="primary">Action</AfButton>
    </AfCard>
  </AfThemeOverride>
</AfSplitSection>

This pattern gives you full control over which theme context each piece of content uses, regardless of its visual position.

AfFeatureAccordion (Wrap in AfSection!)

Unlike self-theming components, AfFeatureAccordion should be wrapped in an AfSection which provides the theme context, padding, and container.

<AfSection theme="soft-clay" padding="default">
  <AfFeatureAccordion
    heading="Give AI agents your paperwork"
    items={JSON.stringify([...])}
  />
</AfSection>

Slot-Based Components

Several components require slot attributes on children:

// AfNavbar slots: logo, start, end, button
<AfNavbar>
  <div slot="start"><AfNavItem href="/">Home</AfNavItem></div>
  <AfButton slot="button">CTA</AfButton>
</AfNavbar>

// AfFooter slots: logo, social, contact, nav, legal, badges
// AfClientCarousel slots: row-1, row-2
// AfButton slots: icon-left, icon-right
// AfTypographyLockup slots: description, buttons

AfFeatureAccordion Items

The items prop requires JSON.stringify():

<AfSection theme="mist-green" padding="default">
  <AfFeatureAccordion items={JSON.stringify([{ title: "...", description: "..." }])} />
</AfSection>

Brand Colors

  1. Always use Affinda brand colors:

    • Primary: Mist Green (#C6D5D1)
    • Text: Inkwell (#14343B)
    • Accent: Soft Clay (#B09670)
    • Bright: Ice (#A6FFF8)
  2. Use CSS custom properties:

    background: var(--colour-brand-mist-green);
    color: var(--colour-brand-inkwell);
  3. Import the tokens CSS:

    import '@affinda/tokens/tokens.css';
  4. Never use purple colors - those were placeholder colors and have been removed

AfFooter

A flexible, slot-based footer component for composing marketing page footers.

import { 
  AfFooter, 
  AfFooterColumn, 
  AfFooterLink, 
  AfSocialLink, 
  AfContactItem,
  AfLogo 
} from '@affinda/react';

<AfFooter
  copyrightText="© 2025 Your Company. All rights reserved."
  statusText="All systems are operational"
  statusUrl="https://status.example.com"
  systemsOperational={true}
  showStatus={true}
>
  {/* Logo */}
  <AfLogo slot="logo" />

  {/* Social Links */}
  <div slot="social" style={{ display: 'flex', gap: '12px' }}>
    <AfSocialLink href="https://linkedin.com/company/..." icon="linkedin" label="LinkedIn" />
    <AfSocialLink href="https://youtube.com/..." icon="youtube" label="YouTube" />
    <AfSocialLink href="https://github.com/..." icon="github" label="GitHub" />
  </div>

  {/* Contact Info */}
  <div slot="contact" style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
    <AfContactItem label="Sales enquiries" value="[email protected]" />
    <AfContactItem label="Support" value="[email protected]" />
  </div>

  {/* Navigation Columns */}
  <div slot="nav" style={{ display: 'contents' }}>
    <AfFooterColumn heading="Products">
      <AfFooterLink href="/product-a">Product A</AfFooterLink>
      <AfFooterLink href="/product-b">Product B</AfFooterLink>
    </AfFooterColumn>

    <AfFooterColumn heading="Company">
      <AfFooterLink href="/about">About</AfFooterLink>
      <AfFooterLink href="/careers">Careers</AfFooterLink>
      <AfFooterLink href="https://external.com" external>Partner Site</AfFooterLink>
    </AfFooterColumn>
  </div>

  {/* Legal Links */}
  <div slot="legal" style={{ display: 'flex', gap: '24px' }}>
    <a href="/privacy">Privacy policy</a>
    <a href="/terms">Terms of service</a>
  </div>

  {/* Certification Badges (optional) */}
  <div slot="badges">
    {/* Your certification badge SVGs or images */}
  </div>
</AfFooter>

Footer Props:

  • copyrightText: Copyright text (e.g., "© 2025 Company. All rights reserved.")
  • statusText: Status message text
  • statusUrl: Link to status page
  • systemsOperational: Boolean for green/red status indicator
  • showStatus: Whether to show the status section

Footer Slots:

  • logo: Your logo component
  • social: Social media links (use SocialLink components)
  • contact: Contact information (use ContactItem components)
  • nav: Navigation columns (use FooterColumn + FooterLink components)
  • legal: Legal/policy links
  • badges: Certification badges

Helper Components:

  • AfFooterColumn: Navigation column with heading
    • Props: heading (string)
  • AfFooterLink: Styled footer link
    • Props: href (string), external (boolean - adds external link icon)
  • AfSocialLink: Circular social media icon link
    • Props: href, label, icon ('linkedin' | 'youtube' | 'github' | 'twitter' | 'facebook' | 'custom')
  • AfContactItem: Label + value pair for contact info
    • Props: label, value

Features:

  • Dark inkwell background with mist green text
  • Fully composable via slots
  • Built-in social media icons
  • External link indicators
  • System status indicator
  • Fully responsive design

Using Illustrations

The @affinda/illustrations package provides themed illustration assets:

import { getIllustrationUrlByScene } from '@affinda/illustrations';

// Available scenes: 'document-raise', 'thinking', 'shapes', 'team-leader', 
// 'grow-business', 'document-type', 'industries', 'accuracy', 'intelligence', 
// 'page-turn', 'automate'

// Available themes: 'white-ivory', 'mist-green', 'soft-clay', 'inkwell'

<img 
  src={getIllustrationUrlByScene('automate', 'inkwell')} 
  alt="Automation illustration" 
/>

Related Packages

  • @affinda/wc - Core web components (used internally)
  • @affinda/tokens - Design tokens (colors, spacing, typography)
  • @affinda/icons - Icon library
  • @affinda/illustrations - Illustration assets (install separately: npm install @affinda/illustrations)
  • @affinda/css - Base CSS styles