diff --git a/.changeset/late-wombats-switch.md b/.changeset/late-wombats-switch.md new file mode 100644 index 00000000000..e63657867d2 --- /dev/null +++ b/.changeset/late-wombats-switch.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Add `minWidth prop to `PageLayout.Pane` and `SplitPageLayout.Pane` diff --git a/generated/components.json b/generated/components.json index c4da5320821..9cfa427c3d3 100644 --- a/generated/components.json +++ b/generated/components.json @@ -2723,6 +2723,12 @@ "defaultValue": "'medium'", "description": "The width of the pane." }, + { + "name": "minWidth", + "type": "number", + "defaultValue": "256", + "description": "The minimum width of the pane." + }, { "name": "resizable", "type": "boolean", @@ -3720,6 +3726,12 @@ "defaultValue": "'medium'", "description": "The width of the pane." }, + { + "name": "minWidth", + "type": "number", + "defaultValue": "256", + "description": "The minimum width of the pane." + }, { "name": "resizable", "type": "boolean", diff --git a/src/PageLayout/PageLayout.docs.json b/src/PageLayout/PageLayout.docs.json index 05c6b8c8be7..dfa273638c5 100644 --- a/src/PageLayout/PageLayout.docs.json +++ b/src/PageLayout/PageLayout.docs.json @@ -152,6 +152,12 @@ "defaultValue": "'medium'", "description": "The width of the pane." }, + { + "name": "minWidth", + "type": "number", + "defaultValue": "256", + "description": "The minimum width of the pane." + }, { "name": "resizable", "type": "boolean", diff --git a/src/PageLayout/PageLayout.stories.tsx b/src/PageLayout/PageLayout.stories.tsx index a55c409d213..2ec2aaa0f56 100644 --- a/src/PageLayout/PageLayout.stories.tsx +++ b/src/PageLayout/PageLayout.stories.tsx @@ -238,6 +238,11 @@ const meta: Meta = { control: {type: 'radio'}, table: {category: 'Pane props'}, }, + 'Pane.minWidth': { + type: 'number', + defaultValue: 256, + table: {category: 'Pane props'}, + }, 'Pane.sticky': { type: 'boolean', table: {category: 'Pane props'}, @@ -383,6 +388,7 @@ const Template: Story = args => ( wide: args['Pane.position.wide'], }} width={args['Pane.width']} + minWidth={args['Pane.minWidth']} sticky={args['Pane.sticky']} resizable={args['Pane.resizable']} padding={args['Pane.padding']} diff --git a/src/PageLayout/PageLayout.tsx b/src/PageLayout/PageLayout.tsx index fe50d009a0b..cda091d97fc 100644 --- a/src/PageLayout/PageLayout.tsx +++ b/src/PageLayout/PageLayout.tsx @@ -482,10 +482,11 @@ export type PageLayoutPaneProps = { * position={{regular: 'start', narrow: 'end'}} * ``` */ + positionWhenNarrow?: 'inherit' | keyof typeof panePositions 'aria-labelledby'?: string 'aria-label'?: string - positionWhenNarrow?: 'inherit' | keyof typeof panePositions width?: keyof typeof paneWidths + minWidth?: number resizable?: boolean widthStorageKey?: string padding?: keyof typeof SPACING_MAP @@ -532,6 +533,7 @@ const Pane = React.forwardRef(null) useRefObjectAsForwardedRef(forwardRef, paneRef) - const MIN_PANE_WIDTH = 256 // 256px, related to `--pane-min-width CSS var. const [minPercent, setMinPercent] = React.useState(0) const [maxPercent, setMaxPercent] = React.useState(0) const hasOverflow = useOverflow(paneRef) @@ -618,7 +619,7 @@ const Pane = React.forwardRef maxPaneWidthDiff ? viewportWidth - maxPaneWidthDiff : viewportWidth - const minPercent = Math.round((100 * MIN_PANE_WIDTH) / viewportWidth) + const minPercent = Math.round((100 * minWidth) / viewportWidth) setMinPercent(minPercent) const maxPercent = Math.round((100 * maxPaneWidth) / viewportWidth) @@ -627,7 +628,7 @@ const Pane = React.forwardRef ({ - '--pane-min-width': `256px`, + '--pane-min-width': `${minWidth}px`, '--pane-max-width-diff': '511px', '--pane-max-width': `calc(100vw - var(--pane-max-width-diff))`, width: resizable diff --git a/src/SplitPageLayout/SplitPageLayout.docs.json b/src/SplitPageLayout/SplitPageLayout.docs.json index 696bbd87d77..9fb036a25d3 100644 --- a/src/SplitPageLayout/SplitPageLayout.docs.json +++ b/src/SplitPageLayout/SplitPageLayout.docs.json @@ -80,6 +80,12 @@ "defaultValue": "'medium'", "description": "The width of the pane." }, + { + "name": "minWidth", + "type": "number", + "defaultValue": "256", + "description": "The minimum width of the pane." + }, { "name": "resizable", "type": "boolean", @@ -156,4 +162,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/src/SplitPageLayout/SplitPageLayout.stories.tsx b/src/SplitPageLayout/SplitPageLayout.stories.tsx index 4b83a7305d1..39f09809d15 100644 --- a/src/SplitPageLayout/SplitPageLayout.stories.tsx +++ b/src/SplitPageLayout/SplitPageLayout.stories.tsx @@ -189,6 +189,11 @@ export default { control: {type: 'radio'}, table: {category: 'Pane props'}, }, + 'Pane.minWidth': { + type: 'number', + defaultValue: 256, + table: {category: 'Pane props'}, + }, 'Pane.sticky': { type: 'boolean', defaultValue: true, @@ -342,6 +347,7 @@ const Template: Story = args => ( wide: args['Pane.position.wide'], }} width={args['Pane.width']} + minWidth={args['Pane.minWidth']} sticky={args['Pane.sticky']} padding={args['Pane.padding']} divider={{