Catch unexpected visual changes & UI bugs in your stories
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Predefined visual testing configurations for different themes, viewports, and layout options to ensure comprehensive visual coverage.
Standard visual testing modes with light and dark theme support.
/**
* Base visual testing modes for theme variations
* Object with Light and Dark mode configurations
*/
declare const baseModes: {
Light: { theme: 'light'; viewport: 'default' };
Dark: { theme: 'dark'; viewport: 'default' };
};The baseModes object contains:
Usage Example:
// Apply base modes to all stories
export default {
title: 'Components/Button',
component: Button,
parameters: {
chromatic: {
modes: {
light: baseModes.find(mode => mode.name === 'light'),
dark: baseModes.find(mode => mode.name === 'dark'),
},
},
},
};Advanced visual testing modes including 2-up panel layouts for side-by-side comparisons.
/**
* Panel-specific visual testing modes
* Object with disabled states and 2-up layout configurations
*/
declare const panelModes: {
Light: { disabled: true };
Dark: { disabled: true };
'Right 2-up': { theme: 'right'; viewport: 'default' };
'Bottom 2-up': { theme: 'bottom'; viewport: 'default' };
};The panelModes object contains:
Panel Mode Configurations:
interface PanelModeConfig extends VisualTestMode {
/** Panel layout type */
layout?: 'right-2up' | 'bottom-2up';
/** Whether interactions are disabled */
disabled?: boolean;
/** Multiple viewport configurations for 2-up layouts */
viewports?: ViewportConfig[];
/** Multiple theme configurations for 2-up layouts */
themes?: string[];
}Usage Examples:
// Use panel modes for complex component testing
export const ComplexComponent = {
parameters: {
chromatic: {
modes: {
'light-disabled': {
theme: 'light',
disabled: true,
},
'right-2up': {
layout: 'right-2up',
themes: ['light', 'dark'],
viewport: { width: 1200, height: 800 },
},
'bottom-2up': {
layout: 'bottom-2up',
viewports: [
{ width: 375, height: 667 }, // Mobile
{ width: 1200, height: 800 }, // Desktop
],
},
},
},
},
};Create custom visual testing modes for specific testing scenarios.
/**
* Create a custom visual test mode
* @param config - Mode configuration object
* @returns Configured visual test mode
*/
function createVisualTestMode(config: VisualTestModeConfig): VisualTestMode;
interface VisualTestModeConfig {
/** Unique mode name */
name: string;
/** Viewport configuration */
viewport?: ViewportConfig;
/** Theme identifier */
theme?: string;
/** CSS media query for responsive testing */
mediaQuery?: string;
/** Animation pause settings */
pauseAnimationAtEnd?: boolean;
/** Delay before capturing screenshot */
delay?: number;
/** Custom CSS to inject */
css?: string;
/** Custom JavaScript to execute */
javascript?: string;
/** Additional parameters */
[key: string]: any;
}Usage Examples:
// Custom responsive testing modes
const customModes = {
mobile: {
name: 'mobile',
viewport: { width: 375, height: 667 },
theme: 'light',
},
tablet: {
name: 'tablet',
viewport: { width: 768, height: 1024 },
theme: 'light',
},
desktop: {
name: 'desktop',
viewport: { width: 1200, height: 800 },
theme: 'light',
},
'dark-mobile': {
name: 'dark-mobile',
viewport: { width: 375, height: 667 },
theme: 'dark',
},
};
// Animation-specific modes
const animationModes = {
'animation-start': {
name: 'animation-start',
delay: 0,
pauseAnimationAtEnd: false,
},
'animation-end': {
name: 'animation-end',
delay: 2000,
pauseAnimationAtEnd: true,
},
};
// Apply custom modes to stories
export const ResponsiveComponent = {
parameters: {
chromatic: {
modes: customModes,
},
},
};
export const AnimatedComponent = {
parameters: {
chromatic: {
modes: animationModes,
},
},
};Helper functions for working with visual test modes.
/**
* Merge multiple mode configurations
* @param modes - Array of mode objects to merge
* @returns Combined mode configuration
*/
function mergeModes(...modes: Record<string, VisualTestMode>[]): Record<string, VisualTestMode>;
/**
* Filter modes by criteria
* @param modes - Modes object to filter
* @param criteria - Filter function
* @returns Filtered modes object
*/
function filterModes(
modes: Record<string, VisualTestMode>,
criteria: (mode: VisualTestMode) => boolean
): Record<string, VisualTestMode>;
/**
* Get viewport dimensions for a mode
* @param mode - Visual test mode
* @returns Viewport configuration or default
*/
function getViewport(mode: VisualTestMode): ViewportConfig;Usage Examples:
import { mergeModes, filterModes } from '@chromatic-com/storybook';
// Merge base modes with custom modes
const allModes = mergeModes(
{ light: baseModes[0], dark: baseModes[1] },
customModes,
animationModes
);
// Filter modes by viewport width
const mobileOnlyModes = filterModes(allModes, (mode) => {
const viewport = getViewport(mode);
return viewport.width <= 768;
});
// Use filtered modes
export const MobileComponent = {
parameters: {
chromatic: {
modes: mobileOnlyModes,
},
},
};Configure modes globally for all stories in your Storybook.
/**
* Global mode configuration interface
*/
interface GlobalModeConfig {
/** Default modes applied to all stories */
default?: Record<string, VisualTestMode>;
/** Modes applied only to specific story kinds */
perKind?: Record<string, Record<string, VisualTestMode>>;
/** Modes excluded from specific stories */
exclude?: Record<string, string[]>;
}Usage Example:
// .storybook/main.ts
export default {
parameters: {
chromatic: {
modes: {
// Apply to all stories by default
light: { theme: 'light' },
dark: { theme: 'dark' },
mobile: {
viewport: { width: 375, height: 667 },
theme: 'light'
},
},
},
},
};
// Override for specific story kinds
export default {
title: 'Components/Complex',
parameters: {
chromatic: {
modes: {
// Inherit global modes and add specific ones
...globalModes,
'high-contrast': {
theme: 'high-contrast',
css: 'filter: contrast(2);',
},
},
},
},
};