diff --git a/README.md b/README.md index bef25888..8e1cb42a 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,10 @@ Callback that is fired when the pane sizes change (usually on drag). Recommended Callback that is fired whenever the user double clicks a sash. +### onVisibleChange + +Callback that is fired whenever the user changes the visibility of a pane by snapping. Note that this will only be called if the new value is different from the current `visible` prop on the Pane. + ## Allotment.Pane props ### maxSize diff --git a/src/allotment.tsx b/src/allotment.tsx index ba78274f..01f553cb 100644 --- a/src/allotment.tsx +++ b/src/allotment.tsx @@ -75,6 +75,8 @@ export type AllotmentProps = { onChange?: (sizes: number[]) => void; /** Callback on reset */ onReset?: () => void; + /** Callback on visibility change */ + onVisibleChange?: (index: number, visible: boolean) => void; } & CommonProps; const Allotment = forwardRef( @@ -91,14 +93,13 @@ const Allotment = forwardRef( vertical = false, onChange, onReset, + onVisibleChange, }, ref ) => { const containerRef = useRef(null!); const previousKeys = useRef([]); - const splitViewPropsRef = useRef( - new Map() - ); + const splitViewPropsRef = useRef(new Map()); const splitViewRef = useRef(null); const splitViewViewRef = useRef(new Map()); @@ -176,6 +177,25 @@ const Allotment = forwardRef( onChange ); + splitViewRef.current.on("sashchange", (index: number) => { + if (onVisibleChange && splitViewRef.current) { + const keys = childrenArray.map((child) => child.key as string); + + for (let index = 0; index < keys.length; index++) { + const props = splitViewPropsRef.current.get(keys[index]); + + if (props?.visible !== undefined) { + if (props.visible !== splitViewRef.current.isViewVisible(index)) { + onVisibleChange( + index, + splitViewRef.current.isViewVisible(index) + ); + } + } + } + } + }); + splitViewRef.current.on("sashreset", (_index: number) => { if (onReset) { onReset(); diff --git a/src/split-view/split-view.ts b/src/split-view/split-view.ts index 1078e608..723915ce 100644 --- a/src/split-view/split-view.ts +++ b/src/split-view/split-view.ts @@ -458,7 +458,9 @@ export class SplitView extends EventEmitter implements Disposable { this.onSashChange(sashEventMapper(event)) ); - sash.on("end", this.onSashEnd); + sash.on("end", () => + this.onSashEnd(this.sashItems.findIndex((item) => item.sash === sash)) + ); sash.on("reset", () => { const index = this.sashItems.findIndex((item) => item.sash === sash); @@ -782,7 +784,7 @@ export class SplitView extends EventEmitter implements Disposable { } private onSashEnd = (index: number): void => { - // TODO: this._onDidSashChange.fire(index); + this.emit("sashchange", index); this.saveProportions(); for (const item of this.viewItems) { diff --git a/stories/allotment.stories.tsx b/stories/allotment.stories.tsx index 42046084..8573b44e 100644 --- a/stories/allotment.stories.tsx +++ b/stories/allotment.stories.tsx @@ -305,7 +305,13 @@ export const Visible: Story = (args) => { {visible ? "Hide" : "Show"}
- + { + setVisible(value); + }} + > diff --git a/website/docs/allotment.md b/website/docs/allotment.md index e95dd9c9..f2168639 100644 --- a/website/docs/allotment.md +++ b/website/docs/allotment.md @@ -7,12 +7,13 @@ title: Allotment ## Props -| Name | Type | Default | Description | -| -------------------- | ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `defaultSizes` | `number[]` | | An array of initial sizes of the panes. If the sum of the sizes differs from the size of the container then the panes' sizes will be scaled proportionally. | -| `maxSize` | `number` | | Maximum size of any pane. | -| `minSize` | `number` | | Minimum size of any pane. | -| `proportionalLayout` | `boolean` | `true` | Resize each view proportionally when resizing container | -| `snap` | `boolean` | `false` | Enable snap to zero for all panes. | -| `vertical` | `boolean` | `false` | Direction to split. If true then the panes will be stacked vertically, otherwise they will be stacked horizontally. | -| `onReset` | `func` | | Callback that is fired whenever the user double clicks a sash | +| Name | Type | Default | Description | +| -------------------- | ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `defaultSizes` | `number[]` | | An array of initial sizes of the panes. If the sum of the sizes differs from the size of the container then the panes' sizes will be scaled proportionally. | +| `maxSize` | `number` | | Maximum size of any pane. | +| `minSize` | `number` | | Minimum size of any pane. | +| `proportionalLayout` | `boolean` | `true` | Resize each view proportionally when resizing container | +| `snap` | `boolean` | `false` | Enable snap to zero for all panes. | +| `vertical` | `boolean` | `false` | Direction to split. If true then the panes will be stacked vertically, otherwise they will be stacked horizontally. | +| `onReset` | `func` | | Callback that is fired whenever the user double clicks a sash | +| `onVisibleChange` | `func` | | Callback that is fired whenever the user changes the visibility of a pane by snapping. Note that this will only be called if the new value is different from the current `visible` prop on the Pane. |