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 */
}