Add M3 error pages and the Markdown mail theme
tests / feature (8.5) (push) Successful in 1m8s
tests / browser (safari, webkit) (push) Has been cancelled
tests / browser (firefox, firefox) (push) Has been cancelled
tests / lint (push) Successful in 1m5s
tests / feature (8.4) (push) Successful in 1m11s
tests / browser (chrome, chromium) (push) Failing after 6m9s
tests / feature (8.5) (push) Successful in 1m8s
tests / browser (safari, webkit) (push) Has been cancelled
tests / browser (firefox, firefox) (push) Has been cancelled
tests / lint (push) Successful in 1m5s
tests / feature (8.4) (push) Successful in 1m11s
tests / browser (chrome, chromium) (push) Failing after 6m9s
Error pages for 401 to 503 in an error-view root appended to view.paths, with an inline fallback when the Vite build is missing, and a mail theme rendered from the application's scheme JSON, with opt-in header and message components. Completes Phase 9. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
co-authored by
Claude Opus 5
parent
ab692b66bb
commit
8f174520eb
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace NoNameWeb\LivewireMaterial\Support;
|
||||
|
||||
/**
|
||||
* The colour scheme as data, for the places CSS custom properties cannot reach: a mail client
|
||||
* resolves none, and an error page whose build is missing has no stylesheet to declare them.
|
||||
*
|
||||
* The data is the JSON `php artisan material:scheme` writes beside the stylesheet
|
||||
* (`livewire-material.scheme`, resources/css/material-scheme.json by default). Without that
|
||||
* file — or with one that is not a scheme — the package's own default applies, the same one
|
||||
* tokens/scheme.css carries. A role the application's file lacks (a scheme generated before
|
||||
* the role existed) is taken from the default, and a value that is not a #rrggbb hex is
|
||||
* refused, so nothing but a colour ever reaches a stylesheet.
|
||||
*
|
||||
* Read on every call and never kept: a regenerated scheme applies at once, and a long-running
|
||||
* worker holds nothing.
|
||||
*/
|
||||
class Scheme
|
||||
{
|
||||
/**
|
||||
* @return array{light: array<string, string>, dark: array<string, string>}
|
||||
*/
|
||||
public static function load(?string $path = null): array
|
||||
{
|
||||
$default = static::read(dirname(__DIR__, 2).'/resources/css/tokens/scheme.json');
|
||||
$scheme = static::read($path ?? (string) config('livewire-material.scheme'));
|
||||
|
||||
return [
|
||||
'light' => [...$default['light'], ...$scheme['light']],
|
||||
'dark' => [...$default['dark'], ...$scheme['dark']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The light roles: what a mail wears.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function light(?string $path = null): array
|
||||
{
|
||||
return static::load($path)['light'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{light: array<string, string>, dark: array<string, string>}
|
||||
*/
|
||||
protected static function read(string $path): array
|
||||
{
|
||||
$data = is_file($path) ? json_decode((string) file_get_contents($path), true) : null;
|
||||
|
||||
return [
|
||||
'light' => static::roles($data['light'] ?? null),
|
||||
'dark' => static::roles($data['dark'] ?? null),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected static function roles(mixed $roles): array
|
||||
{
|
||||
if (! is_array($roles)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_filter(
|
||||
$roles,
|
||||
fn (mixed $hex, mixed $role): bool => is_string($role)
|
||||
&& preg_match('/^[a-z-]+$/', $role) === 1
|
||||
&& is_string($hex)
|
||||
&& preg_match('/^#[0-9a-fA-F]{6}$/', $hex) === 1,
|
||||
ARRAY_FILTER_USE_BOTH,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user