Extract the scheme stylesheet shape for ErrorPage to reuse
SchemeCommand::levels()/selectors()/blocks() move to a new SchemeStylesheet, and Scheme gains forStylesheet(), which resolves a scheme (and every profile) at all three contrast levels together. Plan step 40's fallback needs to draw the same colours material:scheme writes, without duplicating its selector logic. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
513e344912
commit
3b9a889e7c
@@ -109,6 +109,52 @@ class Scheme
|
||||
return $profiles === [] ? null : static::activeFrom($data, $profiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* The scheme, and every profile once there is more than one, in the shape
|
||||
* `SchemeStylesheet::levels()` draws: light and dark roles at all three contrast levels
|
||||
* together, filled from the package's own default wherever the file or a profile is missing a
|
||||
* role — the same fallback `load()` gives one level at a time, given here for all three at
|
||||
* once, since a stylesheet has to carry every level in one pass.
|
||||
*
|
||||
* Which profile is *active* is left to the browser: by the time a page reads this, the theme
|
||||
* script has already written the resolved one to `<html data-scheme>` (`profile()`, embedded
|
||||
* server-side), so every profile is returned here, keyed by name, for `[data-scheme]` to select
|
||||
* between — `scheme` doubles as the plain, attribute-less blocks (`:root`, `[data-theme]`),
|
||||
* exactly as the file `material:scheme` generates gives its own default profile's roles twice.
|
||||
* `ErrorPage::fallbackStyles()`'s only path to a scheme: there is no build to serve a generated
|
||||
* `material-scheme.css`, so this draws the same colours from the same JSON instead.
|
||||
*
|
||||
* @return array{scheme: array{light: array<string, string>, dark: array<string, string>, contrast: array<string, array{light: array<string, string>, dark: array<string, string>}>}, profiles: array<string, array{label: string, light: array<string, string>, dark: array<string, string>, contrast: array<string, array{light: array<string, string>, dark: array<string, string>}>}>}
|
||||
*/
|
||||
public static function forStylesheet(?string $path = null): array
|
||||
{
|
||||
$data = static::data($path);
|
||||
$profiles = [];
|
||||
|
||||
if (is_array($data['profiles'] ?? null)) {
|
||||
foreach ($data['profiles'] as $name => $profile) {
|
||||
if (! is_string($name) || preg_match('/^[a-z0-9-]+$/', $name) !== 1 || ! is_array($profile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$profiles[$name] = [
|
||||
'label' => is_string($profile['label'] ?? null) ? $profile['label'] : Str::headline($name),
|
||||
...static::fullScheme($profile),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($profiles === []) {
|
||||
return ['scheme' => static::fullScheme($data), 'profiles' => []];
|
||||
}
|
||||
|
||||
$default = is_string($data['default'] ?? null) && isset($profiles[$data['default']])
|
||||
? $data['default']
|
||||
: (string) array_key_first($profiles);
|
||||
|
||||
return ['scheme' => $profiles[$default], 'profiles' => $profiles];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
@@ -165,6 +211,27 @@ class Scheme
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* One scheme (a single scheme's data, or one profile's) at every contrast level together, in
|
||||
* the shape `SchemeStylesheet::levels()` reads: `scheme()` already merges a level's own roles
|
||||
* over the standard ones it does not name, over the package's default, one level at a time —
|
||||
* this asks it for all three and nests medium and high under `contrast`, since a stylesheet's
|
||||
* blocks for one scheme need every level in a single call.
|
||||
*
|
||||
* @param array<mixed> $data
|
||||
* @return array{light: array<string, string>, dark: array<string, string>, contrast: array<string, array{light: array<string, string>, dark: array<string, string>}>}
|
||||
*/
|
||||
protected static function fullScheme(array $data): array
|
||||
{
|
||||
return [
|
||||
...static::scheme($data, 'standard'),
|
||||
'contrast' => [
|
||||
'medium' => static::scheme($data, 'medium'),
|
||||
'high' => static::scheme($data, 'high'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $data
|
||||
* @param non-empty-array<string, mixed> $profiles
|
||||
|
||||
Reference in New Issue
Block a user