updated design

This commit is contained in:
Mark Gregory
2026-08-25 14:41:15 +01:00
parent 3e6b3bfc79
commit 3c7361023c
18 changed files with 1828 additions and 76 deletions
@@ -70,6 +70,7 @@ final class StylistServiceProvider extends ServiceProvider
// replace Laravel's base view locations during their own boot phase; the booted
// callback makes Stylist the final authority for ordinary view('...') resolution.
$this->registerSelectedThemeOverrides();
$this->registerSelectedThemeFluxOverrides();
$this->app->booted(function (): void {
$this->registerSelectedThemeOverrides();
@@ -247,10 +248,12 @@ final class StylistServiceProvider extends ServiceProvider
/**
* Make Flux application overrides theme-owned.
*
* Flux normally discovers custom components from resources/views/flux. This
* application deliberately has no resources/views tree, so expose the selected
* theme's views/flux directory through Flux's existing view namespace instead.
* Package-provided Flux views remain available as the final fallback.
* Flux registers anonymous component paths using the prefix "flux". Laravel
* converts that prefix into a hashed view namespace (xxh128 on Laravel 12+).
* Registering only a normal "flux" view namespace therefore does not satisfy
* Flux::componentExists(). Register each themed views/flux directory through
* Blade exactly as Flux itself does, then prepend it to the hashed namespace so
* the selected theme wins over package stubs while retaining package fallbacks.
*/
private function registerSelectedThemeFluxOverrides(): void
{
@@ -281,7 +284,7 @@ final class StylistServiceProvider extends ServiceProvider
$fluxPath = $theme->path().DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'flux';
if (is_dir($fluxPath)) {
if (is_dir($fluxPath) && ! in_array($fluxPath, $themeFluxPaths, true)) {
$themeFluxPaths[] = $fluxPath;
}
}
@@ -290,27 +293,25 @@ final class StylistServiceProvider extends ServiceProvider
return;
}
// This mirrors FluxServiceProvider::bootComponentPath(). It is essential:
// Flux::componentExists() checks the hashed namespace created by
// Blade::anonymousComponentPath(..., 'flux'), not a literal flux:: namespace.
foreach ($themeFluxPaths as $fluxPath) {
Blade::anonymousComponentPath($fluxPath, 'flux');
}
$fluxNamespace = version_compare($this->app->version(), '12.0.0', '>=')
? hash('xxh128', 'flux')
: md5('flux');
// anonymousComponentPath() adds locations to the namespace. Prepend the
// selected theme paths in reverse order so the first selected theme remains
// authoritative while Flux package views continue to work as fallbacks.
foreach (array_reverse($themeFluxPaths) as $fluxPath) {
View::prependNamespace($fluxNamespace, $fluxPath);
}
$finder = View::getFinder();
if (! method_exists($finder, 'getHints')) {
return;
}
$hints = $finder->getHints();
$existingFluxPaths = array_values(array_filter(
(array) ($hints['flux'] ?? []),
static fn (string $path): bool => is_dir($path),
));
$paths = array_values(array_unique(array_merge($themeFluxPaths, $existingFluxPaths)));
if (method_exists($finder, 'replaceNamespace')) {
$finder->replaceNamespace('flux', $paths);
} else {
foreach (array_reverse($themeFluxPaths) as $fluxPath) {
View::prependNamespace('flux', $fluxPath);
}
}
if (method_exists($finder, 'flush')) {
$finder->flush();
}