or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

component-theming.mdconfig.mdcss-processing.mdindex.mdpseudo-responsive.mdtheme-vars.md
tile.json

component-theming.mddocs/

Component Theming and Style Definitions

Comprehensive theming system for defining component styles with variants, sizes, multi-part component support, and responsive theming props. This system enables consistent, theme-aware component styling with powerful customization options.

Capabilities

Style Definition Utilities

Core utilities for defining component styles with type safety and theme integration.

/**
 * Props passed to style functions for theme-aware styling
 */
interface StyleFunctionProps {
  colorScheme: string;
  colorMode: "light" | "dark";
  orientation?: "horizontal" | "vertical";
  theme: Record<string, any>;
  [key: string]: any;
}

/**
 * Function that returns system styles based on props
 */
type SystemStyleFunction = (props: StyleFunctionProps) => SystemStyleObject;

/**
 * Style object or function that can be used in component definitions
 */
type SystemStyleInterpolation = SystemStyleObject | SystemStyleFunction;

/**
 * Defines component styles with type safety
 * @param styles - Style object or function
 * @returns The same styles with proper typing
 */
function defineStyle<T extends SystemStyleInterpolation>(styles: T): T;

Usage Examples:

import { defineStyle, SystemStyleFunction } from "@chakra-ui/styled-system";

// Static style definition
const staticButtonStyle = defineStyle({
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "center",
  borderRadius: "md",
  fontWeight: "semibold",
  transition: "all 0.2s",
  
  _hover: {
    transform: "translateY(-2px)",
    boxShadow: "lg"
  },
  
  _active: {
    transform: "translateY(0)"
  }
});

// Dynamic style function
const dynamicButtonStyle = defineStyle<SystemStyleFunction>(({ 
  colorScheme, 
  colorMode, 
  theme 
}) => ({
  bg: `${colorScheme}.500`,
  color: colorMode === "dark" ? "white" : "black",
  borderColor: `${colorScheme}.600`,
  
  _hover: {
    bg: `${colorScheme}.600`,
    _disabled: {
      bg: `${colorScheme}.500`
    }
  },
  
  _dark: {
    bg: `${colorScheme}.200`,
    color: "gray.800"
  }
}));

// Responsive style definition
const responsiveStyle = defineStyle({
  fontSize: { base: "sm", md: "md", lg: "lg" },
  px: { base: 3, md: 4, lg: 6 },
  py: { base: 2, md: 3 },
  
  // Responsive pseudo-selectors
  _hover: {
    bg: { base: "gray.100", _dark: "gray.700" }
  }
});

Single-Part Component Configuration

Configuration system for single-part components with variants, sizes, and default props.

/**
 * Configuration for single-part component theming
 */
interface StyleConfig {
  baseStyle?: SystemStyleInterpolation;
  sizes?: { [size: string]: SystemStyleInterpolation };
  variants?: { [variant: string]: SystemStyleInterpolation };
  defaultProps?: {
    size?: string;
    variant?: string;
    colorScheme?: string;
  };
}

/**
 * Defines style configuration for single-part components
 * @param config - Component style configuration
 * @returns Typed style configuration object
 */
function defineStyleConfig<
  BaseStyle extends SystemStyleInterpolation,
  Sizes extends Record<string, SystemStyleInterpolation>,
  Variants extends Record<string, SystemStyleInterpolation>
>(config: {
  baseStyle?: BaseStyle;
  sizes?: Sizes;
  variants?: Variants;
  defaultProps?: {
    size?: keyof Sizes;
    variant?: keyof Variants;
    colorScheme?: string;
  };
}): StyleConfig;

Usage Examples:

import { defineStyleConfig, SystemStyleFunction } from "@chakra-ui/styled-system";

