Genairus logoGenAI-R-Us
Genairus logoGenAI-R-Us

Flux Design System Patterns

Version 1.0

Overview

A design system is the foundation of consistent, scalable UI development. Flux provides first-class support for design systems through Design Tokens, Component Libraries, and Theme Management. This guide covers best practices for building and maintaining design systems in Flux.


Design Tokens

Design tokens are the atomic values of your design system—colors, typography, spacing, shadows, and more. In Flux, tokens are defined once and referenced throughout your components.

Defining Design Tokens

Create a design-tokens.flux file:

designTokens {
  colors: {
    // Brand Colors
    primary: "#6366F1"
    primaryHover: "#4F46E5"
    primaryActive: "#4338CA"

    accent: "#EC4899"
    accentHover: "#DB2777"

    // Semantic Colors
    success: "#10B981"
    warning: "#F59E0B"
    error: "#EF4444"
    info: "#3B82F6"

    // Neutrals
    background: "#FFFFFF"
    surface: "#F9FAFB"
    border: "#E5E7EB"

    textPrimary: "#111827"
    textSecondary: "#6B7280"
    textMuted: "#9CA3AF"
  }

  typography: {
    // Font Families
    fontSans: "'Inter', -apple-system, sans-serif"
    fontMono: "'Fira Code', monospace"

    // Font Sizes
    textXs: 12
    textSm: 14
    textBase: 16
    textLg: 18
    textXl: 20
    text2Xl: 24
    text3Xl: 30
    text4Xl: 36

    // Font Weights
    fontLight: 300
    fontNormal: 400
    fontMedium: 500
    fontSemibold: 600
    fontBold: 700

    // Line Heights
    lineHeightTight: 1.25
    lineHeightNormal: 1.5
    lineHeightRelaxed: 1.75
  }

  spacing: {
    xs: 4
    sm: 8
    md: 16
    lg: 24
    xl: 32
    xxl: 48
    xxxl: 64
  }

  borderRadius: {
    none: 0
    sm: 4
    md: 8
    lg: 12
    full: 9999
  }

  shadows: {
    sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
    md: "0 4px 6px -1px rgba(0, 0, 0, 0.1)"
    lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1)"
    xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1)"
  }

  transitions: {
    fast: "150ms"
    normal: "300ms"
    slow: "500ms"
  }
}

Using Design Tokens

Reference tokens in your components with the $token syntax:

component Button {
  props: {
    label: String
    variant: "primary" | "secondary" = "primary"
  }

  styles: {
    // Reference color tokens
    backgroundColor: variant == "primary" ? $colors.primary : $colors.surface
    color: variant == "primary" ? "white" : $colors.textPrimary

    // Reference typography tokens
    fontSize: $typography.textBase
    fontWeight: $typography.fontSemibold
    fontFamily: $typography.fontSans

    // Reference spacing tokens
    padding: [$spacing.sm, $spacing.md]  // [vertical, horizontal]

    // Reference border radius tokens
    borderRadius: $borderRadius.md

    // Reference shadow tokens
    boxShadow: $shadows.sm

    // Reference transition tokens
    transition: $transitions.normal
  }

  layout: HStack {
    children: [
      Text { text: props.label }
    ]
  }
}

Component Variants

Design systems thrive on consistency with flexibility. Flux supports component variants to handle different visual treatments.

Size Variants

component Button {
  props: {
    label: String
    size: "sm" | "md" | "lg" = "md"
  }

  styles: {
    fontSize: {
      sm: $typography.textSm,
      md: $typography.textBase,
      lg: $typography.textLg
    }[props.size]

    padding: {
      sm: [$spacing.xs, $spacing.sm],
      md: [$spacing.sm, $spacing.md],
      lg: [$spacing.md, $spacing.lg]
    }[props.size]

    borderRadius: {
      sm: $borderRadius.sm,
      md: $borderRadius.md,
      lg: $borderRadius.lg
    }[props.size]
  }
}

Visual Variants

component Alert {
  props: {
    message: String
    variant: "success" | "warning" | "error" | "info"
  }

  styles: {
    backgroundColor: {
      success: lighten($colors.success, 0.9),
      warning: lighten($colors.warning, 0.9),
      error: lighten($colors.error, 0.9),
      info: lighten($colors.info, 0.9)
    }[props.variant]

    borderLeft: {
      width: 4,
      color: {
        success: $colors.success,
        warning: $colors.warning,
        error: $colors.error,
        info: $colors.info
      }[props.variant]
    }

    color: {
      success: darken($colors.success, 0.3),
      warning: darken($colors.warning, 0.3),
      error: darken($colors.error, 0.3),
      info: darken($colors.info, 0.3)
    }[props.variant]

    padding: $spacing.md
    borderRadius: $borderRadius.md
  }

  layout: HStack {
    spacing: $spacing.sm
    children: [
      Icon {
        name: {
          success: "check-circle",
          warning: "exclamation-triangle",
          error: "x-circle",
          info: "information-circle"
        }[props.variant]
      },
      Text { text: props.message }
    ]
  }
}

