# ThemeProvider

## Description

Context provider utility that manages theme state across your application. The ThemeProvider enables programmatic theme switching by maintaining centralized theme state and automatically applying theme attributes to the document element. It works in conjunction with the component variant system to provide consistent theming across all UI components.

## How It Works

The ThemeProvider creates a cascading theme system that works at multiple levels:

### 1. Document-Level Theme Attribute
When you switch themes, ThemeProvider sets a `data-theme` attribute on `document.documentElement`:

```html
<html data-theme="dark">
  <!-- Your app content -->
</html>
```

### 2. Component Variant Props System
Components use the `useBuildVariantProps` hook to generate theme-aware attributes:

```tsx
// Inside a component like Spinner
const variantProps = useBuildVariantProps(
  'spinner',           // component name
  { size: 'Large' },   // variant props
  { disabled: true },  // state flags
  componentVariant     // optional override
);

// Generates: { "component-variant": "spinner-large", "disabled": "true" }
```

### 3. CSS Theme Variables
CSS files use attribute selectors that combine both systems:

```css
[data-theme='dark'],
[data-theme='light'] {
  [component-variant^="spinner-"] {
    --spinner-color: var(--colours-grey-50);
    --spinner-height: 16px;
    /* ... other theme variables */
  }
}
```

This creates a powerful cascade where:
- `data-theme` determines the overall theme context
- `component-variant` provides component-specific styling
- CSS variables allow easy customization and theming

## Usage

### Basic Setup

```tsx
import { ThemeProvider, ThemeContext } from '@delightui/components';

// Wrap your app
<ThemeProvider theme="light">
  <App />
</ThemeProvider>

// Use in components
const { theme, updateTheme } = useContext(ThemeContext);
```

### Theme Switching

```tsx
import { useContext } from 'react';
import { ThemeContext } from '@delightui/components';

function ThemeSwitcher() {
  const { theme, updateTheme } = useContext(ThemeContext);

  return (
    <select 
      value={theme} 
      onChange={(e) => updateTheme(e.target.value)}
    >
      <option value="light">Light Theme</option>
      <option value="dark">Dark Theme</option>
      <option value="custom">Custom Theme</option>
    </select>
  );
}
```

## How Components Connect to Themes

### 1. Component Implementation
```tsx
// Example: Spinner component
const Spinner = ({ className, 'component-variant': componentVariant }) => {
  const variantProps = useBuildVariantProps(
    'spinner',        // Component name
    {},              // Variant props (size, style, etc.)
    undefined,       // State flags (disabled, active, etc.)
    componentVariant // Optional override
  );

  return (
    <div 
      className={cx(styles.spinner, className)}
      {...variantProps}  // Applies component-variant attribute
    >
      <div className={styles.inner} />
    </div>
  );
};
```

### 2. Generated HTML Output
```html
<div component-variant="spinner-default" class="spinner">
  <div class="inner"></div>
</div>
```

### 3. CSS Theme Connection
```css
[data-theme='light'] {
  [component-variant="spinner-default"] {
    --spinner-color: #333;
    --spinner-height: 16px;
  }
}

[data-theme='dark'] {
  [component-variant="spinner-default"] {
    --spinner-color: #fff;
    --spinner-height: 16px;
  }
}
```

## Advanced Features

### Component Variant System
The `useBuildVariantProps` hook automatically:
- Converts component props to CSS attribute selectors
- Handles camelCase to kebab-case conversion
- Manages boolean state flags
- Creates consistent naming patterns

### Automatic CSS Variable Application
Components automatically inherit theme variables through CSS cascade:
```scss
// In component SCSS
.spinner {
  color: var(--spinner-color);
  height: var(--spinner-height);
  // Theme variables are automatically available
}
```

## API

### ThemeContext

```tsx
const { theme, updateTheme } = useContext(ThemeContext);
```

- `theme` - Current active theme string
- `updateTheme(newTheme)` - Function to change the theme

### updateTheme(newTheme)
- `newTheme` - String identifying the theme to apply

## Props

| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `theme` | `string` | `'light'` | No | Initial theme to apply |
| `children` | `ReactNode` | - | No | Child components |

## Built-in Themes

The system comes with pre-configured themes:
- `light` - Light theme with standard color palette
- `dark` - Dark theme with inverted colors
- `custom` - Extensible custom theme support

## Creating Custom Themes

### 1. Add Theme CSS File
```css
/* custom-theme.css */
[data-theme='custom'] {
  [component-variant^="spinner-"] {
    --spinner-color: #ff6b6b;
    --spinner-height: 20px;
  }
  
  [component-variant^="button-"] {
    --button-background: #4ecdc4;
    --button-color: white;
  }
}
```

### 2. Import Theme CSS
```tsx
// In ThemeProvider or main app
import './themes/custom-theme.css';
```

### 3. Use Custom Theme
```tsx
<ThemeProvider theme="custom">
  <App />
</ThemeProvider>
```

## Notes

- Automatically sets `data-theme` attribute on `document.documentElement`
- Defaults to 'light' theme if no theme prop provided
- Theme changes are applied immediately to the DOM
- Supports any string value as theme identifier
- CSS files are imported automatically (base, light, dark themes)
- Component variants are generated automatically from props
- CSS variables provide the connection between themes and components
- The system supports infinite customization through CSS variable overrides