// Complete button configuration
const Button = defineStyleConfig({
  // Base styles applied to all variants and sizes
  baseStyle: {
    display: "inline-flex",
    alignItems: "center",
    justifyContent: "center",
    borderRadius: "md",
    fontWeight: "semibold",
    transition: "all 0.2s",
    cursor: "pointer",
    
    _disabled: {
      opacity: 0.4,
      cursor: "not-allowed"
    }
  },
  
  // Size variants
  sizes: {
    xs: { fontSize: "xs", px: 2, py: 1, h: 6 },
    sm: { fontSize: "sm", px: 3, py: 2, h: 8 },
    md: { fontSize: "md", px: 4, py: 2, h: 10 },
    lg: { fontSize: "lg", px: 6, py: 3, h: 12 },
    xl: { fontSize: "xl", px: 8, py: 4, h: 14 }
  },
  
  // Variant styles with color scheme support
  variants: {
    solid: ({ colorScheme }: StyleFunctionProps) => ({
      bg: `${colorScheme}.500`,
      color: "white",
      _hover: {
        bg: `${colorScheme}.600`,
        _disabled: { bg: `${colorScheme}.500` }
      },
      _active: { bg: `${colorScheme}.700` }
    }),
    
    outline: ({ colorScheme }: StyleFunctionProps) => ({
      border: "1px solid",
      borderColor: `${colorScheme}.500`,
      color: `${colorScheme}.500`,
      bg: "transparent",
      _hover: {
        bg: `${colorScheme}.50`,
        _dark: { bg: `${colorScheme}.900` }
      }
    }),
    
    ghost: ({ colorScheme }: StyleFunctionProps) => ({
      bg: "transparent",
      color: `${colorScheme}.500`,
      _hover: {
        bg: `${colorScheme}.100`,
        _dark: { bg: `${colorScheme}.800` }
      }
    }),
    
    link: ({ colorScheme }: StyleFunctionProps) => ({
      color: `${colorScheme}.500`,
      _hover: {
        textDecoration: "underline"
      }
    })
  },
  
  // Default values
  defaultProps: {
    size: "md",
    variant: "solid",
    colorScheme: "gray"
  }
});

// Input field configuration
const Input = defineStyleConfig({
  baseStyle: {
    field: {
      width: "100%",
      minWidth: 0,
      outline: 0,
      position: "relative",
      appearance: "none",
      transition: "all 0.2s"
    }
  },
  
  sizes: {
    lg: { field: { fontSize: "lg", px: 4, h: 12, borderRadius: "md" } },
    md: { field: { fontSize: "md", px: 4, h: 10, borderRadius: "md" } },
    sm: { field: { fontSize: "sm", px: 3, h: 8, borderRadius: "sm" } },
    xs: { field: { fontSize: "xs", px: 2, h: 6, borderRadius: "sm" } }
  },
  
  variants: {
    outline: {
      field: {
        border: "1px solid",
        borderColor: "inherit",
        bg: "inherit",
        _hover: { borderColor: "gray.300" },
        _focus: { 
          borderColor: "blue.500",
          boxShadow: "0 0 0 1px var(--chakra-colors-blue-500)"
        }
      }
    },
    
    filled: {
      field: {
        border: "2px solid",
        borderColor: "transparent", 
        bg: "gray.100",
        _hover: { bg: "gray.200" },
        _focus: {
          bg: "white",
          borderColor: "blue.500"
        }
      }
    }
  },
  
  defaultProps: {
    size: "md",
    variant: "outline"
  }
});

Multi-Part Component Configuration

Configuration system for multi-part components with anatomical part definitions and coordinated styling.

/**
 * Anatomy definition for multi-part components
 */
type Anatomy = { keys: string[] };

/**
 * Style object for multiple component parts
 */
type PartsStyleObject<Parts extends Anatomy = Anatomy> = Partial<
  Record<Parts["keys"][number], SystemStyleObject>
>;

/**
 * Function that returns multi-part styles
 */
type PartsStyleFunction<Parts extends Anatomy = Anatomy> = (
  props: StyleFunctionProps
) => PartsStyleObject<Parts>;

/**
 * Multi-part style interpolation (object or function)
 */
type PartsStyleInterpolation<Parts extends Anatomy = Anatomy> =
  | PartsStyleObject<Parts>
  | PartsStyleFunction<Parts>;

/**
 * Configuration interface for multi-part components
 */
interface MultiStyleConfig<Parts extends Anatomy = Anatomy> {
  parts: Parts["keys"];
  baseStyle?: PartsStyleInterpolation<Parts>;
  sizes?: { [size: string]: PartsStyleInterpolation<Parts> };
  variants?: { [variant: string]: PartsStyleInterpolation<Parts> };
  defaultProps?: {
    size?: string;
    variant?: string;
    colorScheme?: string;
  };
}

/**
 * Creates helpers for defining multi-part component configurations
 * @param parts - Array of component part names
 * @returns Helper functions for multi-part theming
 */
function createMultiStyleConfigHelpers<Part extends string>(
  parts: Part[] | Readonly<Part[]>
): {
  definePartsStyle<PartStyles extends PartsStyleInterpolation<{ keys: Part[] }>>(
    config: PartStyles
  ): PartStyles;
  defineMultiStyleConfig<
    BaseStyle extends PartsStyleInterpolation<{ keys: Part[] }>,
    Sizes extends Record<string, PartsStyleInterpolation<{ keys: Part[] }>>,
    Variants extends Record<string, PartsStyleInterpolation<{ keys: Part[] }>>
  >(config: {
    baseStyle?: BaseStyle;
    sizes?: Sizes;
    variants?: Variants;
    defaultProps?: {
      size?: keyof Sizes;
      variant?: keyof Variants;
      colorScheme?: string;
    };
  }): MultiStyleConfig<{ keys: Part[] }>;
};

