Add the stack layout component and the layout foundation
Plan step 35: <x-stack gap align>, the first of M3's layout components, with what they all share - src/Support/Layout.php reading the props into data-md-* attributes, the spacing-token gap and padding rules, the hide-below/hide-from rules in material.visibility, the stylesheet checks for resources/css/layout, the browser test file and the skill's Layout group. The Workbench puts the material layers above Tailwind's preflight, which would otherwise zero every layout padding and margin. 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
6be9f35c98
commit
b677e60876
@@ -5,3 +5,5 @@
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import './layout/stack.css';
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Gap and padding, the two spacing props of the layout components, on M3's measurement scale.
|
||||
*
|
||||
* Both take only a token's name — `data-md-gap="space200"`, `data-md-padding="space300"` — and the
|
||||
* value is that token, `--md-sys-measurement-space200` (docs/reference/m3/styles-supplement.md
|
||||
* § Spacing; resources/css/tokens/spacing.css). A name the scale does not have renders as `none`
|
||||
* (src/Support/Layout.php): no gap, and no padding.
|
||||
*
|
||||
* A gap is written to `--md-gap`, not to `gap` itself: the stack, row, grid and feed read it (a
|
||||
* grid also counts it into a column's width), and each resets it on itself at zero specificity, so
|
||||
* an arrangement nested in another never inherits its parent's gap. Padding goes on directly.
|
||||
*
|
||||
* In `material.layout`, under every component.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@layer material.layout {
|
||||
[data-md-gap='none'] {
|
||||
--md-gap: 0px;
|
||||
}
|
||||
|
||||
[data-md-gap='space25'] {
|
||||
--md-gap: var(--md-sys-measurement-space25);
|
||||
}
|
||||
|
||||
[data-md-gap='space50'] {
|
||||
--md-gap: var(--md-sys-measurement-space50);
|
||||
}
|
||||
|
||||
[data-md-gap='space75'] {
|
||||
--md-gap: var(--md-sys-measurement-space75);
|
||||
}
|
||||
|
||||
[data-md-gap='space100'] {
|
||||
--md-gap: var(--md-sys-measurement-space100);
|
||||
}
|
||||
|
||||
[data-md-gap='space125'] {
|
||||
--md-gap: var(--md-sys-measurement-space125);
|
||||
}
|
||||
|
||||
[data-md-gap='space200'] {
|
||||
--md-gap: var(--md-sys-measurement-space200);
|
||||
}
|
||||
|
||||
[data-md-gap='space300'] {
|
||||
--md-gap: var(--md-sys-measurement-space300);
|
||||
}
|
||||
|
||||
[data-md-gap='space400'] {
|
||||
--md-gap: var(--md-sys-measurement-space400);
|
||||
}
|
||||
|
||||
[data-md-gap='space500'] {
|
||||
--md-gap: var(--md-sys-measurement-space500);
|
||||
}
|
||||
|
||||
[data-md-gap='space600'] {
|
||||
--md-gap: var(--md-sys-measurement-space600);
|
||||
}
|
||||
|
||||
[data-md-gap='space700'] {
|
||||
--md-gap: var(--md-sys-measurement-space700);
|
||||
}
|
||||
|
||||
[data-md-gap='space800'] {
|
||||
--md-gap: var(--md-sys-measurement-space800);
|
||||
}
|
||||
|
||||
[data-md-gap='space900'] {
|
||||
--md-gap: var(--md-sys-measurement-space900);
|
||||
}
|
||||
|
||||
[data-md-padding='space25'] {
|
||||
padding: var(--md-sys-measurement-space25);
|
||||
}
|
||||
|
||||
[data-md-padding='space50'] {
|
||||
padding: var(--md-sys-measurement-space50);
|
||||
}
|
||||
|
||||
[data-md-padding='space75'] {
|
||||
padding: var(--md-sys-measurement-space75);
|
||||
}
|
||||
|
||||
[data-md-padding='space100'] {
|
||||
padding: var(--md-sys-measurement-space100);
|
||||
}
|
||||
|
||||
[data-md-padding='space125'] {
|
||||
padding: var(--md-sys-measurement-space125);
|
||||
}
|
||||
|
||||
[data-md-padding='space200'] {
|
||||
padding: var(--md-sys-measurement-space200);
|
||||
}
|
||||
|
||||
[data-md-padding='space300'] {
|
||||
padding: var(--md-sys-measurement-space300);
|
||||
}
|
||||
|
||||
[data-md-padding='space400'] {
|
||||
padding: var(--md-sys-measurement-space400);
|
||||
}
|
||||
|
||||
[data-md-padding='space500'] {
|
||||
padding: var(--md-sys-measurement-space500);
|
||||
}
|
||||
|
||||
[data-md-padding='space600'] {
|
||||
padding: var(--md-sys-measurement-space600);
|
||||
}
|
||||
|
||||
[data-md-padding='space700'] {
|
||||
padding: var(--md-sys-measurement-space700);
|
||||
}
|
||||
|
||||
[data-md-padding='space800'] {
|
||||
padding: var(--md-sys-measurement-space800);
|
||||
}
|
||||
|
||||
[data-md-padding='space900'] {
|
||||
padding: var(--md-sys-measurement-space900);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* <x-stack>: its children one under another, in a pane.
|
||||
*
|
||||
* A flex column, stretched across the stack's width unless `data-md-align` says `start`, `center`
|
||||
* or `end`. The space between the children is `--md-gap` (spacing.css), one of M3's spacing
|
||||
* tokens and none by default; M3 groups with proximity, so the gap is the grouping
|
||||
* (docs/reference/m3/foundations.md § Layout → Grids & spacing). M3 defines no in-pane arrangement
|
||||
* component; this is the neutral one, beside <x-row> and <x-grid>.
|
||||
*
|
||||
* In `material.layout`; `hide-below`/`hide-from` come from visibility.css.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@import './spacing.css';
|
||||
@import './visibility.css';
|
||||
|
||||
@layer material.layout {
|
||||
:where([data-md-stack]) {
|
||||
--md-gap: 0px;
|
||||
}
|
||||
|
||||
[data-md-stack] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--md-gap);
|
||||
}
|
||||
|
||||
[data-md-stack][data-md-align='start'] {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
[data-md-stack][data-md-align='center'] {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
[data-md-stack][data-md-align='end'] {
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* `hide-below` and `hide-from`, the visibility props every layout component takes.
|
||||
*
|
||||
* The breakpoints are M3's (docs/reference/m3/foundations.md § Layout → Breakpoints): compact below
|
||||
* 600px, medium 600, expanded 840, large 1200, extra-large 1600, in px — a dp is a CSS pixel, so a
|
||||
* larger text size never moves them. `data-md-hide-below="expanded"` hides an element on a window
|
||||
* narrower than 840px; `data-md-hide-from="expanded"` hides it from 840px on. There is nothing
|
||||
* below compact and from compact is every width, so neither names it; `hidden` does that.
|
||||
*
|
||||
* In `material.visibility`, the last layer, so it beats the `display` of the component it sits on
|
||||
* and of every other package rule. An application's own unlayered rule still wins, by design.
|
||||
*/
|
||||
|
||||
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
|
||||
|
||||
@layer material.visibility {
|
||||
@media (width < 600px) {
|
||||
[data-md-hide-below='medium'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 840px) {
|
||||
[data-md-hide-below='expanded'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 1200px) {
|
||||
[data-md-hide-below='large'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width < 1600px) {
|
||||
[data-md-hide-below='extra-large'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 600px) {
|
||||
[data-md-hide-from='medium'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 840px) {
|
||||
[data-md-hide-from='expanded'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1200px) {
|
||||
[data-md-hide-from='large'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (width >= 1600px) {
|
||||
[data-md-hide-from='extra-large'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user