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>
This commit is contained in:
1 parent
f6350de636
commit
32ee28888e
14 files changed
+346
-3
No files matched your search
@@ -0,0 +1,67 @@
|
||||
<?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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,10 @@ test('design fields follow block type without hiding existing stored values', ()
|
||||
assert.equal(relevantProperty(image, 'objectFit', { group: 'image' }), true);
|
||||
assert.equal(relevantProperty(text, 'fontSize', { group: 'text' }), true);
|
||||
assert.equal(relevantProperty(text, 'gridColumns', { group: 'layout' }), false);
|
||||
// Column shares belong to a row and to nothing else - not even to the column itself.
|
||||
assert.equal(relevantProperty(createBlock('row'), 'columnWidths', { group: 'layout' }), true);
|
||||
assert.equal(relevantProperty(createBlock('column'), 'columnWidths', { group: 'layout' }), false);
|
||||
assert.equal(relevantProperty(text, 'columnWidths', { group: 'layout' }), false);
|
||||
image.style = { mobile: { fontSize: '14px' } };
|
||||
assert.equal(relevantProperty(image, 'fontSize', { group: 'text' }), true);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user