Usage Examples:

import { createMultiStyleConfigHelpers } from "@chakra-ui/styled-system";

// Modal component anatomy
const modalParts = ["overlay", "dialogContainer", "dialog", "header", "body", "footer"] as const;
const { definePartsStyle, defineMultiStyleConfig } = 
  createMultiStyleConfigHelpers(modalParts);

// Define multi-part styles
const baseModalStyle = definePartsStyle({
  overlay: {
    position: "fixed",
    inset: 0,
    bg: "blackAlpha.600",
    zIndex: "overlay"
  },
  
  dialogContainer: {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    position: "fixed",
    inset: 0,
    zIndex: "modal",
    p: 4
  },
  
  dialog: {
    borderRadius: "lg",
    bg: "white",
    color: "inherit",
    boxShadow: "lg",
    width: "100%",
    position: "relative",
    _dark: {
      bg: "gray.700"
    }
  },
  
  header: {
    px: 6,
    py: 4,
    fontSize: "xl",
    fontWeight: "semibold"
  },
  
  body: {
    px: 6,
    py: 2,
    flex: 1
  },
  
  footer: {
    px: 6,
    py: 4
  }
});

// Size variants for multi-part component
const modalSizes = {
  xs: definePartsStyle({
    dialog: { maxW: "xs" }
  }),
  
  sm: definePartsStyle({
    dialog: { maxW: "sm" }
  }),
  
  md: definePartsStyle({
    dialog: { maxW: "md" }
  }),
  
  lg: definePartsStyle({
    dialog: { maxW: "lg" }
  }),
  
  xl: definePartsStyle({
    dialog: { maxW: "xl" }
  }),
  
  full: definePartsStyle({
    dialog: { 
      maxW: "100vw",
      minH: "100vh",
      borderRadius: 0
    }
  })
};

// Complete multi-part configuration
const Modal = defineMultiStyleConfig({
  baseStyle: baseModalStyle,
  sizes: modalSizes,
  defaultProps: {
    size: "md"
  }
});

// Card component with dynamic styling
const cardParts = ["container", "header", "body", "footer"] as const;
const cardHelpers = createMultiStyleConfigHelpers(cardParts);

const Card = cardHelpers.defineMultiStyleConfig({
  baseStyle: cardHelpers.definePartsStyle(({ colorScheme }) => ({
    container: {
      borderRadius: "lg",
      overflow: "hidden",
      boxShadow: "base",
      bg: "white",
      _dark: { bg: "gray.800" }
    },
    
    header: {
      borderBottom: "1px solid",
      borderColor: "gray.200",
      px: 4,
      py: 3,
      bg: `${colorScheme}.50`,
      _dark: { 
        bg: `${colorScheme}.900`,
        borderColor: "gray.600"
      }
    },
    
    body: {
      p: 4
    },
    
    footer: {
      borderTop: "1px solid", 
      borderColor: "gray.200",
      px: 4,
      py: 3,
      bg: "gray.50",
      _dark: {
        bg: "gray.700",
        borderColor: "gray.600"
      }
    }
  })),
  
  variants: {
    elevated: cardHelpers.definePartsStyle({
      container: {
        boxShadow: "lg",
        border: "1px solid",
        borderColor: "gray.200",
        _dark: { borderColor: "gray.600" }
      }
    }),
    
    outline: cardHelpers.definePartsStyle({
      container: {
        boxShadow: "none",
        border: "1px solid", 
        borderColor: "gray.200",
        _dark: { borderColor: "gray.600" }
      }
    })
  },
  
  defaultProps: {
    variant: "elevated",
    colorScheme: "gray"
  }
});

Style Configuration Resolution

Utilities for resolving and applying component style configurations with responsive support.

/**
 * Values passed to style configuration resolution
 */
interface StyleConfigValues {
  theme: WithCSSVar<Record<string, any>>;
  variant?: ResponsiveValue<string>;
  size?: ResponsiveValue<string>;
  colorScheme?: string;
  [key: string]: any;
}

/**
 * Resolves component style configuration into final styles
 * @param config - Component style configuration
 * @returns Function that resolves styles based on props
 */
function resolveStyleConfig(config: StyleConfig): (
  props: StyleConfigValues
) => Record<string, any>;

Usage Examples:

import { resolveStyleConfig } from "@chakra-ui/styled-system";

