Add the stack layout component and the layout foundation

Plan step 35: <x-stack gap align>, the first of M3's layout components,
with what they all share - src/Support/Layout.php reading the props into
data-md-* attributes, the spacing-token gap and padding rules, the
hide-below/hide-from rules in material.visibility, the stylesheet checks
for resources/css/layout, the browser test file and the skill's Layout
group. The Workbench puts the material layers above Tailwind's preflight,
which would otherwise zero every layout padding and margin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 14:50:27 +02:00
co-authored by Claude Opus 5
parent 6be9f35c98
commit b677e60876
13 changed files with 724 additions and 3 deletions
+15
View File
@@ -4,6 +4,21 @@ use NoNameWeb\LivewireMaterial\Tests\TestCase;
pest()->extend(TestCase::class)->in('Feature', 'Browser');
/**
* The element name (under `<`) and the attributes of the first tag in a rendered component, by
* name; a boolean attribute Blade renders as `name="name"`. For the layout components' render
* tests, which assert what their root carries.
*
* @return array<string, string>
*/
function layoutRoot(string $html): array
{
preg_match('/^\s*<([a-z]+)\b([^>]*)>/s', $html, $tag);
preg_match_all('/([\w:.@-]+)(?:="([^"]*)")?/', $tag[2] ?? '', $pairs, PREG_SET_ORDER);
return ['<' => $tag[1] ?? ''] + collect($pairs)->mapWithKeys(fn (array $pair): array => [$pair[1] => $pair[2] ?? ''])->all();
}
// A shared CI runner is slower than a workstation: an animation or a smooth scroll can take longer
// than the default five seconds to settle there. BROWSER_TIMEOUT (milliseconds) raises the limit.
if (($timeout = (int) getenv('BROWSER_TIMEOUT')) > 0) {