Files
KantSites/tests/ColumnWidthsTest.php
kantarciandClaude Fable 5.1 32ee28888e
CMS quality / php (8.2) (push) Canceled after 0s
CMS quality / php (8.4) (push) Canceled after 0s
CMS quality / browser (push) Canceled after 0s
CMS quality / mysql (push) Canceled after 0s
Drag the border between two columns to set their widths in 1.16.0
Umut, with a card of an icon next to a text as the example: "bei Rows die
Breite ändern, am besten per Drag and Drop im Editor". Rows only ever had
equal columns - both the classic `columns` token and the free `gridColumns`
produce `repeat(n, 1fr)`.

A row now carries the free style `columnWidths`, a list of shares such as
`2 1` or `66.7 33.3`, per device and without a new document schema.
`StyleCompiler::columnTracks()` turns it into `grid-template-columns`,
pads or cuts the shares to the number of columns, and gives a device whose
layout stacks the columns a single track, because the desktop rule carries
an id and would otherwise outrank the class that stacks a phone.

In the editor the border between two side-by-side columns of the selected
row is a handle: dragging restyles the row inline while the pointer moves
and writes one undo step on release; the arrow keys nudge by five points.
The design panel shows the same value as the text field "Spaltenbreiten".
The Playwright editor check drags the handle with the real mouse.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 10:39:06 +02:00

68 lines
3.3 KiB
PHP

<?php
namespace App\Tests;
use App\Content\StyleCompiler;
use App\Domain\InvalidDocument;
use PHPUnit\Framework\TestCase;
/**
* Umut: "bei Rows die Breite ändern, am besten per Drag and Drop im Editor". The editor writes
* the shares of a row's columns; this is what the server makes of them.
*/
final class ColumnWidthsTest extends TestCase
{
public function testSharesBecomeTracksAndStackWhereTheLayoutStacks(): void
{
$css = (new StyleCompiler())->compileDocument(['blocks' => [[
'id' => 'zeile', 'type' => 'row',
'layout' => ['design' => ['desktop' => ['columns' => 'two', 'gap' => 'medium'], 'mobile' => ['columns' => 'one']]],
'style' => ['desktop' => ['columnWidths' => '66.7 33.3']],
'children' => [['id' => 'a', 'type' => 'column'], ['id' => 'b', 'type' => 'column']],
]]]);
// The desktop rule carries an id and would win over the class that stacks a phone, so
// the phone gets a single track of its own.
self::assertSame(
'#zeile{grid-template-columns:minmax(0,66.7fr) minmax(0,33.3fr)}@media (max-width:767px){#zeile{grid-template-columns:minmax(0,1fr)}}',
$css,
);
}
public function testSharesArePaddedOrCutToTheColumnsAndCanDifferPerDevice(): void
{
$css = (new StyleCompiler())->compileDocument(['blocks' => [[
'id' => 'zeile', 'type' => 'row',
'style' => [
'desktop' => ['columnWidths' => '2 1'],
'tablet' => ['columnWidths' => '1 1 1 1'],
'mobile' => ['gridColumns' => 1],
],
'children' => [['id' => 'a', 'type' => 'column'], ['id' => 'b', 'type' => 'column'], ['id' => 'c', 'type' => 'column']],
]]]);
// A column added after the drag gets the average share; a surplus share is dropped.
self::assertStringContainsString('#zeile{grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,1.5fr)}', $css);
self::assertStringContainsString('@media (max-width:1024px){#zeile{grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(0,1fr)}}', $css);
self::assertStringContainsString('@media (max-width:767px){#zeile{grid-template-columns:minmax(0,1fr)}}', $css);
// A single column has nothing to share, and only rows have columns.
self::assertSame('', (new StyleCompiler())->compileDocument(['blocks' => [
['id' => 'einzeln', 'type' => 'row', 'style' => ['desktop' => ['columnWidths' => '2 1']], 'children' => [['id' => 'a', 'type' => 'column']]],
]]));
}
public function testOnlyListsOfPositiveSharesAreAccepted(): void
{
$compiler = new StyleCompiler();
foreach (['2 1', '66.7 33.3', '25 50 25', '1'] as $good) {
$compiler->validate(['desktop' => ['columnWidths' => $good]]);
}
foreach (['2 0', '2,1', '2 1', ' 2 1', '2fr 1fr', '1 1 1 1 1 1 1 1 1 1 1 1 1', '1000 1', '1.25 1'] as $bad) {
try {
$compiler->validate(['desktop' => ['columnWidths' => $bad]]);
self::fail(sprintf('"%s" darf keine Spaltenaufteilung sein.', $bad));
} catch (InvalidDocument $e) {
self::assertStringContainsString('column shares', $e->getMessage());
}
}
}
}