// Using the button config from above
const buttonStyleResolver = resolveStyleConfig(Button);

// Resolve styles for specific props
const buttonStyles = buttonStyleResolver({
  theme: myTheme,
  variant: "solid",
  size: "md", 
  colorScheme: "blue"
});

// Responsive variant and size
const responsiveButtonStyles = buttonStyleResolver({
  theme: myTheme,
  variant: { base: "outline", md: "solid" },
  size: { base: "sm", md: "md", lg: "lg" },
  colorScheme: "green"
});

// Custom style resolution function
function createComponentStyles(
  config: StyleConfig,
  defaultProps: Record<string, any> = {}
) {
  const resolver = resolveStyleConfig(config);
  
  return (props: Record<string, any>) => {
    const finalProps = { ...defaultProps, ...props };
    return resolver(finalProps);
  };
}

// Usage in component
function MyButton(props: ButtonProps) {
  const styles = buttonStyleResolver({
    theme: useTheme(),
    ...props
  });
  
  return <button style={styles} {...props} />;
}

Theming Props Interface

Type-safe theming properties for component configuration with theme typing support.

/**
 * Theming properties interface for components
 */
interface ThemingProps<ThemeComponent extends string = any> {
  /** Component variant */
  variant?: ResponsiveValue<
    ThemeComponent extends keyof ThemeTypings["components"]
      ? ThemeTypings["components"][ThemeComponent]["variants"]
      : string
  >;
  
  /** Component size */
  size?: ResponsiveValue<
    ThemeComponent extends keyof ThemeTypings["components"]
      ? ThemeTypings["components"][ThemeComponent]["sizes"]  
      : string
  >;
  
  /** Color scheme for theming */
  colorScheme?: ThemeTypings["colorSchemes"];
  
  /** Component orientation */
  orientation?: "vertical" | "horizontal";
  
  /** Custom style configuration override */
  styleConfig?: Record<string, any>;
}

/**
 * Removes theming props from component props object
 * @param props - Component props including theming props
 * @returns Props object without theming-specific properties
 */
function omitThemingProps<T extends ThemingProps>(
  props: T
): Omit<T, "styleConfig" | "size" | "variant" | "colorScheme">;

Usage Examples:

import { ThemingProps, omitThemingProps } from "@chakra-ui/styled-system";

// Component with theming props
interface ButtonProps extends ThemingProps<"Button"> {
  children: React.ReactNode;
  onClick?: () => void;
  disabled?: boolean;
}

function Button(props: ButtonProps) {
  const { children, ...rest } = props;
  
  // Separate theming props from other props
  const themingProps = {
    variant: props.variant,
    size: props.size,
    colorScheme: props.colorScheme
  };
  
  // Get props without theming-specific ones
  const componentProps = omitThemingProps(rest);
  
  // Resolve styles
  const styles = buttonStyleResolver({
    theme: useTheme(),
    ...themingProps
  });
  
  return (
    <button style={styles} {...componentProps}>
      {children}
    </button>
  );
}

// Usage with type safety
<Button 
  variant="solid"          // ✓ Valid variant
  size="lg"               // ✓ Valid size  
  colorScheme="blue"      // ✓ Valid color scheme
  onClick={handleClick}   // ✓ Regular prop
  customProp="value"      // ✓ Passes through
/>

// Generic theming component
interface ThemedComponentProps<T extends string> extends ThemingProps<T> {
  component: T;
  children: React.ReactNode;
  [key: string]: any;
}

function ThemedComponent<T extends string>({ 
  component, 
  children, 
  ...props 
}: ThemedComponentProps<T>) {
  const themingProps = {
    variant: props.variant,
    size: props.size,
    colorScheme: props.colorScheme
  };
  
  const otherProps = omitThemingProps(props);
  
  // Get component config from theme
  const config = useTheme().components[component];
  const styles = resolveStyleConfig(config)(themingProps);
  
  return <div style={styles} {...otherProps}>{children}</div>;
}

Import Examples:

// Import all component theming utilities
import {
  defineStyle,
  defineStyleConfig, 
  createMultiStyleConfigHelpers,
  resolveStyleConfig,
  ThemingProps,
  omitThemingProps
} from "@chakra-ui/styled-system";

// Import specific modules
import { defineStyleConfig } from "@chakra-ui/styled-system/define-styles";
import { ThemingProps } from "@chakra-ui/styled-system/theming-props";

// Import types
import type {
  StyleConfig,
  MultiStyleConfig,
  SystemStyleFunction,
  StyleFunctionProps,
  PartsStyleObject,
  PartsStyleFunction
} from "@chakra-ui/styled-system";