Files
livewire-material/tests/Feature/Components/DataTest.php
T
Andreas Reinhold / reiniandClaude Opus 5 2acd9ab492 Draw the paginators without Tailwind
Laravel's and Livewire's paginator views render data-md-pagination
hooks; pagination.css draws the row, the 40px steps with their 48px
targets, the selected page and the swap to "Page n of m" below 600px
(plan step 36, inputs). It imports button.css for the simple
paginators, now that the button is rewritten.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 15:47:07 +02:00

114 lines
6.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Livewire\Component;
use Livewire\Livewire;
use Livewire\WithPagination;
it('marks a table for its styles and takes a size', function () {
expect((string) $this->blade('<x-table class="min-w-160"><tbody><tr><td>a</td></tr></tbody></x-table>'))
->toContain('<table data-md-table data-md-size="sm" class="min-w-160">')
->and((string) $this->blade('<x-table size="xs" />'))->toContain('data-md-size="xs"')
->and((string) $this->blade('<x-table size="huge" />'))->toContain('data-md-size="sm"');
});
it('tightens a table only when the caller asks for it', function () {
expect((string) $this->blade('<x-table />'))->not->toContain('data-md-dense')
->and((string) $this->blade('<x-table dense />'))->toContain('data-md-dense');
});
it('draws 52px rows, 36px dense ones, from its stylesheet in the components layer', function () {
$css = (string) file_get_contents(__DIR__.'/../../../resources/css/components/table.css');
expect($css)->toContain('@layer material.components')
->toMatch('/\\[data-md-table\\] \\{\\s*--cell-x: 12px;\\s*--cell-y: var\\(--md-sys-measurement-space200\\);/')
->toMatch('/\\[data-md-table\\]\\[data-md-dense\\] \\{\\s*--cell-y: var\\(--md-sys-measurement-space100\\);/')
->toContain('[data-md-table] :where(tbody tr[aria-selected=\'true\'])')
->and((string) file_get_contents(__DIR__.'/../../../resources/css/components.css'))->toContain("@import './components/table.css';")
->and((string) file_get_contents(__DIR__.'/../../../resources/css/tailwind.css'))->not->toContain('table.css');
});
it('sorts by its column, ascending first and then flipping', function () {
expect((string) $this->blade('<x-sort-header column="size" :sort-by="[\'column\' => \'name\', \'direction\' => \'asc\']">Size</x-sort-header>'))
->not->toContain('aria-sort')
->toContain('wire:click="$set(\'sortBy\', {&quot;column&quot;:&quot;size&quot;,&quot;direction&quot;:&quot;asc&quot;})"')
->and((string) $this->blade('<x-sort-header column="size" model="order" :sort-by="[\'column\' => \'size\', \'direction\' => \'asc\']" class="text-end">Size</x-sort-header>'))
->toContain('aria-sort="ascending"')
->toMatch('/<th data-md-sort-header\\s+data-md-active aria-sort="ascending"\\s+class="text-end">/')
->toContain('$set(\'order\', {&quot;column&quot;:&quot;size&quot;,&quot;direction&quot;:&quot;desc&quot;})')
->and((string) $this->blade('<x-sort-header column="size" :sort-by="[\'column\' => \'size\', \'direction\' => \'desc\']">Size</x-sort-header>'))
->toContain('aria-sort="descending"')
->toContain('&quot;direction&quot;:&quot;asc&quot;');
});
it('gives the sort button and every page control a 48px target', function () {
$pages = new LengthAwarePaginator(range(1, 10), 95, 10, 3, ['path' => '/shares']);
expect((string) $this->blade('<x-sort-header column="size" :sort-by="[]">Size</x-sort-header>'))
->toMatch('/<button(?=[^>]*data-md-sort-header-button)(?=[^>]*class="md-focus-ring md-touch-target")[^>]*>/')
->toContain('--md-icon-size: 16px')
->not->toContain('data-md-active')
->and((string) $pages->links())
->toContain('data-md-pagination-step class="md-state-layer md-focus-ring md-touch-target"');
});
it('draws Laravel\'s paginators in M3', function () {
$pages = new LengthAwarePaginator(range(1, 10), 95, 10, 3, ['path' => '/shares']);
expect((string) $pages->links())
->toContain('data-md-pagination')
->toContain('<span data-md-pagination-compact>Page 3 of 10</span>')
->toContain('<span data-md-pagination-range>2130 of 95</span>')
->toContain('<span aria-current="page" data-md-pagination-step data-md-pagination-page>3</span>')
->toContain('href="/shares?page=2" rel="prev"')
->toContain('aria-label="Go to page 4"')
->toContain('data-md-mirror-rtl')
->not->toContain('text-gray')
->not->toMatch('/class="(?!md-)[^"]*"/');
expect((string) (new Paginator(range(1, 11), 10, 2, ['path' => '/shares']))->links())
->toContain('data-md-pagination')
->toContain('href="/shares?page=1"')
->toContain('href="/shares?page=3"')
->toContain('Previous');
});
it('draws Livewire\'s paginators in M3, wired to its page actions', function () {
Livewire::component('paging-probe', new class extends Component
{
use WithPagination;
public function render(): string
{
return <<<'BLADE'
<div>
{{ (new \Illuminate\Pagination\LengthAwarePaginator(range(1, 10), 95, 10, $this->getPage(), ['path' => '/'])) ->links() }}
</div>
BLADE;
}
});
expect(Livewire::test('paging-probe')->html())
->toContain('data-md-pagination')
->toContain('data-md-pagination-page')
->toContain('wire:click="gotoPage(2, \'page\')"')
->toContain('wire:click="nextPage(\'page\')"')
->not->toContain('text-gray');
});
it('draws the sort header from its stylesheet, its arrow hidden until the column sorts or is hovered', function () {
expect((string) file_get_contents(__DIR__.'/../../../resources/css/components/sort-header.css'))
->toContain('@layer material.components')
->toMatch('/\\[data-md-sort-header\\]:not\\(\\[data-md-active\\]\\) \\[data-md-sort-header-arrow\\] \\{\\s*opacity: 0;/')
->and((string) file_get_contents(__DIR__.'/../../../resources/css/components.css'))->toContain("@import './components/sort-header.css';");
});
it('draws the paginators from their stylesheet, trading the numbers for "Page n of m" below 600px', function () {
expect((string) file_get_contents(__DIR__.'/../../../resources/css/components/pagination.css'))
->toContain('@layer material.components')
->toMatch('/@media \\(width < 600px\\) \\{\\s*\\[data-md-pagination-page\\],\\s*\\[data-md-pagination-range\\] \\{\\s*display: none;/')
->toMatch('/@media \\(width >= 600px\\) \\{\\s*\\[data-md-pagination-compact\\] \\{\\s*display: none;/')
->and((string) file_get_contents(__DIR__.'/../../../resources/css/components.css'))->toContain("@import './components/pagination.css';");
});