Plan step 37: all.css replaces the two interim import lists with one entry for an application that wants everything — the foundation, every layout stylesheet and every component stylesheet, grouped under the same block comments components.css used, plus a Layout block. It also directly imports the three files nothing imported by name before (layout/spacing.css, layout/visibility.css, components/selection.css), so every file under components/ and layout/ is now one @import away. Every test that read a block of components.css or layout.css now reads the matching block of all.css through one shared helper (allCssBlock(), in tests/Pest.php so it loads for any test run) instead of repeating the same substr() search in each file. StylesheetsTest.php's shape, Tailwind-free and breakpoint checks, previously run twice (once for the foundation, once for the layout tree), now run once over the whole tree all.css reaches, since every component and layout stylesheet is plain CSS after step 36; a new test asserts all.css imports everything under components/ and layout/ exactly once. The Workbench imports all.css in place of layout.css and components.css. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
74 lines
4.4 KiB
PHP
74 lines
4.4 KiB
PHP
<?php
|
|
|
|
it('draws a tonal region in surface-container by default, as a div', function () {
|
|
$root = layoutRoot((string) $this->blade('<x-surface>Content</x-surface>'));
|
|
|
|
expect($root)->toMatchArray(['<' => 'div', 'data-md-surface' => 'data-md-surface', 'data-md-level' => 'surface-container'])
|
|
->not->toHaveKeys(['data-md-padding', 'data-md-corner', 'data-md-outlined', 'data-md-hide-below', 'data-md-hide-from', 'class', 'style']);
|
|
});
|
|
|
|
it('fills the surface with each of M3\'s surface roles, and the default for any other', function () {
|
|
foreach (['surface', 'surface-dim', 'surface-bright', 'surface-container-lowest', 'surface-container-low', 'surface-container', 'surface-container-high', 'surface-container-highest'] as $level) {
|
|
expect(layoutRoot((string) $this->blade('<x-surface :level="$level" />', ['level' => $level]))['data-md-level'])->toBe($level);
|
|
}
|
|
|
|
expect(layoutRoot((string) $this->blade('<x-surface level="primary-container" />'))['data-md-level'])->toBe('surface-container');
|
|
});
|
|
|
|
it('pads the surface with a spacing token only, and with none for anything else', function () {
|
|
expect(layoutRoot((string) $this->blade('<x-surface padding="space300" />'))['data-md-padding'])->toBe('space300');
|
|
|
|
foreach (['24px', '3', 'space1000', 'roomy'] as $padding) {
|
|
expect(layoutRoot((string) $this->blade('<x-surface :padding="$padding" />', ['padding' => $padding]))['data-md-padding'])->toBe('none');
|
|
}
|
|
});
|
|
|
|
it('rounds the surface with a corner token, and leaves it square for anything else', function () {
|
|
foreach (['none', 'xs', 'sm', 'md', 'lg', 'lg-increased', 'xl', 'xl-increased', 'xxl', 'full'] as $corner) {
|
|
expect(layoutRoot((string) $this->blade('<x-surface :corner="$corner" />', ['corner' => $corner]))['data-md-corner'])->toBe($corner);
|
|
}
|
|
|
|
expect(layoutRoot((string) $this->blade('<x-surface corner="huge" />')))->not->toHaveKey('data-md-corner');
|
|
});
|
|
|
|
it('draws an outline only when asked', function () {
|
|
expect(layoutRoot((string) $this->blade('<x-surface outlined />')))->toHaveKey('data-md-outlined')
|
|
->and(layoutRoot((string) $this->blade('<x-surface :outlined="false" />')))->not->toHaveKey('data-md-outlined');
|
|
});
|
|
|
|
it('draws the element it is asked for, and a div for one it does not take', function () {
|
|
expect(layoutRoot((string) $this->blade('<x-surface as="section">Content</x-surface>'))['<'])->toBe('section')
|
|
->and((string) $this->blade('<x-surface as="section">Content</x-surface>'))->toContain('</section>')
|
|
->and(layoutRoot((string) $this->blade('<x-surface as="script">Content</x-surface>'))['<'])->toBe('div')
|
|
->and(layoutRoot((string) $this->blade('<x-surface as="input" />'))['<'])->toBe('div');
|
|
});
|
|
|
|
it('hides below and from a breakpoint, never below or from compact', function () {
|
|
expect(layoutRoot((string) $this->blade('<x-surface hide-below="expanded" hide-from="extra-large" />')))
|
|
->toMatchArray(['data-md-hide-below' => 'expanded', 'data-md-hide-from' => 'extra-large']);
|
|
|
|
foreach (['compact', 'tablet', 'Medium', '840'] as $breakpoint) {
|
|
expect(layoutRoot((string) $this->blade('<x-surface :hide-below="$b" :hide-from="$b" />', ['b' => $breakpoint])))
|
|
->not->toHaveKeys(['data-md-hide-below', 'data-md-hide-from']);
|
|
}
|
|
});
|
|
|
|
it('puts the caller\'s class and style on the surface untouched', function () {
|
|
expect(layoutRoot((string) $this->blade('<x-surface class="upload-zone" style="min-height: 12rem" data-test="zone" />')))
|
|
->toMatchArray(['class' => 'upload-zone', 'style' => 'min-height: 12rem;', 'data-test' => 'zone']);
|
|
});
|
|
|
|
it('draws the surface from a stylesheet in the layout layer, imported by all.css', function () {
|
|
$css = (string) file_get_contents(__DIR__.'/../../../resources/css/layout/surface.css');
|
|
|
|
expect($css)->toContain('@layer material.layout')
|
|
->toContain("[data-md-surface][data-md-level='surface-container-high'] {")
|
|
->toContain('background-color: var(--md-sys-color-surface-container-high);')
|
|
->toContain('border: 1px solid var(--md-sys-color-outline-variant);')
|
|
->toContain("@import './spacing.css';")
|
|
->toContain("@import './visibility.css';")
|
|
// A pane on a surface keeps its content off the surface's edge again.
|
|
->toContain("[data-md-surface] > * {\n --md-layout-margin: initial;")
|
|
->and((string) file_get_contents(__DIR__.'/../../../resources/css/all.css'))->toContain("@import './layout/surface.css';");
|
|
});
|