Home

Dark Mode

PHPXUI supports dark mode out of the box by toggling the dark class on the <html> tag. The selected theme is stored persistently using Request::$localStorage.

1. Configure src/app/layout.php

Add the following logic to your root layout to ensure persistence on page load:

<?php

use PP\MainLayout;
use PP\Request;

MainLayout::$title = !empty(MainLayout::$title) ? MainLayout::$title : 'Create Prisma PHP App';
MainLayout::$description = !empty(MainLayout::$description) ? MainLayout::$description : 'Generated by create Prisma PHP App';

$themeName = Request::$localStorage->themeName ?? 'dark';

?>

<html lang="en" class="<?= $themeName ?>">

2. Add a Theme Toggle

You can implement the theme toggle using a simple switch or a custom component with icons.

Option A: Using the ToggleSwitch Component

Use the standard toggle switch component and a JavaScript function to update the theme:

<?php

use Lib\PHPXUI\ToggleSwitch;
use PP\Request;

$themeName = Request::$localStorage->themeName ?? 'dark';
$isDark = $themeName === 'dark' ? '{true}' : '{false}';

?>

<ToggleSwitch checked="{$isDark}" onchange="toggleTheme(event.target.checked)" />
<script>
    function toggleTheme(isChecked) {
        const newThemeName = isChecked ? 'dark' : 'light';
        document.documentElement.setAttribute('class', newThemeName);
        store.setState({
            themeName: newThemeName
        }, true);
    }
</script>

The store.setState(..., true) ensures that the value is saved in local storage via Request::$localStorage.

Option B: Custom Component with Icons

For a more polished UI with Sun/Moon icons, create a reusable component at src/app/_components/ToggleTheme.php:

<?php

declare(strict_types=1);

namespace app\_components;

use Lib\PPIcons\{Moon, SunMoon};
use PP\PHPX\PHPX;
use PP\Request;

class ToggleTheme extends PHPX
{
    public ?string $class = '';
    private string $themeName = '';

    public function __construct(array $props = [])
    {
        parent::__construct($props);
        $this->themeName = Request::$localStorage->themeName ?? 'dark';
    }

    public function render(): string
    {
        $class = $this->getMergeClasses($this->class);
        $attributes = $this->getAttributes([
            'class' => $class,
        ]);
        $isDark = $this->themeName === 'dark' ? 'true' : 'false';

        return <<<HTML
        <div {$attributes}>
            <button class="p-2 text-muted-foreground hover:text-foreground transition-colors" onclick="toggleThemeName()">
                <SunMoon class="size-5" hidden="{toggleTheme}" />
                <Moon class="size-5" hidden="{!toggleTheme}" />
            </button>

            <script>
                const [toggleTheme, setToggleTheme] = pp.state({$isDark});

                function toggleThemeName() {
                    setToggleTheme(!toggleTheme);
                    const newThemeName = toggleTheme ? 'dark' : 'light';
                    document.documentElement.setAttribute('class', newThemeName);
                    store.setState({
                        themeName: newThemeName
                    }, true);
                }
            </script>
        </div>
        HTML;
    }
}

Then use it in your views like this:

<ToggleTheme />

3. Customize Dark Mode Colors

Open your stylesheet at src/app/globals.css and edit the .dark block:

.dark {
  --background: 240 10% 3.9%;
  --foreground: 0 0% 98%;
  --card: 240 10% 3.9%;
  --card-foreground: 0 0% 98%;
  --primary: 0 0% 98%;
  --primary-foreground: 240 5.9% 10%;
  --border: 240 3.7% 15.9%;
  --input: 240 3.7% 15.9%;
  /* Add or customize other Shadcn-compatible tokens */
}

4. Helpful Resources