Keep a switch's track whole beside long text in a row
`[data-md-toggle] { min-width: 0 }` let the switch's root shrink below
its 52px track as a flex item. In `<x-row justify="between">` beside a
paragraph, flex shrinking weighs each item by its width, so the root of
a bare switch gave up a share of its 52px, and a switch with a long
label of its own gave its label a column one word wide and less; the
track, which does not shrink inside the root, ran out of it and past a
card's edge on a phone. `<x-checkbox>`'s root did the same with its box.
Both roots now keep their automatic minimum, the control and, beside a
label, its longest word, so the text beside the control, or the
control's own label, wraps instead. The toggle's docblock and the skill
say so.
A browser test lays a bare switch, a labelled switch and a bare
checkbox beside long text in rows on a 393px window and checks each
control's size and that it stays inside its row, and that the switch's
own label wraps inside its root; it fails without the change in Chrome,
Firefox and Safari.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1885c3e54e
commit
cf63f11bfb
@@ -505,3 +505,53 @@ it('draws the switch\'s handle at SwitchTokens\' sizes and centres, off and on',
|
||||
->wait(0.7)
|
||||
->assertScript("{$handle} === '52,32,24,36,16'");
|
||||
});
|
||||
|
||||
it('keeps a switch\'s track and a checkbox\'s box whole beside long text in a row, wrapping the text instead', function () {
|
||||
Route::middleware('web')->get('/selection-row-probe', fn () => Blade::render(<<<'BLADE'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<x-theme-script />
|
||||
@vite(config('livewire-material.showcase.vite'))
|
||||
</head>
|
||||
<body style="background-color: var(--md-sys-color-surface);">
|
||||
<x-surface outlined padding="space200" style="margin: var(--md-sys-measurement-space200);">
|
||||
<x-row id="bare-switch-row" justify="between" gap="space200">
|
||||
<x-stack gap="space50">
|
||||
<div class="md-type-title-sm">Drop the mark</div>
|
||||
<p class="md-type-body-sm md-ink-variant">Takes effect on the next sync: your calendar is rewritten with the new names, and a watch keeps the first characters of each.</p>
|
||||
</x-stack>
|
||||
<x-toggle id="row-bare-switch" aria-label="Drop the mark from exported workouts" />
|
||||
</x-row>
|
||||
<x-row id="labelled-switch-row" justify="between" gap="space200">
|
||||
<p class="md-type-body-sm md-ink-variant">Takes effect on the next sync: your calendar is rewritten with the new names, and a watch keeps the first characters of each.</p>
|
||||
<x-toggle id="row-labelled-switch" label="Notifications on this device whenever a session changes" />
|
||||
</x-row>
|
||||
<x-row id="bare-check-row" justify="between" gap="space200">
|
||||
<p class="md-type-body-sm md-ink-variant">Takes effect on the next sync: your calendar is rewritten with the new names, and a watch keeps the first characters of each.</p>
|
||||
<x-checkbox id="row-bare-check" aria-label="Drop the mark" />
|
||||
</x-row>
|
||||
</x-surface>
|
||||
</body>
|
||||
</html>
|
||||
BLADE));
|
||||
|
||||
// [the control's drawn width, its end inside its row, the root's end inside its row].
|
||||
$control = fn (string $input, string $drawing, string $root): string => "(() => {
|
||||
const drawing = document.getElementById('{$input}').closest('{$drawing}').getBoundingClientRect();
|
||||
const root = document.getElementById('{$input}').closest('{$root}').getBoundingClientRect();
|
||||
const row = document.getElementById('{$input}').closest('[data-md-row]').getBoundingClientRect();
|
||||
|
||||
return [Math.round(drawing.width), drawing.right <= row.right + 0.5, root.right <= row.right + 0.5];
|
||||
})()";
|
||||
|
||||
// A phone's window: the row is 329px across, less than the text beside each control would take.
|
||||
$page = visit('/selection-row-probe')->resize(393, 800)->waitForEvent('networkidle')
|
||||
->assertScript("document.readyState === 'complete'");
|
||||
|
||||
expect($page->script($control('row-bare-switch', '[data-md-switch]', '[data-md-toggle]')))->toBe([52, true, true])
|
||||
->and($page->script($control('row-labelled-switch', '[data-md-switch]', '[data-md-toggle]')))->toBe([52, true, true])
|
||||
->and($page->script($control('row-bare-check', '[data-md-checkbox-box]', '[data-md-checkbox]')))->toBe([18, true, true])
|
||||
// The switch's own label wraps inside the switch's root rather than running past it.
|
||||
->and($page->script("(() => { const label = document.querySelector('[data-md-toggle]:has(#row-labelled-switch) [data-md-selection-label]').getBoundingClientRect(); const root = document.querySelector('[data-md-toggle]:has(#row-labelled-switch)').getBoundingClientRect(); return label.right <= root.right + 0.5 && label.height > 24; })()"))->toBeTrue();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user