Keep a nested dialog's head out of the full-screen phone rules
Plan step 36 review of 3c235ecc. The rules that hide a full-screen
dialog's head and title below 600px, zero its subtitle's margin and
shorten its action bar matched descendants of the full-screen dialog, so
a basic confirm opened from inside its body lost its title and its
padding on a phone. They now go through > [data-md-modal-box] >, as the
divider marks already did (old dialog.css: "the child combinators tie a
mark to its own dialog's rows"), and the icon and subtitle checks look
only at the head's own children.
The computed data-md-modal-divider flag stays. It is correct (the old
view's data-dialog-head placement, one for one), and though a :has()
chain on the box could say when the bar owns the rule, the flag keeps
bar, head and actions on one hook the view already has the facts for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
21f8ed826c
commit
d86392fd47
@@ -26,6 +26,10 @@
|
||||
* the head already owns); `data-md-separator` (the `separator` prop) draws the rule whatever the
|
||||
* scroll. The rule is a pseudo-element over the row's own edge, so showing it moves nothing.
|
||||
*
|
||||
* Every rule that reads the full-screen flag or the head's icon and subtitle goes through
|
||||
* `> [data-md-modal-box] >`, as the divider marks do: a basic dialog opened from inside a
|
||||
* full-screen dialog's body is a descendant of it, and must keep its own title and padding.
|
||||
*
|
||||
* `[data-md-modal-body]:focus-visible` is Chrome's own focusable scroll container catching the
|
||||
* dialog's first focus when nothing inside can take it — M3's 3px secondary indicator, drawn
|
||||
* inside the edge because the box's rounded, overflow-hidden corner would clip one drawn outside.
|
||||
@@ -128,14 +132,14 @@
|
||||
padding-bottom: var(--md-sys-measurement-space100);
|
||||
}
|
||||
|
||||
[data-md-modal-head]:has([data-md-icon]) {
|
||||
[data-md-modal-head]:has(> [data-md-icon]) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* On a phone the bar already names a plain dialog; the head hides unless an icon or a
|
||||
subtitle keeps it there (the bar cannot hold either). */
|
||||
@media (width < 600px) {
|
||||
[data-md-modal][data-md-fullscreen] [data-md-modal-head]:not(:has([data-md-icon])):not(:has([data-md-modal-subtitle])) {
|
||||
[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-head]:not(:has(> [data-md-icon], > [data-md-modal-subtitle])) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -152,7 +156,7 @@
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
[data-md-modal][data-md-fullscreen]:not(:has([data-md-modal-head] [data-md-icon])) [data-md-modal-title] {
|
||||
[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-head]:not(:has(> [data-md-icon])) > [data-md-modal-title] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +173,7 @@
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
[data-md-modal][data-md-fullscreen]:not(:has([data-md-modal-head] [data-md-icon])) [data-md-modal-subtitle] {
|
||||
[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-head]:not(:has(> [data-md-icon])) > [data-md-modal-subtitle] {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
@@ -197,7 +201,7 @@
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
[data-md-modal][data-md-fullscreen] [data-md-modal-head]:not(:has([data-md-icon])):not(:has([data-md-modal-subtitle])) ~ [data-md-modal-body] {
|
||||
[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-head]:not(:has(> [data-md-icon], > [data-md-modal-subtitle])) ~ [data-md-modal-body] {
|
||||
padding-top: var(--md-sys-measurement-space200);
|
||||
}
|
||||
}
|
||||
@@ -223,7 +227,7 @@
|
||||
}
|
||||
|
||||
@media (width < 600px) {
|
||||
[data-md-modal][data-md-fullscreen] [data-md-modal-actions] {
|
||||
[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-actions] {
|
||||
min-height: var(--md-sys-measurement-space700);
|
||||
padding-top: var(--md-sys-measurement-space100);
|
||||
padding-bottom: var(--md-sys-measurement-space100);
|
||||
|
||||
@@ -59,9 +59,13 @@ it('keeps a full-screen dialog\'s subtitle on a phone, where its bar carries the
|
||||
// The markup is the same at every width; modal.css (ContainmentStylesheetsTest) decides which
|
||||
// of the bar/head/title/subtitle show below 600px, keyed on the icon and the subtitle.
|
||||
expect(File::get(__DIR__.'/../../../resources/css/components/modal.css'))
|
||||
->toContain('[data-md-modal][data-md-fullscreen] [data-md-modal-head]:not(:has([data-md-icon])):not(:has([data-md-modal-subtitle]))')
|
||||
->toContain('[data-md-modal][data-md-fullscreen]:not(:has([data-md-modal-head] [data-md-icon])) [data-md-modal-title]')
|
||||
->toContain('[data-md-modal][data-md-fullscreen]:not(:has([data-md-modal-head] [data-md-icon])) [data-md-modal-subtitle]');
|
||||
->toContain('[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-head]:not(:has(> [data-md-icon], > [data-md-modal-subtitle]))')
|
||||
->toContain('[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-head]:not(:has(> [data-md-icon])) > [data-md-modal-title]')
|
||||
->toContain('[data-md-modal][data-md-fullscreen] > [data-md-modal-box] > [data-md-modal-head]:not(:has(> [data-md-icon])) > [data-md-modal-subtitle]');
|
||||
|
||||
// Each through its own box, so a basic dialog opened inside a full-screen one's body keeps its
|
||||
// title and padding on a phone.
|
||||
expect(File::get(__DIR__.'/../../../resources/css/components/modal.css'))->not->toMatch('/\[data-md-fullscreen\](?::[^ ]+)? \[/');
|
||||
});
|
||||
|
||||
it('pins a dialog\'s headline and actions and scrolls only the body between them', function () {
|
||||
|
||||
Reference in New Issue
Block a user