Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions packages/react/src/PageLayout/PageLayout.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export const ResizablePaneWithoutPersistence: StoryFn = () => (
<PageLayout.Header>
<Placeholder height={64} label="Header" />
</PageLayout.Header>
<PageLayout.Pane resizable={{persist: false}} aria-label="Side pane">
<PageLayout.Pane resizable aria-label="Side pane">
<Placeholder height={320} label="Pane (resizable, not persisted)" />
</PageLayout.Pane>
<PageLayout.Content>
Expand Down Expand Up @@ -400,20 +400,22 @@ export const ResizablePaneWithCustomPersistence: StoryFn = () => {
useIsomorphicLayoutEffect(() => {
setCurrentWidth(getInitialWidth())
}, [])

const handleWidthChange = (width: number) => {
setCurrentWidth(width)
localStorage.setItem(key, width.toString())
}

return (
<PageLayout>
<PageLayout.Header>
<Placeholder height={64} label="Header" />
</PageLayout.Header>
<PageLayout.Pane
width={{min: '256px', default: `${defaultPaneWidth.medium}px`, max: '600px'}}
resizable={{
width: currentWidth,
persist: width => {
setCurrentWidth(width)
localStorage.setItem(key, width.toString())
},
}}
resizable
currentWidth={currentWidth}
onWidthChange={handleWidthChange}
aria-label="Side pane"
>
<Placeholder height={320} label={`Pane (width: ${currentWidth}px)`} />
Expand Down Expand Up @@ -448,20 +450,21 @@ export const ResizablePaneWithNumberWidth: StoryFn = () => {

const [currentWidth, setCurrentWidth] = React.useState<number>(getInitialWidth)

const handleWidthChange = (newWidth: number) => {
setCurrentWidth(newWidth)
localStorage.setItem(key, newWidth.toString())
}

return (
<PageLayout>
<PageLayout.Header>
<Placeholder height={64} label="Header" />
</PageLayout.Header>
<PageLayout.Pane
width="medium"
resizable={{
width: currentWidth,
persist: newWidth => {
setCurrentWidth(newWidth)
localStorage.setItem(key, newWidth.toString())
},
}}
resizable
currentWidth={currentWidth}
onWidthChange={handleWidthChange}
aria-label="Side pane"
>
<Placeholder height={320} label={`Pane (width: ${currentWidth}px)`} />
Expand Down Expand Up @@ -496,20 +499,21 @@ export const ResizablePaneWithControlledWidth: StoryFn = () => {

const [currentWidth, setCurrentWidth] = React.useState<number>(getInitialWidth)

const handleWidthChange = (newWidth: number) => {
setCurrentWidth(newWidth)
localStorage.setItem(key, newWidth.toString())
}

return (
<PageLayout>
<PageLayout.Header>
<Placeholder height={64} label="Header" />
</PageLayout.Header>
<PageLayout.Pane
width={{min: '256px', default: '296px', max: '600px'}}
resizable={{
width: currentWidth,
persist: newWidth => {
setCurrentWidth(newWidth)
localStorage.setItem(key, newWidth.toString())
},
}}
resizable
currentWidth={currentWidth}
onWidthChange={handleWidthChange}
aria-label="Side pane"
>
<Placeholder height={320} label={`Pane (current: ${currentWidth}px)`} />
Expand Down
29 changes: 21 additions & 8 deletions packages/react/src/PageLayout/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -600,20 +600,29 @@ export type PageLayoutPaneProps = {
* - Named sizes: `'small'` | `'medium'` | `'large'`
* - Custom object: `{min: string, default: string, max: string}`
*
* For controlled width (current value), use `resizable.width` instead.
* For controlled width (current value), use `currentWidth` prop instead.
*/
width?: PaneWidthValue
minWidth?: number
/**
* Current/controlled width value in pixels.
* When provided, this overrides the default width from the `width` prop.
* Use with `onWidthChange` for controlled width behavior.
*/
currentWidth?: number
/**
* Callback fired when the pane width changes (during resize).
* Only called when `resizable` is enabled.
* When provided, this callback is used instead of any persistence mechanism.
* Use with `currentWidth` for controlled width behavior.
*/
onWidthChange?: (width: number) => void
/**
* Enable resizable pane behavior.
* - `true`: Enable with default localStorage persistence
* - `false`: Disable resizing
* - `{width?: number, persist: false}`: Enable without persistence, optionally with controlled current width
* - `{width?: number, persist: 'localStorage'}`: Enable with localStorage, optionally with controlled current width
* - `{width?: number, persist: fn}`: Enable with custom persistence, optionally with controlled current width
* - `true`: Enable resizing with localStorage persistence (only if onWidthChange is not provided)
* - `false` or `undefined`: Disable resizing
*
* The `width` property in the config represents the current/controlled width value.
* When provided, it takes precedence over the default width from the `width` prop.
* Note: When `onWidthChange` is provided, it takes precedence over localStorage persistence.
*/
resizable?: ResizableConfig
widthStorageKey?: string
Expand Down Expand Up @@ -659,6 +668,8 @@ const Pane = React.forwardRef<HTMLDivElement, React.PropsWithChildren<PageLayout
positionWhenNarrow = 'inherit',
width = 'medium',
minWidth = 256,
currentWidth: controlledWidth,
onWidthChange,
padding = 'none',
resizable = false,
widthStorageKey = 'paneWidth',
Expand Down Expand Up @@ -712,6 +723,8 @@ const Pane = React.forwardRef<HTMLDivElement, React.PropsWithChildren<PageLayout
paneRef,
handleRef,
contentWrapperRef,
onWidthChange,
currentWidth: controlledWidth,
})

useRefObjectAsForwardedRef(forwardRef, paneRef)
Expand Down
9 changes: 1 addition & 8 deletions packages/react/src/PageLayout/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
export * from './PageLayout'
export type {
PersistConfig,
PersistFunction,
SaveOptions,
ResizableConfig,
PaneWidth,
PaneWidthValue,
} from './usePaneWidth'
export type {ResizableConfig, PaneWidth, PaneWidthValue} from './usePaneWidth'
export {defaultPaneWidth} from './usePaneWidth'
Loading