Theming

Flux supports light/dark themes and custom themes through token overrides.

Theme Definition

// themes/light.flux
theme Light {
  colors: {
    background: "#FFFFFF"
    surface: "#F9FAFB"
    border: "#E5E7EB"
    textPrimary: "#111827"
    textSecondary: "#6B7280"
    textMuted: "#9CA3AF"
  }
}

// themes/dark.flux
theme Dark {
  colors: {
    background: "#0F172A"
    surface: "#1E293B"
    border: "#334155"
    textPrimary: "#F1F5F9"
    textSecondary: "#CBD5E1"
    textMuted: "#94A3B8"
  }
}

Theme-Aware Components

Components automatically adapt to the active theme:

component Card {
  styles: {
    // These token references automatically switch with the theme
    backgroundColor: $colors.surface
    borderColor: $colors.border
    borderWidth: 1
    borderRadius: $borderRadius.lg
    padding: $spacing.lg
    boxShadow: $shadows.md
  }

  layout: VStack {
    spacing: $spacing.md
    children: props.children
  }
}

Custom Themes

// themes/brand.flux
theme BrandTheme extends Light {
  colors: {
    primary: "#FF6B6B"
    accent: "#4ECDC4"
    background: "#FFF8F0"
  }

  typography: {
    fontSans: "'Montserrat', sans-serif"
  }

  borderRadius: {
    md: 16  // More rounded than default
    lg: 24
  }
}

Component Libraries

Organize your design system into reusable component libraries.

Library Structure

design-system/
├── tokens/
│   ├── colors.flux
│   ├── typography.flux
│   ├── spacing.flux
│   └── shadows.flux
├── themes/
│   ├── light.flux
│   ├── dark.flux
│   └── brand.flux
├── primitives/
│   ├── Button.flux
│   ├── Input.flux
│   ├── Text.flux
│   └── Icon.flux
├── components/
│   ├── Card.flux
│   ├── Modal.flux
│   ├── Alert.flux
│   └── Dropdown.flux
└── patterns/
    ├── Form.flux
    ├── Table.flux
    └── Navigation.flux

Exporting a Library

// index.flux
library MyDesignSystem {
  version: "1.0.0"

  // Export tokens
  export tokens from "./tokens"
  export themes from "./themes"

  // Export components
  export { Button, Input, Text, Icon } from "./primitives"
  export { Card, Modal, Alert, Dropdown } from "./components"
  export { Form, Table, Navigation } from "./patterns"
}

Consuming a Library

// In your app
import { Button, Card, Alert } from "@mycompany/design-system"

component Dashboard {
  layout: VStack {
    children: [
      Card {
        children: [
          Alert {
            variant: "info"
            message: "Welcome to the dashboard!"
          }
        ]
      },

      Button {
        label: "Get Started"
        size: "lg"
      }
    ]
  }
}

Composition Patterns

The Container Pattern

component Container {
  props: {
    maxWidth: "sm" | "md" | "lg" | "xl" | "full" = "lg"
  }

  styles: {
    maxWidth: {
      sm: 640,
      md: 768,
      lg: 1024,
      xl: 1280,
      full: "100%"
    }[props.maxWidth]

    marginHorizontal: "auto"
    paddingHorizontal: $spacing.md
  }

  layout: VStack {
    children: props.children
  }
}

The Stack Pattern

component Stack {
  props: {
    direction: "vertical" | "horizontal" = "vertical"
    spacing: Integer = $spacing.md
    alignment: "start" | "center" | "end" = "start"
  }

  layout: props.direction == "vertical" ? VStack : HStack {
    spacing: props.spacing
    alignment: props.alignment
    children: props.children
  }
}

The Grid Pattern

component Grid {
  props: {
    columns: Integer = 12
    gap: Integer = $spacing.md
  }

  layout: Grid {
    columns: props.columns
    gap: props.gap
    children: props.children
  }
}

component GridItem {
  props: {
    span: Integer = 1
    start?: Integer
  }

  styles: {
    gridColumn: props.start
      ? `${props.start} / span ${props.span}`
      : `span ${props.span}`
  }

  layout: VStack {
    children: props.children
  }
}

Responsive Design

Breakpoints

Define responsive breakpoints in your design tokens:

