diff --git a/.changeset/spotty-parents-cheat.md b/.changeset/spotty-parents-cheat.md
new file mode 100644
index 00000000000..54544ed8632
--- /dev/null
+++ b/.changeset/spotty-parents-cheat.md
@@ -0,0 +1,19 @@
+---
+"@primer/react": minor
+---
+
+* Updated the `divider` prop in `PageLayout.Header`, `PageLayout.Pane`, and `PageLayout.Footer` to use the new responsive prop API introduced in https://github.com/primer/react/pull/2174.
+* Deprecated the `dividerWhenNarrow` prop in favor of the new responsive prop API
+
+**Before**
+
+```
+divider="line"
+dividerWhenNarrow="filled"
+```
+
+**After**
+
+```
+divider={{regular: 'line', narrow: 'filled'}}
+```
diff --git a/docs/content/PageLayout.mdx b/docs/content/PageLayout.mdx
index d9ad832f9e7..277c0c1a255 100644
--- a/docs/content/PageLayout.mdx
+++ b/docs/content/PageLayout.mdx
@@ -48,7 +48,8 @@ See [storybook](https://primer.style/react/storybook?path=/story/layout-pagelayo
-
+ {/* You can change the divider based on the viewport width */}
+
@@ -172,25 +173,39 @@ See [storybook](https://primer.style/react/storybook?path=/story/layout-pagelayo
@@ -213,10 +228,10 @@ See [storybook](https://primer.style/react/storybook?path=/story/layout-pagelayo
name="hidden"
type={`| boolean
| {
- narrow?: boolean
- regular?: boolean
- wide?: boolean
-}`}
+ narrow?: boolean
+ regular?: boolean
+ wide?: boolean
+ }`}
defaultValue="false"
description="Whether the content is hidden."
/>
@@ -250,25 +265,39 @@ See [storybook](https://primer.style/react/storybook?path=/story/layout-pagelayo
@@ -281,25 +310,39 @@ See [storybook](https://primer.style/react/storybook?path=/story/layout-pagelayo
diff --git a/src/PageLayout/PageLayout.tsx b/src/PageLayout/PageLayout.tsx
index b317597f12f..ed1f9fa820a 100644
--- a/src/PageLayout/PageLayout.tsx
+++ b/src/PageLayout/PageLayout.tsx
@@ -1,6 +1,6 @@
import React from 'react'
import {Box} from '..'
-import {ResponsiveValue, useResponsiveValue} from '../hooks/useResponsiveValue'
+import {isResponsiveValue, ResponsiveValue, useResponsiveValue} from '../hooks/useResponsiveValue'
import {BetterSystemStyleObject, merge, SxProp} from '../sx'
const REGION_ORDER = {
@@ -79,8 +79,7 @@ Root.displayName = 'PageLayout'
// Divider (internal)
type DividerProps = {
- variant?: 'none' | 'line'
- variantWhenNarrow?: 'inherit' | 'none' | 'line' | 'filled'
+ variant?: 'none' | 'line' | 'filled' | ResponsiveValue<'none' | 'line' | 'filled'>
} & SxProp
const horizontalDividerVariants = {
@@ -111,12 +110,9 @@ function negateSpacingValue(value: number | null | Array) {
return value === null ? null : -value
}
-const HorizontalDivider: React.FC> = ({
- variant = 'none',
- variantWhenNarrow = 'inherit',
- sx = {}
-}) => {
+const HorizontalDivider: React.FC> = ({variant = 'none', sx = {}}) => {
const {padding} = React.useContext(PageLayoutContext)
+ const responsiveVariant = useResponsiveValue(variant, 'none')
return (
> = ({
{
// Stretch divider to viewport edges on narrow screens
marginX: negateSpacingValue(SPACING_MAP[padding]),
- ...horizontalDividerVariants[variantWhenNarrow === 'inherit' ? variant : variantWhenNarrow],
+ ...horizontalDividerVariants[responsiveVariant],
[`@media screen and (min-width: ${theme.breakpoints[1]})`]: {
- marginX: '0 !important',
- ...horizontalDividerVariants[variant]
+ marginX: '0 !important'
}
},
sx
@@ -157,26 +152,17 @@ const verticalDividerVariants = {
}
}
-const VerticalDivider: React.FC> = ({
- variant = 'none',
- variantWhenNarrow = 'inherit',
- sx = {}
-}) => {
+const VerticalDivider: React.FC> = ({variant = 'none', sx = {}}) => {
+ const responsiveVariant = useResponsiveValue(variant, 'none')
return (
- merge(
- {
- height: '100%',
- ...verticalDividerVariants[variantWhenNarrow === 'inherit' ? variant : variantWhenNarrow],
- [`@media screen and (min-width: ${theme.breakpoints[1]})`]: {
- ...verticalDividerVariants[variant]
- }
- },
- sx
- )
- }
+ sx={merge(
+ {
+ height: '100%',
+ ...verticalDividerVariants[responsiveVariant]
+ },
+ sx
+ )}
/>
)
}
@@ -185,7 +171,21 @@ const VerticalDivider: React.FC> = ({
// PageLayout.Header
export type PageLayoutHeaderProps = {
- divider?: 'none' | 'line'
+ divider?: 'none' | 'line' | ResponsiveValue<'none' | 'line', 'none' | 'line' | 'filled'>
+ /**
+ * @deprecated Use the `divider` prop with a responsive value instead.
+ *
+ * Before:
+ * ```
+ * divider="line"
+ * dividerWhenNarrow="filled"
+ * ```
+ *
+ * After:
+ * ```
+ * divider={{regular: 'line', narrow: 'filled'}}
+ * ```
+ */
dividerWhenNarrow?: 'inherit' | 'none' | 'line' | 'filled'
hidden?: boolean | ResponsiveValue
} & SxProp
@@ -197,6 +197,13 @@ const Header: React.FC> = ({
children,
sx = {}
}) => {
+ // Combine divider and dividerWhenNarrow for backwards compatibility
+ const dividerProp =
+ !isResponsiveValue(divider) && dividerWhenNarrow !== 'inherit'
+ ? {regular: divider, narrow: dividerWhenNarrow}
+ : divider
+
+ const dividerVariant = useResponsiveValue(dividerProp, 'none')
const isHidden = useResponsiveValue(hidden, false)
const {rowGap} = React.useContext(PageLayoutContext)
return (
@@ -213,11 +220,7 @@ const Header: React.FC> = ({
)}
>
{children}
-
+
)
}
@@ -279,7 +282,21 @@ export type PageLayoutPaneProps = {
position?: keyof typeof panePositions
positionWhenNarrow?: 'inherit' | keyof typeof panePositions
width?: keyof typeof paneWidths
- divider?: 'none' | 'line'
+ divider?: 'none' | 'line' | ResponsiveValue<'none' | 'line', 'none' | 'line' | 'filled'>
+ /**
+ * @deprecated Use the `divider` prop with a responsive value instead.
+ *
+ * Before:
+ * ```
+ * divider="line"
+ * dividerWhenNarrow="filled"
+ * ```
+ *
+ * After:
+ * ```
+ * divider={{regular: 'line', narrow: 'filled'}}
+ * ```
+ */
dividerWhenNarrow?: 'inherit' | 'none' | 'line' | 'filled'
hidden?: boolean | ResponsiveValue
} & SxProp
@@ -305,10 +322,16 @@ const Pane: React.FC> = ({
children,
sx = {}
}) => {
+ // Combine divider and dividerWhenNarrow for backwards compatibility
+ const dividerProp =
+ !isResponsiveValue(divider) && dividerWhenNarrow !== 'inherit'
+ ? {regular: divider, narrow: dividerWhenNarrow}
+ : divider
+
+ const dividerVariant = useResponsiveValue(dividerProp, 'none')
const isHidden = useResponsiveValue(hidden, false)
const {rowGap, columnGap} = React.useContext(PageLayoutContext)
const computedPositionWhenNarrow = positionWhenNarrow === 'inherit' ? position : positionWhenNarrow
- const computedDividerWhenNarrow = dividerWhenNarrow === 'inherit' ? divider : dividerWhenNarrow
return (
> = ({
>
{/* Show a horizontal divider when viewport is narrow. Otherwise, show a vertical divider. */}
{children}
@@ -357,7 +382,21 @@ Pane.displayName = 'PageLayout.Pane'
// PageLayout.Footer
export type PageLayoutFooterProps = {
- divider?: 'none' | 'line'
+ divider?: 'none' | 'line' | ResponsiveValue<'none' | 'line', 'none' | 'line' | 'filled'>
+ /**
+ * @deprecated Use the `divider` prop with a responsive value instead.
+ *
+ * Before:
+ * ```
+ * divider="line"
+ * dividerWhenNarrow="filled"
+ * ```
+ *
+ * After:
+ * ```
+ * divider={{regular: 'line', narrow: 'filled'}}
+ * ```
+ */
dividerWhenNarrow?: 'inherit' | 'none' | 'line' | 'filled'
hidden?: boolean | ResponsiveValue
} & SxProp
@@ -369,6 +408,13 @@ const Footer: React.FC> = ({
children,
sx = {}
}) => {
+ // Combine divider and dividerWhenNarrow for backwards compatibility
+ const dividerProp =
+ !isResponsiveValue(divider) && dividerWhenNarrow !== 'inherit'
+ ? {regular: divider, narrow: dividerWhenNarrow}
+ : divider
+
+ const dividerVariant = useResponsiveValue(dividerProp, 'none')
const isHidden = useResponsiveValue(hidden, false)
const {rowGap} = React.useContext(PageLayoutContext)
return (
@@ -384,11 +430,7 @@ const Footer: React.FC> = ({
sx
)}
>
-
+
{children}
)
diff --git a/src/PageLayout/__snapshots__/PageLayout.test.tsx.snap b/src/PageLayout/__snapshots__/PageLayout.test.tsx.snap
index cfc3a6d898e..24f8bfb8370 100644
--- a/src/PageLayout/__snapshots__/PageLayout.test.tsx.snap
+++ b/src/PageLayout/__snapshots__/PageLayout.test.tsx.snap
@@ -115,7 +115,6 @@ exports[`PageLayout renders condensed layout 1`] = `
.c3 {
margin-left: 0 !important;
margin-right: 0 !important;
- display: none;
}
}
@@ -138,13 +137,6 @@ exports[`PageLayout renders condensed layout 1`] = `
.c7 {
margin-left: 0 !important;
margin-right: 0 !important;
- display: none;
- }
-}
-
-@media screen and (min-width:768px) {
- .c8 {
- display: none;
}
}
@@ -315,7 +307,6 @@ exports[`PageLayout renders default layout 1`] = `
.c3 {
margin-left: 0 !important;
margin-right: 0 !important;
- display: none;
}
}
@@ -352,7 +343,6 @@ exports[`PageLayout renders default layout 1`] = `
.c7 {
margin-left: 0 !important;
margin-right: 0 !important;
- display: none;
}
}
@@ -364,12 +354,6 @@ exports[`PageLayout renders default layout 1`] = `
}
}
-@media screen and (min-width:768px) {
- .c8 {
- display: none;
- }
-}
-
@media screen and (min-width:1012px) {
.c8 {
margin-right: 24px;
@@ -561,7 +545,6 @@ exports[`PageLayout renders pane in different position when narrow 1`] = `
.c3 {
margin-left: 0 !important;
margin-right: 0 !important;
- display: none;
}
}
@@ -577,7 +560,6 @@ exports[`PageLayout renders pane in different position when narrow 1`] = `
.c10 {
margin-left: 0 !important;
margin-right: 0 !important;
- display: none;
}
}
@@ -589,12 +571,6 @@ exports[`PageLayout renders pane in different position when narrow 1`] = `
}
}
-@media screen and (min-width:768px) {
- .c7 {
- display: none;
- }
-}
-
@media screen and (min-width:1012px) {
.c7 {
margin-right: 24px;
@@ -718,6 +694,13 @@ exports[`PageLayout renders with dividers 1`] = `
margin-bottom: 16px;
}
+.c3 {
+ margin-left: -16px;
+ margin-right: -16px;
+ display: none;
+ margin-top: 16px;
+}
+
.c4 {
-webkit-order: 2;
-ms-flex-order: 2;
@@ -742,11 +725,18 @@ exports[`PageLayout renders with dividers 1`] = `
margin-right: auto;
}
-.c9 {
+.c10 {
+ margin-left: -16px;
+ margin-right: -16px;
+ display: none;
+ margin-bottom: 16px;
+}
+
+.c8 {
width: 100%;
}
-.c10 {
+.c9 {
-webkit-order: 4;
-ms-flex-order: 4;
order: 4;
@@ -754,16 +744,6 @@ exports[`PageLayout renders with dividers 1`] = `
margin-top: 16px;
}
-.c3 {
- margin-left: -16px;
- margin-right: -16px;
- display: block;
- height: 8px;
- background-color: #f6f8fa;
- box-shadow: inset 0 -1px 0 0 #d0d7de,inset 0 1px 0 0 #d0d7de;
- margin-top: 16px;
-}
-
.c6 {
-webkit-order: 1;
-ms-flex-order: 1;
@@ -782,30 +762,11 @@ exports[`PageLayout renders with dividers 1`] = `
}
.c7 {
- margin-left: -16px;
- margin-right: -16px;
- display: block;
- height: 8px;
- background-color: #f6f8fa;
- box-shadow: inset 0 -1px 0 0 #d0d7de,inset 0 1px 0 0 #d0d7de;
- margin-top: 16px;
-}
-
-.c8 {
height: 100%;
display: none;
margin-left: 16px;
}
-.c11 {
- margin-left: -16px;
- margin-right: -16px;
- display: block;
- height: 1px;
- background-color: #d0d7de;
- margin-bottom: 16px;
-}
-
@media screen and (min-width:1012px) {
.c0 {
padding: 24px;
@@ -819,37 +780,49 @@ exports[`PageLayout renders with dividers 1`] = `
}
@media screen and (min-width:768px) {
- .c9 {
- width: 256px;
- }
-}
-
-@media screen and (min-width:1012px) {
- .c9 {
- width: 296px;
+ .c3 {
+ margin-left: 0 !important;
+ margin-right: 0 !important;
}
}
@media screen and (min-width:1012px) {
- .c10 {
+ .c3 {
+ margin-left: -24px;
+ margin-right: -24px;
margin-top: 24px;
}
}
@media screen and (min-width:768px) {
- .c3 {
+ .c10 {
margin-left: 0 !important;
margin-right: 0 !important;
- display: block;
- height: 1px;
- background-color: #d0d7de;
}
}
@media screen and (min-width:1012px) {
- .c3 {
+ .c10 {
margin-left: -24px;
margin-right: -24px;
+ margin-bottom: 24px;
+ }
+}
+
+@media screen and (min-width:768px) {
+ .c8 {
+ width: 256px;
+ }
+}
+
+@media screen and (min-width:1012px) {
+ .c8 {
+ width: 296px;
+ }
+}
+
+@media screen and (min-width:1012px) {
+ .c9 {
margin-top: 24px;
}
}
@@ -875,52 +848,12 @@ exports[`PageLayout renders with dividers 1`] = `
}
}
-@media screen and (min-width:768px) {
- .c7 {
- margin-left: 0 !important;
- margin-right: 0 !important;
- display: none;
- }
-}
-
@media screen and (min-width:1012px) {
.c7 {
- margin-left: -24px;
- margin-right: -24px;
- margin-top: 24px;
- }
-}
-
-@media screen and (min-width:768px) {
- .c8 {
- display: block;
- width: 1px;
- background-color: #d0d7de;
- }
-}
-
-@media screen and (min-width:1012px) {
- .c8 {
margin-left: 24px;
}
}
-@media screen and (min-width:768px) {
- .c11 {
- margin-left: 0 !important;
- margin-right: 0 !important;
- display: none;
- }
-}
-
-@media screen and (min-width:1012px) {
- .c11 {
- margin-left: -24px;
- margin-right: -24px;
- margin-bottom: 24px;
- }
-}
-