diff --git a/packages/cli/assets/templates/pages/detail-page/page.tsx b/packages/cli/assets/templates/pages/detail-page/page.tsx index e94d4531f73..a206ff10ed5 100644 --- a/packages/cli/assets/templates/pages/detail-page/page.tsx +++ b/packages/cli/assets/templates/pages/detail-page/page.tsx @@ -43,20 +43,9 @@ import { // ─── Styles ───────────────────────────────────────────────────────────────── import type {CSSProperties} from 'react'; -// The only custom CSS in this template is small optical-alignment negative -// margins: the tab row's block dock has no prop (see tabsRow) and List has no -// "bleed to container edge" prop (#2626). Everything else uses props. Plain -// inline styles — no StyleX compiler required. - -// Dock the tab bar on the header's bottom edge so the active-tab underline -// meets the header divider. TabList's `isFullBleed` handles the inline bleed; -// the block-end dock is still hand-tuned because the tab row sits inside -// nested flex wrappers (StackItem > HStack), where no component prop can -// reach the header's padding edge (a LayoutHeader docking slot would). -const tabsRow: CSSProperties = { - marginBottom: -16, - marginTop: 12, -}; +// The only custom CSS in this template is a small optical-alignment negative +// margin: List has no "bleed to container edge" prop (#2626). Everything else +// uses props. Plain inline styles — no StyleX compiler required. // Pull the list items' inner padding back so their content optically aligns // with the section heading above (ListItem insets content by ~8px). No // edge/inset prop on List (#2626). @@ -178,7 +167,7 @@ function PageHeader({ isNarrow: boolean; }) { return ( - + @@ -260,7 +249,7 @@ function PageHeader({ )} - + { */ padding?: SpacingStep; + /** + * Block-end (bottom) padding override. Takes precedence over `padding` on + * that edge only; the block-start edge and both inline edges are left alone. + * `paddingBlockEnd={0}` docks the last child on the header's bottom edge, so + * a tab strip's underline meets `hasDivider` with no hand-written margin. + * Accepts numeric spacing steps: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10. + */ + paddingBlockEnd?: SpacingStep; + /** * Accessible label for the landmark. * Required when role is set and multiple landmarks of the same type exist. @@ -140,6 +150,7 @@ export function LayoutHeader({ height, label, padding, + paddingBlockEnd, role, xstyle, className, @@ -179,6 +190,12 @@ export function LayoutHeader({ padding != null && containerPaddingInlineVarStyles[padding], padding != null && containerPaddingBlockStartVarStyles[padding], padding != null && containerPaddingBlockEndVarStyles[padding], + // Per-edge override last so it wins over `padding` on its own edge. + // The container var moves with it so bleed children compensate + // against the padding actually applied, not the one asked for. + paddingBlockEnd != null && paddingBlockEndStyles[paddingBlockEnd], + paddingBlockEnd != null && + containerPaddingBlockEndVarStyles[paddingBlockEnd], )}> {children}