Styling Guide

Learn how to customize the appearance of @c15t/react components through our flexible theming system.

Our theming system provides a powerful way to customize the appearance of @c15t/react components while maintaining their functionality and accessibility. This guide will walk you through the different approaches to styling and help you understand how our theming system works.

Understanding the Theming System

Think of our theming system as a set of style instructions that cascade through your components, similar to CSS but with more structure and type safety. Each component has specific customizable areas, called theme keys, that you can target for styling.

For example, when you want to style a Cookie Banner, you might want to customize:

  • The banner's container
  • The title and description text
  • The action buttons
  • The overlay background

Our theming system makes this straightforward while ensuring you can't accidentally target non-existent elements.

Basic Theme Structure

Let's start with a simple example of customizing a Cookie Banner:

<CookieBanner 
  theme={{
    'banner.root': 'bg-white p-4 rounded-lg shadow-lg',
    'banner.header.title': 'text-xl font-bold text-gray-900',
    'banner.header.description': 'text-sm text-gray-600 mt-2',
    'banner.footer': 'mt-4 flex justify-end gap-2'
  }}
/>

Every theme key follows a predictable pattern:

  1. The component name, which will be banner, widget, dialog.
  2. The element path (e.g., 'header.title' or 'footer.accept-button')
  3. Optional state variations (e.g., 'switch.thumb.checked')

Style Values

Our theming system supports several ways to define styles:

String Classes

The simplest approach is using class names:

theme={{
  'banner.root': 'my-custom-class another-class'
}}

Style Objects

For inline styles, use a style object:

theme={{
  'banner.root': {
    style: {
      backgroundColor: 'white',
      padding: '1rem'
    }
  }
}}

CSS Variables

CSS Variables allow you to customize the component using the component's CSS variables.

theme={{
  'banner.root': {
    style: {
      '--banner-background-color': 'white',
      '--banner-background-color-dark': 'black',
      '--banner-border-radius': '0.5rem',
      '--banner-border-color': '1px solid #e0e0e0'
    }
  }
}}
 
### Combined Approach
You can use both classes and inline styles together:
 
```tsx
theme={{
  'banner.root': {
    className: 'my-custom-class',
    style: {
      backgroundColor: 'white'
    }
  }
}}

Working with Component Hierarchies

@c15t/react components often contain nested elements. Understanding this hierarchy helps you style effectively:

// Example of nested component styling
const theme = {
  'widget.root': 'container mx-auto',
  'widget.accordion': 'space-y-2',
  'widget.accordion.item': 'border rounded-sm',
  'widget.accordion.trigger': 'p-4 hover:bg-gray-50',
  'widget.accordion.trigger-inner': '',
  'widget.accordion.content': 'p-4 bg-gray-50'
}

Each level in the hierarchy can be styled independently, giving you fine-grained control over the appearance.

Using Theme Context

For consistent styling across your application, you can use theme context:

import { ThemeProvider } from '@c15t/react'
 
const globalTheme = {
  // Your theme configuration
}
 
function App() {
  return (
    <ThemeProvider theme={globalTheme}>
      <YourApp />
    </ThemeProvider>
  )
}

Disabling Default Styles

Sometimes you might want to start from scratch. Use the noStyle prop to remove all default styling:

<CookieBanner noStyle theme={yourCustomTheme} />

Type-Safe Styling

Our theming system includes TypeScript support to help prevent errors:

import type { CookieBannerTheme } from '@c15t/react'
 
// TypeScript will catch invalid theme keys
const theme: CookieBannerTheme = {
  'banner.root': 'valid-key',
  'banner.invalid': 'TypeScript error!' // Error: invalid key
}

Responsive Design

You can use media queries and responsive classes just like you would in regular CSS:

theme={{
  'banner.root': 'p-4 md:p-6 lg:p-8',
  'banner.header.title': {
    style: {
      fontSize: 'clamp(1rem, 2vw, 1.5rem)'
    }
  }
}}

Common Patterns

Here are some effective patterns for common styling needs:

Creating a Clean, Modern Look

const modernTheme = {
  'banner.root': 'bg-white shadow-lg rounded-lg mx-4 sm:mx-auto max-w-2xl',
  'banner.header.title': 'text-lg font-semibold text-gray-900',
  'banner.header.description': 'text-sm text-gray-600 mt-2',
  'banner.footer': 'mt-6 flex flex-col sm:flex-row justify-end gap-3'
}

Building Dark Mode Support

const darkModeTheme = {
  'banner.root': 'bg-gray-900 dark:bg-gray-800',
  'banner.header.title': 'text-white dark:text-gray-100',
  'banner.header.description': 'text-gray-300 dark:text-gray-400'
}

Best Practices

  1. Maintain Accessibility

    • Ensure sufficient color contrast
    • Keep interactive elements visually distinct
    • Test your styles with screen readers
  2. Consider Responsive Design

    • Start with mobile-first styles
    • Use flexible units (rem, em) over fixed pixels
    • Test across different screen sizes
  3. Performance

    • Group related styles together
    • Avoid unnecessary style overrides
    • Use CSS classes over inline styles when possible
  4. Maintainability

    • Keep theme configurations organized
    • Document custom styles
    • Use consistent naming conventions

Troubleshooting

If your styles aren't applying as expected, check these common issues:

  1. Style Precedence

    • Component-level styles take precedence over theme context
    • More specific selectors take precedence over general ones
  2. Class Name Conflicts

    • Use unique class names to avoid conflicts
    • Consider using CSS modules or similar solutions
  3. Theme Key Accuracy

    • Verify theme keys match exactly
    • Check for typos in dot notation paths
c15t.com