From c9112fcaeb37272947c27f44c948ea72a48b9d1a Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Wed, 17 Sep 2025 18:35:05 -0400 Subject: [PATCH 1/5] pulls PageLayout changes from mp/rm-box-and-sx-from-components --- .../PageLayout.dev.stories.module.css | 9 ++ .../src/PageLayout/PageLayout.dev.stories.tsx | 11 +- .../src/PageLayout/PageLayout.module.css | 20 +++ .../src/PageLayout/PageLayout.stories.tsx | 1 - packages/react/src/PageLayout/PageLayout.tsx | 141 +++++++----------- .../src/components/PageLayout.tsx | 58 +++++++ packages/styled-react/src/sx.ts | 8 + 7 files changed, 158 insertions(+), 90 deletions(-) create mode 100644 packages/react/src/PageLayout/PageLayout.dev.stories.module.css create mode 100644 packages/styled-react/src/components/PageLayout.tsx create mode 100644 packages/styled-react/src/sx.ts diff --git a/packages/react/src/PageLayout/PageLayout.dev.stories.module.css b/packages/react/src/PageLayout/PageLayout.dev.stories.module.css new file mode 100644 index 00000000000..35584590235 --- /dev/null +++ b/packages/react/src/PageLayout/PageLayout.dev.stories.module.css @@ -0,0 +1,9 @@ +.DebugPageLayout { + /* `red` is just used for debugging purposes. VRTs fail if changed. */ + /* stylelint-disable-next-line color-named */ + border: var(--borderWidth-thin) solid red; +} + +.SuccessColor { + color: var(--fgColor-success); +} diff --git a/packages/react/src/PageLayout/PageLayout.dev.stories.tsx b/packages/react/src/PageLayout/PageLayout.dev.stories.tsx index 1eca843ae20..5be8f52ffad 100644 --- a/packages/react/src/PageLayout/PageLayout.dev.stories.tsx +++ b/packages/react/src/PageLayout/PageLayout.dev.stories.tsx @@ -1,6 +1,7 @@ import type {Meta, StoryFn} from '@storybook/react-vite' import {Placeholder} from '../Placeholder' import {PageLayout} from './PageLayout' +import classes from './PageLayout.dev.stories.module.css' const meta: Meta = { title: 'Components/PageLayout/Dev', @@ -346,11 +347,11 @@ export const Default: StoryFn = args => ( padding={args.padding} rowGap={args.rowGap} columnGap={args.columnGap} - sx={{border: '1px solid red'}} + className={classes.DebugPageLayout} > ( ( ( padding={args.padding} rowGap={args.rowGap} columnGap={args.columnGap} - sx={args.sx} > {args['Render header?'] ? ( className?: string style?: React.CSSProperties -} & SxProp +} // eslint-disable-next-line @typescript-eslint/no-unused-vars const containerWidths = { @@ -73,7 +70,6 @@ const Root: React.FC> = ({ rowGap = 'normal', columnGap = 'normal', children, - sx, className, style, _slotsConfig: slotsConfig, @@ -93,14 +89,13 @@ const Root: React.FC> = ({ return ( -
@@ -108,7 +103,7 @@ const Root: React.FC> = ({
{rest}
{slots.footer}
-
+
) } @@ -123,11 +118,10 @@ type DividerProps = { className?: string style?: React.CSSProperties position?: keyof typeof panePositions -} & SxProp +} const HorizontalDivider: React.FC> = ({ variant = 'none', - sx, className, position, style, @@ -136,8 +130,7 @@ const HorizontalDivider: React.FC> = ({ const responsiveVariant = useResponsiveValue(variant, 'none') return ( - { const [isDragging, setIsDragging] = React.useState(false) const [isKeyboardDrag, setIsKeyboardDrag] = React.useState(false) @@ -268,8 +260,7 @@ const VerticalDivider: React.FC {draggable ? ( // Drag handle - <> - { - if (event.button === 0) { - setIsDragging(true) - onDragStart?.() - } - }} - onKeyDown={event => { - if ( - event.key === 'ArrowLeft' || - event.key === 'ArrowRight' || - event.key === 'ArrowUp' || - event.key === 'ArrowDown' - ) { - setIsKeyboardDrag(true) - onDragStart?.() - } - }} - onDoubleClick={onDoubleClick} - /> - +
{ + if (event.button === 0) { + setIsDragging(true) + onDragStart?.() + } + }} + onKeyDown={(event: React.KeyboardEvent) => { + if ( + event.key === 'ArrowLeft' || + event.key === 'ArrowRight' || + event.key === 'ArrowUp' || + event.key === 'ArrowDown' + ) { + setIsKeyboardDrag(true) + onDragStart?.() + } + }} + onDoubleClick={onDoubleClick} + /> ) : null} - +
) } @@ -355,7 +336,7 @@ export type PageLayoutHeaderProps = { hidden?: boolean | ResponsiveValue className?: string style?: React.CSSProperties -} & SxProp +} const Header: React.FC> = ({ 'aria-label': label, @@ -366,7 +347,6 @@ const Header: React.FC> = ({ hidden = false, children, style, - sx, className, }) => { // Combine divider and dividerWhenNarrow for backwards compatibility @@ -380,12 +360,10 @@ const Header: React.FC> = ({ const {rowGap} = React.useContext(PageLayoutContext) return ( - + ) } @@ -443,7 +421,7 @@ export type PageLayoutContentProps = { hidden?: boolean | ResponsiveValue className?: string style?: React.CSSProperties -} & SxProp +} // TODO: Account for pane width when centering content // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -462,19 +440,17 @@ const Content: React.FC> = ({ padding = 'none', hidden = false, children, - sx, className, style, }) => { const isHidden = useResponsiveValue(hidden, false) + const Component = as return ( - @@ -489,7 +465,7 @@ const Content: React.FC> = ({ > {children} - + ) } @@ -563,7 +539,7 @@ export type PageLayoutPaneProps = { id?: string className?: string style?: React.CSSProperties -} & SxProp +} // eslint-disable-next-line @typescript-eslint/no-unused-vars const panePositions = { @@ -601,7 +577,6 @@ const Pane = React.forwardRef -
+ ) }, ) @@ -803,7 +779,7 @@ export type PageLayoutFooterProps = { hidden?: boolean | ResponsiveValue className?: string style?: React.CSSProperties -} & SxProp +} const Footer: React.FC> = ({ 'aria-label': label, @@ -813,7 +789,6 @@ const Footer: React.FC> = ({ dividerWhenNarrow = 'inherit', hidden = false, children, - sx, className, style, }) => { @@ -828,13 +803,11 @@ const Footer: React.FC> = ({ const {rowGap} = React.useContext(PageLayoutContext) return ( - + ) } diff --git a/packages/styled-react/src/components/PageLayout.tsx b/packages/styled-react/src/components/PageLayout.tsx new file mode 100644 index 00000000000..eec141dc510 --- /dev/null +++ b/packages/styled-react/src/components/PageLayout.tsx @@ -0,0 +1,58 @@ +import React, {type PropsWithChildren} from 'react' +import styled from 'styled-components' +import type { + PageLayoutProps as PrimerPageLayoutProps, + PageLayoutContentProps as PrimerPageLayoutContentProps, + PageLayoutHeaderProps as PrimerPageLayoutHeaderProps, + PageLayoutPaneProps as PrimerPageLayoutPaneProps, + PageLayoutFooterProps as PrimerPageLayoutFooterProps, +} from '@primer/react' +import {PageLayout as PrimerPageLayout} from '@primer/react' +import {sx, type SxProp} from '../sx' + +const Wrapper = styled.div` + ${sx} +` + +type PageLayoutProps = PropsWithChildren & SxProp + +const PageLayoutImpl = React.forwardRef((props, ref) => { + // @ts-expect-error - PrimerPageLayout is not recognized as a valid component type + return +}) + +type PageLayoutContentProps = PropsWithChildren & SxProp + +const PageLayoutContent = React.forwardRef((props, ref) => { + return +}) + +type PageLayoutHeaderProps = PropsWithChildren & SxProp + +const PageLayoutHeader = React.forwardRef((props, ref) => { + // @ts-expect-error - PrimerPageLayout.Header is not recognized as a valid component type + return +}) + +type PageLayoutPaneProps = PropsWithChildren & SxProp + +const PageLayoutPane = React.forwardRef((props, ref) => { + return +}) + +type PageLayoutFooterProps = PropsWithChildren & SxProp + +const PageLayoutFooter = React.forwardRef((props, ref) => { + // @ts-expect-error - PrimerPageLayout.Footer is not recognized as a valid component type + return +}) + +const PageLayout = Object.assign(PageLayoutImpl, { + Content: PageLayoutContent, + Header: PageLayoutHeader, + Pane: PageLayoutPane, + Footer: PageLayoutFooter, +}) + +export {PageLayout} +export type {PageLayoutProps} diff --git a/packages/styled-react/src/sx.ts b/packages/styled-react/src/sx.ts new file mode 100644 index 00000000000..e3ff0277f10 --- /dev/null +++ b/packages/styled-react/src/sx.ts @@ -0,0 +1,8 @@ +import css from '@styled-system/css' +import type {SxProp} from '@primer/react' + +export const sx = (props: SxProp) => { + return css(props.sx) +} + +export type {SxProp} From cbc522ea8f7456504fa911a89a65aa784a2fbdb6 Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Wed, 17 Sep 2025 18:37:03 -0400 Subject: [PATCH 2/5] adds PageLayout to styled-react --- packages/styled-react/src/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/styled-react/src/index.tsx b/packages/styled-react/src/index.tsx index 66763c5389a..fc11e02e660 100644 --- a/packages/styled-react/src/index.tsx +++ b/packages/styled-react/src/index.tsx @@ -28,6 +28,7 @@ import type { SpaceProps, TypographyProps, } from 'styled-system' +import {PageLayout} from './components/PageLayout' type StyledProps = SxProp & SpaceProps & @@ -90,7 +91,7 @@ const ToggleSwitch = forwardRef(function T return }) -export {SegmentedControl, StateLabel, SubNav, ToggleSwitch} +export {PageLayout, SegmentedControl, StateLabel, SubNav, ToggleSwitch} export { ActionList, @@ -116,7 +117,6 @@ export { NavList, Overlay, PageHeader, - PageLayout, ProgressBar, RadioGroup, RelativeTime, From 7485692b6de5329823fa9bafb0f0ee30e043c62a Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Wed, 17 Sep 2025 19:01:00 -0400 Subject: [PATCH 3/5] adds changeset --- .changeset/gold-geckos-send.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/gold-geckos-send.md diff --git a/.changeset/gold-geckos-send.md b/.changeset/gold-geckos-send.md new file mode 100644 index 00000000000..5e3441f4a4a --- /dev/null +++ b/.changeset/gold-geckos-send.md @@ -0,0 +1,5 @@ +--- +'@primer/react': major +--- + +Removes sx prop from PageLayout and subcomponents From 1fcd33935ba1000759661a8d1bc39e34b79705b8 Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Tue, 23 Sep 2025 20:56:19 -0400 Subject: [PATCH 4/5] updates snapshots --- .../src/__tests__/__snapshots__/exports.test.ts.snap | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/styled-react/src/__tests__/__snapshots__/exports.test.ts.snap b/packages/styled-react/src/__tests__/__snapshots__/exports.test.ts.snap index 3cef707a5e0..fbb4eb59ca8 100644 --- a/packages/styled-react/src/__tests__/__snapshots__/exports.test.ts.snap +++ b/packages/styled-react/src/__tests__/__snapshots__/exports.test.ts.snap @@ -28,6 +28,7 @@ exports[`@primer/styled-react exports 1`] = ` "Overlay", "PageHeader", "PageLayout", + "ProgressBar", "RadioGroup", "RelativeTime", "SegmentedControl", From 52adc312186a2859d523702ffbb38aa1d1c56231 Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Wed, 24 Sep 2025 13:21:39 -0400 Subject: [PATCH 5/5] adds primer-styled PageLayout export back to exports --- packages/styled-react/src/components/PageLayout.tsx | 3 +-- packages/styled-react/src/index.tsx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/styled-react/src/components/PageLayout.tsx b/packages/styled-react/src/components/PageLayout.tsx index eec141dc510..de4670c6528 100644 --- a/packages/styled-react/src/components/PageLayout.tsx +++ b/packages/styled-react/src/components/PageLayout.tsx @@ -54,5 +54,4 @@ const PageLayout = Object.assign(PageLayoutImpl, { Footer: PageLayoutFooter, }) -export {PageLayout} -export type {PageLayoutProps} +export {PageLayout, type PageLayoutProps} diff --git a/packages/styled-react/src/index.tsx b/packages/styled-react/src/index.tsx index 8be52072298..53e0249daa4 100644 --- a/packages/styled-react/src/index.tsx +++ b/packages/styled-react/src/index.tsx @@ -16,7 +16,6 @@ export {Label} from '@primer/react' export {Link} from '@primer/react' export {NavList} from '@primer/react' export {Overlay} from '@primer/react' -export {PageLayout} from '@primer/react' export {ProgressBar} from '@primer/react' export {Select} from '@primer/react' export {Text} from '@primer/react' @@ -40,6 +39,7 @@ export {CounterLabel, type CounterLabelProps} from './components/CounterLabel' export {Flash} from './components/Flash' export {Header, type HeaderProps} from './components/Header' export {LinkButton, type LinkButtonProps} from './components/LinkButton' +export {PageLayout, type PageLayoutProps} from './components/PageLayout' export { PageHeader, type PageHeaderProps,