diff --git a/config/livewire-material.php b/config/livewire-material.php
index 2b258fbe..25f52200 100644
--- a/config/livewire-material.php
+++ b/config/livewire-material.php
@@ -192,16 +192,13 @@ return [
|
| Every component in every variant, rendered in the application's own
| scheme. Off unless the application runs locally. 'vite' names the
- | application's own entry points: its JavaScript (Livewire, Alpine) and,
- | for an application that still builds one of its own, a CSS entry. The
- | showcase page draws its CSS only from its own bundle
- | (ShowcaseAssetController serves Stylesheets::bundle() of all.css,
- | showcase.css and the scheme) — nothing on it needs the application's
- | build, Tailwind included — so the showcase's layout keeps only the
- | entries here that are not a stylesheet before passing the rest to
- | @vite(), and links its own bundle after them. The error pages have no
- | bundle of their own to fall back on, so ErrorPage::assets() still
- | passes this whole list, CSS included, to @vite().
+ | application's own entry points: its JavaScript (Livewire, Alpine) and
+ | the CSS entry that imports this package's stylesheets. The showcase's
+ | pages pass @vite() only the entries that are not a stylesheet: their
+ | CSS is a bundle of their own (all.css, showcase.css and the scheme,
+ | served by ShowcaseAssetController), so they need nothing from the
+ | application's build. The error pages have no such bundle, so
+ | ErrorPage::assets() passes this whole list, CSS included, to @vite().
|
*/
diff --git a/resources/views/showcase/layout.blade.php b/resources/views/showcase/layout.blade.php
index d81c2da2..bb951fbe 100644
--- a/resources/views/showcase/layout.blade.php
+++ b/resources/views/showcase/layout.blade.php
@@ -1,5 +1,6 @@
{{-- The showcase's frame, and the package's own scaffold at work: the rail groups every section,
- collapses and expands from `lg`, and opens as a modal from the app bar's menu button on a phone.
+ collapses and expands from `expanded` (840px), and opens as a modal from the app bar's menu
+ button on a phone.
Pages move with wire:navigate, so the rail keeps its place and the theme stays. --}}
@php
@@ -38,16 +39,14 @@
- {{-- The application's own entries, JavaScript only (Livewire, Alpine): no showcase view
- needs anything Tailwind builds any more, and linking its CSS here would open the
- document's first @layer statement (Workbench package.css's header explains the trick)
- ahead of the showcase's own bundle below, re-anchoring `material` before Tailwind's
- own layers instead of after. config('livewire-material.showcase.vite')'s own comment
- says why ErrorPage::assets() still passes the whole array. --}}
- @vite(array_filter(config('livewire-material.showcase.vite'), fn (string $entry): bool => ! str_ends_with($entry, '.css')))
+ {{-- The application's own entries without its stylesheets (ShowcaseAssetController::scripts()
+ says why): the CSS of every showcase page is the bundle linked below, and nothing else. --}}
+ @if (($scripts = \NoNameWeb\LivewireMaterial\Http\Controllers\ShowcaseAssetController::scripts()) !== [])
+ @vite($scripts)
+ @endif
@livewireStyles
- {{-- The showcase's own chrome: does not depend on the build above. --}}
+ {{-- all.css, showcase.css and the application's scheme, without the application's build. --}}
diff --git a/resources/views/showcase/shell.blade.php b/resources/views/showcase/shell.blade.php
index 4c98682b..e53f1b2c 100644
--- a/resources/views/showcase/shell.blade.php
+++ b/resources/views/showcase/shell.blade.php
@@ -35,14 +35,14 @@
- {{-- Kept only for the Livewire/Alpine runtime here — this page has no Tailwind class of its
- own. The next batches of step 38 leave it to the sections that still need it. It opens
- the document's first @layer statement (Workbench package.css's header explains the
- trick), which the link below must follow, not precede — see layout.blade.php's comment. --}}
- @vite(config('livewire-material.showcase.vite'))
+ {{-- As layout.blade.php: the application's entries without its stylesheets, then the
+ showcase's own bundle as the page's only CSS. --}}
+ @if (($scripts = \NoNameWeb\LivewireMaterial\Http\Controllers\ShowcaseAssetController::scripts()) !== [])
+ @vite($scripts)
+ @endif
@livewireStyles
- {{-- The showcase's own chrome: does not depend on the build above. --}}
+ {{-- all.css, showcase.css and the application's scheme, without the application's build. --}}
diff --git a/src/Http/Controllers/ShowcaseAssetController.php b/src/Http/Controllers/ShowcaseAssetController.php
index 8dedf0c1..c9fd7559 100644
--- a/src/Http/Controllers/ShowcaseAssetController.php
+++ b/src/Http/Controllers/ShowcaseAssetController.php
@@ -104,6 +104,25 @@ class ShowcaseAssetController
return route('livewire-material.stylesheet', ['hash' => self::hash(self::build())]);
}
+ /**
+ * The application's Vite entries (`livewire-material.showcase.vite`) the showcase's own pages
+ * pass to `@vite()`: every one but a stylesheet — a path Laravel's Vite itself treats as CSS —
+ * since those pages draw their CSS from `url()`'s bundle alone. An application's CSS entry
+ * would load Tailwind for nothing, or the package's stylesheets a second time. Empty when the
+ * list names only stylesheets, and then the page skips `@vite()` altogether (it would read a
+ * build manifest for nothing). A JavaScript entry that imports a stylesheet itself still
+ * brings it: Vite links a chunk's own CSS.
+ *
+ * @return list
+ */
+ public static function scripts(): array
+ {
+ return array_values(array_filter(
+ (array) config('livewire-material.showcase.vite', []),
+ fn (mixed $entry): bool => is_string($entry) && preg_match('/\.(css|less|sass|scss|styl|stylus|pcss|postcss)(\?[^\.]*)?$/', $entry) !== 1,
+ ));
+ }
+
protected static function build(): string
{
$files = [self::path('all.css'), self::path('showcase.css')];
diff --git a/tests/Feature/ShowcaseAssetsTest.php b/tests/Feature/ShowcaseAssetsTest.php
index 1c1b4f6c..ec4dae63 100644
--- a/tests/Feature/ShowcaseAssetsTest.php
+++ b/tests/Feature/ShowcaseAssetsTest.php
@@ -1,5 +1,6 @@
refreshApplication();
}
});
+
+it('passes Vite the application entries but its stylesheets, on every kind of showcase page', function () {
+ $hot = sys_get_temp_dir().'/livewire-material-showcase-hot-'.Str::random(8);
+ file_put_contents($hot, 'http://vite.test');
+ Vite::useHotFile($hot);
+
+ config(['livewire-material.showcase.vite' => ['resources/css/app.css', 'resources/sass/extra.scss', 'resources/js/app.js']]);
+
+ try {
+ expect(ShowcaseAssetController::scripts())->toBe(['resources/js/app.js']);
+
+ foreach (['/material', '/material/progress', '/material/layout/feed', '/material/shell'] as $page) {
+ $this->get($page)
+ ->assertOk()
+ ->assertSee('http://vite.test/resources/js/app.js', false)
+ ->assertDontSee('http://vite.test/resources/css/app.css', false)
+ ->assertDontSee('http://vite.test/resources/sass/extra.scss', false)
+ ->assertSee(ShowcaseAssetController::url(), false);
+ }
+
+ // A list of stylesheets alone leaves @vite() out, rather than reading a manifest for nothing.
+ config(['livewire-material.showcase.vite' => ['resources/css/app.css']]);
+
+ expect(ShowcaseAssetController::scripts())->toBe([]);
+
+ $this->get('/material/progress')->assertOk()->assertDontSee('http://vite.test', false);
+ } finally {
+ unlink($hot);
+ }
+});