customization
patterns

Customizing Patterns

Panda provides the ability to customize the built-in patterns, as well as creating your own custom patterns. This is useful to create your own layout pattern abstractions that can be used in your application.

Panda allows you to customize built-in patterns and create custom patterns for reusable layout abstractions.

A pattern accepts the following parameters:

  • description - The description of the pattern.
  • properties - The list of properties that the pattern accepts.
  • defaultValues - The default values for the properties. This is useful when you want to provide a default value for a property.
  • transform - The function that accepts the properties and returns a css object.
  • jsx - The name of the JSX component that will be generated (when jsxFramework is set). Defaults to the pascal-case version of the pattern name.
  • jsxElement - The actual JSX element that will be rendered (when jsxFramework is set). Defaults to div.
  • blocklist - The list of properties that are not allowed to be used in the pattern. Can be used to ensure strict typings when using the pattern.
  • strict - Whether to only generate types for the specified properties. This will disallow css properties.

Creating a Pattern

To create a pattern, you can use the patterns property in the config. Let's say we want to create a "Scrollable" pattern that applies preset styles to a container that allows for scrolling.

const config = {
  patterns: {
    extend: {
      scrollable: {
        description: 'A container that allows for scrolling',
        defaultValues: {
          direction: 'vertical',
          hideScrollbar: true
        },
        properties: {
          // The direction of the scroll
          direction: { type: 'enum', value: ['horizontal', 'vertical'] },
          // Whether to hide the scrollbar
          hideScrollbar: { type: 'boolean' }
        },
        // disallow the `overflow` property (in TypeScript)
        blocklist: ['overflow'],
        transform(props) {
          const { direction, hideScrollbar, ...rest } = props
          return {
            overflow: 'auto',
            height: direction === 'horizontal' ? '100%' : 'auto',
            width: direction === 'vertical' ? '100%' : 'auto',
            scrollbarWidth: hideScrollbar ? 'none' : 'auto',
            WebkitOverflowScrolling: 'touch',
            '&::-webkit-scrollbar': {
              display: hideScrollbar ? 'none' : 'auto'
            },
            ...rest
          }
        }
      }
    }
  }
}

Then you can run the following command to generate the pattern JS code:

pnpm panda codegen

Now you can import the pattern and use it in your application:

import { scrollable } from '../styled-system/patterns'
 
const App = () => {
  return (
    <div className={scrollable({ direction: 'vertical', hideScrollbar: true })}>
      <div>Scrollable content</div>
    </div>
  )
}

Customizing Built-in Patterns

You can extend the default patterns by using the patterns.extend property in the config.

panda.config.ts

import { defineConfig } from '@pandacss/dev'
 
export default defineConfig({
  patterns: {
    extend: {
      // Extend the default `flex` pattern
      flex: {
        properties: {
          // only allow row and column
          direction: { type: 'enum', value: ['row', 'column'] },
          jsx: ['Flex', 'CustomFlex'] // 👈 match the `CustomFlex` component to this pattern
        }
      }
    }
  }
})

Changing pattern defaults

Use defaultValues in patterns.extend to change what a built-in pattern applies when you omit a prop. The shape is the same for every pattern — only the pattern name and keys change.

For example, @pandacss/preset-base sets gap: '8px' on stack. To default to a spacing token instead:

panda.config.ts

import { defineConfig } from '@pandacss/dev'
 
export default defineConfig({
  patterns: {
    extend: {
      stack: {
        defaultValues: {
          gap: '2' // same as <Stack gap="2" />
        }
      }
    }
  }
})

<Stack /> and stack({}) now use spacing token 2. Pass gap on the component or in the function call to override.

Values can be token keys ('2') or literals ('12px'). stack, hstack, and vstack are separate patterns — override each if you want the same default gap everywhere.

Then you can run the following command to update the pattern JS code:

pnpm panda codegen

Minimal setup

If you want to use Panda with the bare minimum, without any of the defaults, you can read more about it here