# `PhiaUi.Components.ThemeProvider`
[🔗](https://github.com/charlenopires/PhiaUI/blob/v0.1.17/lib/phia_ui/components/display/theme_provider.ex#L1)

Scoped CSS theme provider using a CSS-first, data-attribute approach.

`theme_provider/1` wraps its children in a `<div>` and sets the
`data-phia-theme` attribute on it. A static CSS file (`phia-themes.css`,
generated by `mix phia.theme install`) defines CSS custom property overrides
for each `[data-phia-theme="name"]` selector. Because CSS cascades, every
PhiaUI component inside the wrapper automatically uses the theme's color
tokens without any additional props.

## Architecture: CSS-first theming

The v2 theme system is completely CSS-first — no `<style>` tags are injected
at runtime. The flow is:

    mix phia.theme install
        │
        ▼
    assets/css/phia-themes.css
    ┌─────────────────────────────────────────────────────────────────┐
    │  [data-phia-theme="blue"] { --primary: oklch(...); ... }        │
    │  [data-phia-theme="rose"] { --primary: oklch(...); ... }        │
    │  ... (one block per preset × dark/light variant)                │
    └─────────────────────────────────────────────────────────────────┘
        │
        ▼ CSS cascades into children
    <div data-phia-theme="blue">
      <.button>Blue primary button</.button>
      <!-- --primary resolves to the blue preset value -->
    </div>

This is more efficient than runtime `<style>` injection because:
- The CSS is already in the browser's CSSOM on first paint
- No JavaScript is needed to apply theme colors
- Multiple scoped themes on the same page work without conflict
- Dark mode variants are handled entirely by CSS

## Setup

Generate the theme CSS file:

    mix phia.theme install

This creates `assets/css/phia-themes.css` and adds an `@import` to
`assets/css/app.css`. You can also import it manually:

    @import "./phia-themes.css";

## Basic usage — atom shorthand

    <.theme_provider theme={:blue}>
      <section class="p-4 rounded-lg">
        <.button>Blue button</.button>
        <.badge>Blue badge</.badge>
      </section>
    </.theme_provider>

## Usage with Theme struct

Useful when the theme is loaded from the database or application config:

    # In your LiveView mount:
    {:ok, theme} = PhiaUi.Theme.get(:rose)
    {:ok, assign(socket, org_theme: theme)}

    # In the template:
    <.theme_provider theme={@org_theme}>
      <%= render_slot(@inner_block) %>
    </.theme_provider>

## Multiple themes on one page

Because theming is attribute-scoped, different sections of the same page can
use different themes simultaneously — a powerful feature for multi-tenant UIs
or theme preview pages:

    <.metric_grid cols={3}>
      <.theme_provider theme={:blue}>
        <.stat_card title="Plan A" value="$12/mo" trend={:up} trend_value="+5%" />
      </.theme_provider>

      <.theme_provider theme={:rose}>
        <.stat_card title="Plan B" value="$49/mo" trend={:up} trend_value="+12%" />
      </.theme_provider>

      <.theme_provider theme={:green}>
        <.stat_card title="Plan C" value="$99/mo" trend={:up} trend_value="+3%" />
      </.theme_provider>
    </.metric_grid>

## Runtime theme switching

To switch the entire page theme at runtime (e.g. from a user preferences
panel), use the `PhiaTheme` JS hook from `priv/templates/js/hooks/theme.js`.
The hook reads the `data-theme` attribute on the clicked element and updates
`data-phia-theme` on `<html>`, then stores the choice in
`localStorage['phia-color-theme']`.

For a full-page theme (not scoped to a wrapper), set `data-phia-theme`
directly on `<html>` from your anti-FOUC script (already handled by the
unified script in the `DarkModeToggle` module docs).

## Theme values

The `:theme` attribute accepts three types:

| Value                 | Resolution                                                  |
|-----------------------|-------------------------------------------------------------|
| `:zinc`, `:blue`, etc.| `Theme.get/1` is called; uses `theme.name` string          |
| `%PhiaUi.Theme{}`     | Uses `theme.name` directly                                  |
| `nil` (default)       | No `data-phia-theme` attribute added; inherits parent theme |

## Available presets

Run `mix phia.theme list` to see all built-in presets:

    zinc | slate | blue | rose | orange | green | violet | neutral

## Nesting

Themes can be nested. The inner `data-phia-theme` wins via CSS specificity:

    <.theme_provider theme={:blue}>
      <.button>Blue</.button>
      <.theme_provider theme={:rose}>
        <.button>Rose (overrides blue)</.button>
      </.theme_provider>
    </.theme_provider>

# `theme_provider`

Wraps content in a scoped CSS theme context.

Sets `data-phia-theme={theme_name}` on the wrapper `<div>`, which activates
the matching CSS custom property block from `phia-themes.css`. All PhiaUI
components inside the wrapper resolve their color tokens (primary, secondary,
muted, etc.) from the theme's CSS variables.

When `theme` is `nil`, the attribute is omitted and the div is rendered as
a neutral wrapper without any theme override.

## Example

    <.theme_provider theme={:blue} class="rounded-lg border p-4">
      <.button>Blue button</.button>
      <.badge variant={:default}>Blue badge</.badge>
    </.theme_provider>

## Attributes

* `theme` (`:any`) - The theme to activate inside the wrapper. Accepts:

  - An atom matching a built-in preset (`:zinc`, `:blue`, `:slate`, `:rose`,
    `:orange`, `:green`, `:violet`, `:neutral`) — resolved via `Theme.get/1`
  - A `%PhiaUi.Theme{}` struct — uses `theme.name` directly
  - `nil` (default) — no `data-phia-theme` attribute is set; the element
    inherits whatever theme is set on an ancestor (or the page default)

  Defaults to `nil`.
* `class` (`:string`) - Additional CSS classes applied to the wrapper `<div>`. The wrapper is
  a plain `<div>` with no visual styling of its own — use `:class` to add
  layout, padding, or background classes if needed.

  Defaults to `nil`.
* Global attributes are accepted. HTML attributes forwarded to the wrapper div (e.g. `id`, `style`, `data-*`).
## Slots

* `inner_block` (required) - Content rendered inside the themed scope. All PhiaUI components inside will use the specified theme's CSS custom properties.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
