Skip to main content
The Backgrounds addon allows you to change the background color behind your stories, making it easier to test component appearance against different backgrounds.

Installation

npm install @storybook/addon-ondevice-backgrounds

Setup

Register the addon in your .storybook/main.ts:
import type { StorybookConfig } from '@storybook/react-native';

const main: StorybookConfig = {
  addons: [
    '@storybook/addon-ondevice-backgrounds',
  ],
};

export default main;

Usage

Define background options in your story parameters:
import type { Meta, StoryObj } from '@storybook/react-native';
import { Text, StyleSheet } from 'react-native';

const TextComponent = () => (
  <Text style={styles.text}>This text adapts to different backgrounds</Text>
);

const meta = {
  component: TextComponent,
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#FFFFFF' },
        dark: { name: 'Dark', value: '#000000' },
        brand: { name: 'Brand', value: '#3B82F6' },
      },
    },
  },
} satisfies Meta<typeof TextComponent>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Basic: Story = {
  globals: {
    backgrounds: { value: 'light' },
  },
};

const styles = StyleSheet.create({
  text: { 
    color: 'black',
    fontSize: 16,
  },
});

Parameters

backgrounds
object
Background configuration
options
Record<string, BackgroundOption>
required
Available background options
interface BackgroundOption {
  name: string;  // Display name in the UI
  value: string; // CSS color value
}
default
string
deprecated
Default background to use (key from options)
Deprecated: Use globals.backgrounds.value instead

Global Configuration

Set a background for a specific story:
export const DarkBackground: Story = {
  globals: {
    backgrounds: { value: 'dark' },
  },
};

Examples

Basic Configuration

import type { Meta, StoryObj } from '@storybook/react-native';
import { Text, StyleSheet } from 'react-native';

const Background = () => (
  <Text style={styles.text}>Change background via Addons → Backgrounds</Text>
);

const meta = {
  component: Background,
  parameters: {
    backgrounds: {
      options: {
        warm: { name: 'Warm', value: 'hotpink' },
        cool: { name: 'Cool', value: 'deepskyblue' },
        white: { name: 'White', value: 'white' },
        black: { name: 'Black', value: 'black' },
      },
    },
  },
} satisfies Meta<typeof Background>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Basic: Story = {
  globals: {
    backgrounds: { value: 'warm' },
  },
};

const styles = StyleSheet.create({
  text: { color: 'black' },
});

Themed Card Example

import { View, Text, StyleSheet } from 'react-native';

interface CardProps {
  title: string;
  content: string;
}

const Card = ({ title, content }: CardProps) => (
  <View style={styles.card}>
    <Text style={styles.title}>{title}</Text>
    <Text style={styles.content}>{content}</Text>
  </View>
);

const meta = {
  component: Card,
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light Gray', value: '#F3F4F6' },
        medium: { name: 'Medium Gray', value: '#9CA3AF' },
        dark: { name: 'Dark Gray', value: '#1F2937' },
        brand: { name: 'Brand Blue', value: '#3B82F6' },
      },
    },
  },
} satisfies Meta<typeof Card>;

export default meta;

type Story = StoryObj<typeof meta>;

export const OnLight: Story = {
  args: {
    title: 'Card Title',
    content: 'This card looks great on light backgrounds',
  },
  globals: {
    backgrounds: { value: 'light' },
  },
};

export const OnDark: Story = {
  args: {
    title: 'Card Title',
    content: 'This card also works on dark backgrounds',
  },
  globals: {
    backgrounds: { value: 'dark' },
  },
};

const styles = StyleSheet.create({
  card: {
    backgroundColor: 'white',
    padding: 20,
    borderRadius: 12,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3,
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    marginBottom: 8,
  },
  content: {
    fontSize: 14,
    color: '#666',
  },
});

Brand Colors

const meta = {
  component: Logo,
  parameters: {
    backgrounds: {
      options: {
        primary: { name: 'Primary', value: '#3B82F6' },
        secondary: { name: 'Secondary', value: '#10B981' },
        accent: { name: 'Accent', value: '#F59E0B' },
        neutral: { name: 'Neutral', value: '#6B7280' },
        white: { name: 'White', value: '#FFFFFF' },
      },
    },
  },
} satisfies Meta<typeof Logo>;

Gradient Backgrounds

While the addon directly supports solid colors, you can test components against gradient backgrounds:
import { LinearGradient } from 'expo-linear-gradient';

const meta = {
  component: Hero,
  decorators: [
    (Story, context) => {
      const gradients = {
        sunset: ['#FF6B6B', '#FFD93D'],
        ocean: ['#667EEA', '#764BA2'],
        forest: ['#134E5E', '#71B280'],
      };
      
      const selectedGradient = context.globals?.backgrounds?.value;
      const colors = gradients[selectedGradient] || ['transparent', 'transparent'];
      
      return (
        <LinearGradient colors={colors} style={{ flex: 1 }}>
          <Story />
        </LinearGradient>
      );
    },
  ],
  parameters: {
    backgrounds: {
      options: {
        sunset: { name: 'Sunset', value: 'sunset' },
        ocean: { name: 'Ocean', value: 'ocean' },
        forest: { name: 'Forest', value: 'forest' },
      },
    },
  },
} satisfies Meta<typeof Hero>;

Background Interface

interface Background {
  name: string;  // Display name (e.g., "Dark Mode")
  value: string; // Color value (e.g., "#000000", "rgb(0,0,0)", "black")
}

Supported Color Formats

The addon accepts any valid CSS color value:
  • Hex: #3B82F6, #000
  • RGB: rgb(59, 130, 246)
  • RGBA: rgba(59, 130, 246, 0.5)
  • Named colors: white, black, red, hotpink
  • HSL: hsl(217, 91%, 60%)
  • HSLA: hsla(217, 91%, 60%, 0.8)

Using the Backgrounds Panel

  1. Navigate to the Addons panel
  2. Select the “Backgrounds” tab
  3. Click on a swatch to change the background
  4. The story will re-render with the new background color

Disabling for Specific Stories

Disable backgrounds for specific stories:
export const NoBackground: Story = {
  parameters: {
    backgrounds: { disable: true },
  },
};

Global Configuration

Set default backgrounds for all stories in .storybook/preview.tsx:
import type { Preview } from '@storybook/react-native';

const preview: Preview = {
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#FFFFFF' },
        dark: { name: 'Dark', value: '#000000' },
        gray: { name: 'Gray', value: '#F3F4F6' },
      },
    },
  },
  globals: {
    backgrounds: { value: 'light' },
  },
};

export default preview;

Programmatic Access

Access the current background in your component:
import { useGlobals } from '@storybook/preview-api';

function AdaptiveComponent() {
  const [globals] = useGlobals();
  const backgroundColor = globals.backgrounds?.value;
  
  return (
    <Text style={{ color: backgroundColor === 'dark' ? 'white' : 'black' }}>
      Adaptive text color
    </Text>
  );
}

Deprecated API

The old API using default and values is deprecated:
// ❌ Deprecated
parameters: {
  backgrounds: {
    default: 'dark',
    values: [
      { name: 'light', value: '#FFF' },
      { name: 'dark', value: '#000' },
    ],
  },
}

// ✅ Use this instead
parameters: {
  backgrounds: {
    options: {
      light: { name: 'Light', value: '#FFF' },
      dark: { name: 'Dark', value: '#000' },
    },
  },
}

Build docs developers (and LLMs) love