ValyroUI English version

Начало работы: Laravel + Inertia

React-стартер Laravel (Inertia 3): ThemeProvider — в withApp, атрибуты темы — в Blade-шаблоне, фон и шрифт стартера уступают теме

1. Создайте приложение

Проверено с Laravel 13.36 и Inertia 3.9. Без --stability=dev Composer берёт устаревший тег стартера (Laravel 12, Inertia 2). Скрипты Composer сами создают .env, ключ, SQLite-базу и собирают фронтенд.

composer create-project laravel/react-starter-kit my-app --stability=dev --no-interaction
cd my-app

2. Установите пакет

Подходят react и react-dom 17, 18 и 19 (на React 17 id из useId появляются сразу после монтирования). Пакет — ES-модули (плюс CommonJS-копия для require()), без runtime-зависимостей, по файлу на модуль: в бандл попадают только импортированные компоненты, а как грузить и CSS только их — в разделе «Только нужный CSS» ниже. Шрифты — отдельные файлы: тема vercel (по умолчанию в ThemeProvider) использует Geist, поэтому рядом со стилями импортируйте valyro-ui/fonts/geist.css и valyro-ui/fonts/geist-mono.css, иначе текст будет системным шрифтом; glass использует системные шрифты, ей файлы не нужны. Пока пакет не опубликован, соберите и упакуйте его в репозитории (npm run build:core && npm pack ./dist/core) и установите tarball из корня репозитория: npm install /path/to/ValyroUI/valyro-ui-0.1.0.tgz.

npm install valyro-ui

3. Стили и ThemeProvider

В Inertia 3 нет setup() с <App /> — корневая обёртка задаётся колбэком withApp. При SSR задайте locale в ThemeProvider: иначе числа и даты форматируются по локали сервера, а в браузере — по локали пользователя, и гидрация падает на несовпадении текста («1,200» против «1 200»).

import { createInertiaApp } from '@inertiajs/react';
import 'valyro-ui/styles.css';
import { ThemeProvider } from 'valyro-ui';
import { Toaster } from '@/components/ui/sonner';
import { TooltipProvider } from '@/components/ui/tooltip';
import { initializeTheme } from '@/hooks/use-appearance';
import AppLayout from '@/layouts/app-layout';
import AuthLayout from '@/layouts/auth-layout';
import SettingsLayout from '@/layouts/settings/layout';

const appName = import.meta.env.VITE_APP_NAME || 'Laravel';

void createInertiaApp({
    title: (title) => (title ? `${title} - ${appName}` : appName),
    layout: (name) => {
        switch (true) {
            case name === 'welcome':
                return null;
            case name.startsWith('auth/'):
                return AuthLayout;
            case name.startsWith('settings/'):
                return [AppLayout, SettingsLayout];
            default:
                return AppLayout;
        }
    },
    strictMode: true,
    withApp(app) {
        return (
            <ThemeProvider theme="glass" mode="light" locale="en-US">
                <TooltipProvider delayDuration={0}>
                    {app}
                    <Toaster />
                </TooltipProvider>
            </ThemeProvider>
        );
    },
    progress: {
        color: '#4B5563',
    },
});

// This will set light / dark mode on load...
initializeTheme();

4. Тема в Blade-шаблоне

Добавьте атрибуты на <html> и уберите font-sans с <body>: шрифт стартера через font: inherit из preflight Tailwind перебивает шрифт темы даже в кнопках. Уберите и @fonts из <head>: он предзагружает Instrument Sans стартера, который больше не используется (три лишние загрузки и предупреждения «preloaded but not used» в консоли). Собственная светлая/тёмная тема стартера (класс dark) с data-mode не синхронизирована — переключайте их вместе сами.

<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" data-theme="glass" data-mode="light" @class(['dark' => ($appearance ?? 'system') == 'dark'])>
    …
    <body class="antialiased">

5. Уберите фон body

Правило стартера делает body непрозрачным и закрывает фон темы, который рисуется на <html>. Удалите его из @layer base.

/* …the rest of the file stays as is… */

@layer base {
    * {
        @apply border-border;
    }
}

6. Страница

Showcase — компонент из гайда по Next.js, без изменений (в resources/js/components/showcase.tsx).

import { Head } from '@inertiajs/react';
import { Showcase } from '@/components/showcase';

export default function Welcome() {
    return (
        <>
            <Head title="Welcome" />
            <Showcase />
        </>
    );
}

7. Соберите и запустите

Без SSR Inertia рендерит страницу в браузере. С SSR (npm run build:ssr и php artisan inertia:start-ssr) серверный HTML уже содержит разметку компонентов, гидрация проходит без предупреждений.

npm run build
php artisan serve

Другие фреймворки