From b297518810b26352cd919e415b909ccc16e349b3 Mon Sep 17 00:00:00 2001 From: Christoph Date: Thu, 1 Oct 2026 09:33:26 +0200 Subject: [PATCH] Flux durch TallStackUI 4 ersetzt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TallStackUI 4 (MIT) statt Flux; Komponenten mit Präfix ts- () - Layouts, Login-, Passwort-, 2FA- und Einstellungsseiten neu aufgebaut - Livewire-Skripte explizit in beiden Layouts, damit Alpine auch auf den Fortify-Seiten ohne Livewire-Komponente läuft - Dark Mode über tallstackui_darkTheme(), ohne Aufblitzen beim Laden - Registrierungs-View und ungenutzte Layout-Varianten entfernt - Test: Seiten laden keine Ressourcen von fremden Hosts (Vorgabe "alles lokal") Co-Authored-By: Claude Opus 5.5 --- .env.example | 3 + app/Livewire/Settings/Profile.php | 8 +- app/Livewire/Settings/Security.php | 6 +- app/Providers/FortifyServiceProvider.php | 1 - composer.json | 4 +- composer.lock | 148 ++++---- package-lock.json | 26 ++ package.json | 3 + resources/css/app.css | 52 +-- resources/views/components/app-logo.blade.php | 23 +- .../views/components/auth-header.blade.php | 6 +- .../components/desktop-user-menu.blade.php | 39 --- resources/views/components/heading.blade.php | 14 + .../components/passkey-registration.blade.php | 43 +-- .../views/components/passkey-verify.blade.php | 20 +- .../components/settings/layout.blade.php | 31 +- .../views/components/subheading.blade.php | 1 + .../views/components/user-menu.blade.php | 33 ++ resources/views/dashboard.blade.php | 2 +- .../views/flux/icon/book-open-text.blade.php | 47 --- .../flux/icon/chevrons-up-down.blade.php | 43 --- .../views/flux/icon/folder-git-2.blade.php | 45 --- .../views/flux/icon/layout-grid.blade.php | 45 --- resources/views/flux/navlist/group.blade.php | 51 --- resources/views/layouts/app.blade.php | 41 ++- resources/views/layouts/app/header.blade.php | 84 ----- resources/views/layouts/app/sidebar.blade.php | 101 ------ resources/views/layouts/auth.blade.php | 31 +- resources/views/layouts/auth/card.blade.php | 33 -- resources/views/layouts/auth/simple.blade.php | 29 -- resources/views/layouts/auth/split.blade.php | 50 --- .../livewire/auth/confirm-password.blade.php | 36 +- .../livewire/auth/forgot-password.blade.php | 22 +- resources/views/livewire/auth/login.blade.php | 50 ++- .../views/livewire/auth/register.blade.php | 69 ---- .../livewire/auth/reset-password.blade.php | 54 ++- .../auth/two-factor-challenge.blade.php | 90 ++--- .../livewire/auth/verify-email.blade.php | 18 +- .../livewire/settings/appearance.blade.php | 11 +- .../settings/delete-user-form.blade.php | 53 +-- .../views/livewire/settings/profile.blade.php | 23 +- .../livewire/settings/security.blade.php | 315 ++++++------------ .../two-factor/recovery-codes.blade.php | 98 +++--- resources/views/partials/head.blade.php | 14 +- .../views/partials/settings-heading.blade.php | 6 +- tests/Feature/Auth/RegistrationTest.php | 41 --- tests/Feature/NoExternalResourcesTest.php | 43 +++ 47 files changed, 644 insertions(+), 1362 deletions(-) delete mode 100644 resources/views/components/desktop-user-menu.blade.php create mode 100644 resources/views/components/heading.blade.php create mode 100644 resources/views/components/subheading.blade.php create mode 100644 resources/views/components/user-menu.blade.php delete mode 100644 resources/views/flux/icon/book-open-text.blade.php delete mode 100644 resources/views/flux/icon/chevrons-up-down.blade.php delete mode 100644 resources/views/flux/icon/folder-git-2.blade.php delete mode 100644 resources/views/flux/icon/layout-grid.blade.php delete mode 100644 resources/views/flux/navlist/group.blade.php delete mode 100644 resources/views/layouts/app/header.blade.php delete mode 100644 resources/views/layouts/app/sidebar.blade.php delete mode 100644 resources/views/layouts/auth/card.blade.php delete mode 100644 resources/views/layouts/auth/simple.blade.php delete mode 100644 resources/views/layouts/auth/split.blade.php delete mode 100644 resources/views/livewire/auth/register.blade.php delete mode 100644 tests/Feature/Auth/RegistrationTest.php create mode 100644 tests/Feature/NoExternalResourcesTest.php diff --git a/.env.example b/.env.example index 71d6958..89026f4 100644 --- a/.env.example +++ b/.env.example @@ -72,3 +72,6 @@ MEILISEARCH_UPGRADE_DB=true # Host-Ports für Sail (80 und 3306 sind auf dem Entwicklungsrechner belegt) APP_PORT=8080 FORWARD_DB_PORT=3307 + +# TallStackUI-Komponenten als , damit sie nicht mit eigenen Komponenten kollidieren +TALLSTACKUI_PREFIX=ts- diff --git a/app/Livewire/Settings/Profile.php b/app/Livewire/Settings/Profile.php index a78533b..96d647f 100644 --- a/app/Livewire/Settings/Profile.php +++ b/app/Livewire/Settings/Profile.php @@ -3,17 +3,17 @@ namespace App\Livewire\Settings; use App\Concerns\ProfileValidationRules; -use Flux\Flux; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Support\Facades\Auth; use Livewire\Attributes\Computed; use Livewire\Attributes\Title; use Livewire\Component; +use TallStackUi\Traits\Interactions; #[Title('Profile settings')] class Profile extends Component { - use ProfileValidationRules; + use Interactions, ProfileValidationRules; public string $name = ''; @@ -45,7 +45,7 @@ class Profile extends Component $user->save(); - Flux::toast(variant: 'success', text: __('Profile updated.')); + $this->toast()->success(__('Profile updated.'))->send(); } /** @@ -63,7 +63,7 @@ class Profile extends Component $user->sendEmailVerificationNotification(); - Flux::toast(text: __('A new verification link has been sent to your email address.')); + $this->toast()->info(__('A new verification link has been sent to your email address.'))->send(); } #[Computed] diff --git a/app/Livewire/Settings/Security.php b/app/Livewire/Settings/Security.php index 85ec4a6..3f227da 100644 --- a/app/Livewire/Settings/Security.php +++ b/app/Livewire/Settings/Security.php @@ -4,7 +4,6 @@ namespace App\Livewire\Settings; use App\Concerns\PasswordValidationRules; use Exception; -use Flux\Flux; use Illuminate\Support\Facades\Auth; use Illuminate\Validation\ValidationException; use Laravel\Fortify\Actions\ConfirmTwoFactorAuthentication; @@ -18,11 +17,12 @@ use Livewire\Attributes\Locked; use Livewire\Attributes\Title; use Livewire\Attributes\Validate; use Livewire\Component; +use TallStackUi\Traits\Interactions; #[Title('Security settings')] class Security extends Component { - use PasswordValidationRules; + use Interactions, PasswordValidationRules; public string $current_password = ''; @@ -114,7 +114,7 @@ class Security extends Component $this->reset('current_password', 'password', 'password_confirmation'); - Flux::toast(variant: 'success', text: __('Password updated.')); + $this->toast()->success(__('Password updated.'))->send(); } /** diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index 72f4195..9720376 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -49,7 +49,6 @@ class FortifyServiceProvider extends ServiceProvider Fortify::verifyEmailView(fn () => view('livewire.auth.verify-email')); Fortify::twoFactorChallengeView(fn () => view('livewire.auth.two-factor-challenge')); Fortify::confirmPasswordView(fn () => view('livewire.auth.confirm-password')); - Fortify::registerView(fn () => view('livewire.auth.register')); Fortify::resetPasswordView(fn () => view('livewire.auth.reset-password')); Fortify::requestPasswordResetLinkView(fn () => view('livewire.auth.forgot-password')); } diff --git a/composer.json b/composer.json index 2d67811..f89d18a 100644 --- a/composer.json +++ b/composer.json @@ -15,9 +15,9 @@ "laravel/framework": "^13.17", "laravel/tinker": "^3.0", "livewire/blaze": "^1.0", - "livewire/flux": "^2.13.1", "livewire/livewire": "^4.1", - "spatie/laravel-permission": "^8.3" + "spatie/laravel-permission": "^8.3", + "tallstackui/tallstackui": "^4.0" }, "require-dev": { "fakerphp/faker": "^1.24", diff --git a/composer.lock b/composer.lock index 0beda81..5223b03 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3dfa984d6bf252bdd70906ed897c535e", + "content-hash": "57105dffaaadf223d295f7e9d25f68f2", "packages": [ { "name": "bacon/bacon-qr-code", @@ -2432,72 +2432,6 @@ }, "time": "2026-09-15T09:45:15+00:00" }, - { - "name": "livewire/flux", - "version": "v2.20.1", - "source": { - "type": "git", - "url": "https://github.com/livewire/flux.git", - "reference": "ee9ad7f91087ea117a2c80993a14cb25bb902f70" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/livewire/flux/zipball/ee9ad7f91087ea117a2c80993a14cb25bb902f70", - "reference": "ee9ad7f91087ea117a2c80993a14cb25bb902f70", - "shasum": "" - }, - "require": { - "illuminate/console": "^10.0|^11.0|^12.0|^13.0", - "illuminate/support": "^10.0|^11.0|^12.0|^13.0", - "illuminate/view": "^10.0|^11.0|^12.0|^13.0", - "laravel/prompts": "^0.1|^0.2|^0.3", - "livewire/livewire": "^3.7.4|^4.0|dev-main", - "php": "^8.1", - "symfony/console": "^6.0|^7.0|^8.0" - }, - "conflict": { - "livewire/blaze": "<1.0.0-beta.2" - }, - "type": "library", - "extra": { - "laravel": { - "aliases": { - "Flux": "Flux\\Flux" - }, - "providers": [ - "Flux\\FluxServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Flux\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "proprietary" - ], - "authors": [ - { - "name": "Caleb Porzio", - "email": "calebporzio@gmail.com" - } - ], - "description": "The official UI component library for Livewire.", - "keywords": [ - "components", - "flux", - "laravel", - "livewire", - "ui" - ], - "support": { - "issues": "https://github.com/livewire/flux/issues", - "source": "https://github.com/livewire/flux/tree/v2.20.1" - }, - "time": "2026-09-28T18:14:53+00:00" - }, { "name": "livewire/livewire", "version": "v4.4.7", @@ -7605,6 +7539,86 @@ ], "time": "2026-08-30T20:10:52+00:00" }, + { + "name": "tallstackui/tallstackui", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/tallstackui/tallstackui.git", + "reference": "b2333d59893e3fccd382b3f2c7a87653056c14d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tallstackui/tallstackui/zipball/b2333d59893e3fccd382b3f2c7a87653056c14d4", + "reference": "b2333d59893e3fccd382b3f2c7a87653056c14d4", + "shasum": "" + }, + "require": { + "ext-zip": "*", + "illuminate/console": "^10.0|^11.0|^12.0|^13.0", + "illuminate/contracts": "^10.0|^11.0|^12.0|^13.0", + "illuminate/pagination": "^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", + "illuminate/view": "^10.0|^11.0|^12.0|^13.0", + "livewire/livewire": "^4.3.0", + "php": "^8.1" + }, + "require-dev": { + "blade-ui-kit/blade-icons": "^1.7", + "larastan/larastan": "^3.9", + "laravel/pint": "^1.13", + "orchestra/testbench": "^8.21.0|^9.0|^10.0|^11.0", + "orchestra/testbench-dusk": "^8.24|^9.1|^10.0|^11.0", + "pestphp/pest": "^5.0", + "pestphp/pest-plugin-type-coverage": "^5.0", + "spatie/ray": "^1.41" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "TallStackUi": "TallStackUi\\Facades\\TallStackUi" + }, + "providers": [ + "TallStackUi\\TallStackUiServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "TallStackUi\\": "src/" + }, + "exclude-from-classmap": [ + "src/**/*FeatureTest.php", + "src/**/*BrowserTest.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "AJ Meireles", + "email": "alvaro.meireles@live.com" + } + ], + "description": "TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.", + "support": { + "issues": "https://github.com/tallstackui/tallstackui/issues", + "source": "https://github.com/tallstackui/tallstackui/tree/v4.2.1" + }, + "funding": [ + { + "url": "https://github.com/devajmeireles", + "type": "github" + } + ], + "time": "2026-09-27T02:17:50+00:00" + }, { "name": "tijsverkoyen/css-to-inline-styles", "version": "v2.4.0", diff --git a/package-lock.json b/package-lock.json index 0a3adfd..3a0b8c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,9 @@ "vite": "^8.0.0", "vite-plus": "0.3.0" }, + "devDependencies": { + "@tailwindcss/forms": "^0.5.11" + }, "optionalDependencies": { "@laravel/multiplex": "^0.4.1", "@rollup/rollup-linux-x64-gnu": "4.9.5", @@ -1245,6 +1248,19 @@ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "license": "MIT" }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.11.tgz", + "integrity": "sha512-h9wegbZDPurxG22xZSoWtdzc41/OlNEUQERNqI/0fOwa2aVlWGu7C35E/x6LDyD3lgtztFSSjKZyuVM0hxhbgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" + } + }, "node_modules/@tailwindcss/node": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", @@ -3405,6 +3421,16 @@ "node": ">=6" } }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "license": "MIT", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", diff --git a/package.json b/package.json index d97f3be..3ba31b7 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,8 @@ "@rollup/rollup-linux-x64-gnu": "4.9.5", "@tailwindcss/oxide-linux-x64-gnu": "^4.0.1", "lightningcss-linux-x64-gnu": "^1.29.1" + }, + "devDependencies": { + "@tailwindcss/forms": "^0.5.11" } } diff --git a/resources/css/app.css b/resources/css/app.css index ad6eeed..b425287 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -1,43 +1,17 @@ @import 'tailwindcss'; -@import '../../vendor/livewire/flux/dist/flux.css'; +@import '../../vendor/tallstackui/tallstackui/css/v4.css'; +@plugin '@tailwindcss/forms'; + +@source '../../vendor/tallstackui/tallstackui/**/*.php'; @source '../views'; @source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php'; -@source '../../vendor/livewire/flux-pro/stubs/**/*.blade.php'; -@source '../../vendor/livewire/flux/stubs/**/*.blade.php'; - -@custom-variant dark (&:where(.dark, .dark *)); @theme { --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; - - --color-zinc-50: #fafafa; - --color-zinc-100: #f5f5f5; - --color-zinc-200: #e5e5e5; - --color-zinc-300: #d4d4d4; - --color-zinc-400: #a3a3a3; - --color-zinc-500: #737373; - --color-zinc-600: #525252; - --color-zinc-700: #404040; - --color-zinc-800: #262626; - --color-zinc-900: #171717; - --color-zinc-950: #0a0a0a; - - --color-accent: var(--color-neutral-800); - --color-accent-content: var(--color-neutral-800); - --color-accent-foreground: var(--color-white); -} - -@layer theme { - .dark { - --color-accent: var(--color-white); - --color-accent-content: var(--color-white); - --color-accent-foreground: var(--color-neutral-800); - } } @layer base { - *, ::after, ::before, @@ -46,21 +20,3 @@ border-color: var(--color-gray-200, currentColor); } } - -[data-flux-field]:not(ui-radio, ui-checkbox) { - @apply grid gap-2; -} - -[data-flux-label] { - @apply !mb-0 !leading-tight; -} - -input:focus[data-flux-control], -textarea:focus[data-flux-control], -select:focus[data-flux-control] { - @apply outline-hidden ring-2 ring-accent ring-offset-2 ring-offset-accent-foreground; -} - -/* \[:where(&)\]:size-4 { - @apply size-4; -} */ diff --git a/resources/views/components/app-logo.blade.php b/resources/views/components/app-logo.blade.php index 31c2688..55e05e8 100644 --- a/resources/views/components/app-logo.blade.php +++ b/resources/views/components/app-logo.blade.php @@ -1,17 +1,6 @@ -@props([ - 'sidebar' => false, -]) - -@if($sidebar) - - - - - -@else - - - - - -@endif +merge(['class' => 'flex items-center gap-2']) }}> + + + + {{ config('app.name', 'Laravel') }} + diff --git a/resources/views/components/auth-header.blade.php b/resources/views/components/auth-header.blade.php index a5632b2..8a4fba4 100644 --- a/resources/views/components/auth-header.blade.php +++ b/resources/views/components/auth-header.blade.php @@ -3,7 +3,7 @@ 'description', ]) -
- {{ $title }} - {{ $description }} +
+ {{ $title }} + {{ $description }}
diff --git a/resources/views/components/desktop-user-menu.blade.php b/resources/views/components/desktop-user-menu.blade.php deleted file mode 100644 index 7fb3706..0000000 --- a/resources/views/components/desktop-user-menu.blade.php +++ /dev/null @@ -1,39 +0,0 @@ - - - - -
- -
- {{ auth()->user()->name }} - {{ auth()->user()->email }} -
-
- - - - {{ __('Settings') }} - -
- @csrf - - {{ __('Log out') }} - -
-
-
-
diff --git a/resources/views/components/heading.blade.php b/resources/views/components/heading.blade.php new file mode 100644 index 0000000..51fe6e1 --- /dev/null +++ b/resources/views/components/heading.blade.php @@ -0,0 +1,14 @@ +@props([ + 'level' => 2, + 'size' => 'base', +]) + +@php + $sizeClass = match ($size) { + 'xl' => 'text-2xl', + 'lg' => 'text-lg', + default => 'text-base', + }; +@endphp + +class([$sizeClass, 'font-semibold text-gray-900 dark:text-dark-50']) }}>{{ $slot }} diff --git a/resources/views/components/passkey-registration.blade.php b/resources/views/components/passkey-registration.blade.php index 2aaa144..20dd070 100644 --- a/resources/views/components/passkey-registration.blade.php +++ b/resources/views/components/passkey-registration.blade.php @@ -66,50 +66,37 @@ }" > diff --git a/resources/views/components/passkey-verify.blade.php b/resources/views/components/passkey-verify.blade.php index 47dd9a8..ac5bb52 100644 --- a/resources/views/components/passkey-verify.blade.php +++ b/resources/views/components/passkey-verify.blade.php @@ -47,26 +47,24 @@