designTokens {
  breakpoints: {
    sm: 640
    md: 768
    lg: 1024
    xl: 1280
    xxl: 1536
  }
}

Responsive Styles

component Hero {
  styles: {
    padding: {
      base: $spacing.md,
      md: $spacing.lg,
      lg: $spacing.xl,
      xl: $spacing.xxl
    }

    fontSize: {
      base: $typography.text2Xl,
      md: $typography.text3Xl,
      lg: $typography.text4Xl
    }
  }

  layout: VStack {
    children: [
      Text {
        text: "Welcome"
        style: "responsive"
      }
    ]
  }
}

Responsive Layouts

component ResponsiveGrid {
  layout: Grid {
    columns: {
      base: 1,      // 1 column on mobile
      sm: 2,        // 2 columns on small screens
      md: 3,        // 3 columns on medium screens
      lg: 4         // 4 columns on large screens
    }

    gap: $spacing.md
    children: props.items
  }
}

Accessibility

Focus States

component Button {
  styles: {
    // Default styles
    backgroundColor: $colors.primary
    color: "white"

    // Hover state
    '&:hover': {
      backgroundColor: $colors.primaryHover
    }

    // Focus state
    '&:focus': {
      outline: `2px solid ${$colors.primary}`
      outlineOffset: 2
    }

    // Active state
    '&:active': {
      backgroundColor: $colors.primaryActive
    }

    // Disabled state
    '&:disabled': {
      backgroundColor: $colors.border
      color: $colors.textMuted
      cursor: "not-allowed"
    }
  }

  // ARIA attributes
  accessibility: {
    role: "button"
    ariaLabel: props.label
    ariaDisabled: props.disabled
  }
}

Color Contrast

Ensure WCAG compliance:

designTokens {
  colors: {
    // All text/background combinations meet WCAG AA
    primary: "#6366F1"  // Contrast ratio: 4.5:1 with white
    textPrimary: "#111827"  // Contrast ratio: 16:1 with white
    textSecondary: "#6B7280"  // Contrast ratio: 4.6:1 with white
  }
}

// Validate at compile time
@validateContrast(minRatio: 4.5)
component Alert {
  styles: {
    backgroundColor: $colors.surface
    color: $colors.textPrimary
  }
}

Semantic HTML

component Heading {
  props: {
    text: String
    level: 1 | 2 | 3 | 4 | 5 | 6 = 1
  }

  // Generates <h1>, <h2>, etc. based on level
  element: `h${props.level}`

  styles: {
    fontSize: {
      1: $typography.text4Xl,
      2: $typography.text3Xl,
      3: $typography.text2Xl,
      4: $typography.textXl,
      5: $typography.textLg,
      6: $typography.textBase
    }[props.level]

    fontWeight: $typography.fontBold
  }
}

Documentation

Component Documentation

Use JSDoc-style comments to document your components:

/**
 * Primary button component for user actions.
 *
 * @example
 * Button {
 *   label: "Click me"
 *   variant: "primary"
 *   size: "md"
 *   onClick: handleClick
 * }
 */
component Button {
  props: {
    /** The text displayed on the button */
    label: String

    /** Visual style variant */
    variant: "primary" | "secondary" = "primary"

    /** Size of the button */
    size: "sm" | "md" | "lg" = "md"

    /** Click handler function */
    onClick: Handler
  }
}

Generating Documentation

# Generate documentation site
flux docs generate --output ./docs

# Generate Storybook stories
flux storybook generate --output ./stories

# Generate Figma design tokens
flux figma export --output ./figma-tokens.json

Versioning and Evolution

Semantic Versioning

library MyDesignSystem {
  version: "2.1.0"  // Major.Minor.Patch

  // Breaking changes increment major version
  // New features increment minor version
  // Bug fixes increment patch version
}

Deprecation Warnings

/**
 * @deprecated Use `Button` with `variant="text"` instead
 */
component TextButton {
  // ... implementation
}

Migration Path

// v1.x
component OldButton {
  props: {
    type: "primary" | "secondary"
  }
}

// v2.x - backward compatible alias
component OldButton = Button {
  variant: props.type  // Map old prop to new prop
}

// v3.x - remove deprecated component
// OldButton removed, users must migrate to Button

Best Practices

  1. Start with Tokens - Define your design tokens before building components
  2. Compose Components - Build complex components from simple primitives
  3. Think in Systems - Design for reusability and consistency
  4. Document Everything - Good documentation is essential for adoption
  5. Version Carefully - Use semantic versioning and provide migration guides
  6. Test Across Platforms - Ensure components work on all target frameworks
  7. Measure Adoption - Track which components are used and improve based on data
  8. Iterate Often - Design systems evolve—embrace continuous improvement

Further Reading