mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-11 15:16:35 +02:00
Add a class to track auto collapse state
- An object of this class can be used by all the behaviours to collapse/expand the panel - Can also query whether the panel is already collapsed
This commit is contained in:
parent
26dce9ff47
commit
8a6ef20865
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { PanelImperativeHandle } from "@element-hq/web-shared-components";
|
||||
|
||||
/**
|
||||
* Contains auto-collapsed state and methods to expand/collapse the panel.
|
||||
* This class is used by the different auto-collapse behaviours.
|
||||
*/
|
||||
export class CollapseHandler {
|
||||
/**
|
||||
* @param setCollapsed Callback that will be called when the handler changes the collapsed state.
|
||||
*/
|
||||
public constructor(private readonly setCollapsed: (collapsed: boolean) => void) {}
|
||||
|
||||
/**
|
||||
* This gives access to the panel's imperative methods.
|
||||
*/
|
||||
public panelHandle?: PanelImperativeHandle;
|
||||
|
||||
/**
|
||||
* Whether the left-panel is auto-collapsed.
|
||||
*/
|
||||
public isAutoCollapsed: boolean = false;
|
||||
|
||||
/**
|
||||
* Stores the width to which the left-panel should be restored to when the auto-collapsed
|
||||
* panel is expanded due to the window being resized.
|
||||
*/
|
||||
private restoreWidth?: number;
|
||||
|
||||
/**
|
||||
* Make the panel API from react-resizable-panels available to this class.
|
||||
* @param handle The panel handle to access react-resizable-panels API.
|
||||
*/
|
||||
public setHandle = (handle: PanelImperativeHandle): void => {
|
||||
this.panelHandle = handle;
|
||||
this.restoreWidth = this.panelHandle?.getSize().inPixels;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update {@link CollapseHandler#restoreWidth} with the up to date width of the left panel.
|
||||
*/
|
||||
public updateRestoreWidth = (): void => {
|
||||
// Takes a bit of time for the library to update the pixel values.
|
||||
window.setTimeout(() => {
|
||||
this.restoreWidth = this.panelHandle?.getSize().inPixels;
|
||||
}, 500);
|
||||
};
|
||||
|
||||
/**
|
||||
* Collapse the left panel.
|
||||
*/
|
||||
public collapse = (): void => {
|
||||
this.isAutoCollapsed = true;
|
||||
this.panelHandle?.collapse();
|
||||
this.setCollapsed(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand the left panel.
|
||||
*/
|
||||
public expand = (): void => {
|
||||
this.isAutoCollapsed = false;
|
||||
this.panelHandle?.resize(this.restoreWidth!);
|
||||
this.setCollapsed(false);
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { PanelImperativeHandle } from "@element-hq/web-shared-components";
|
||||
import { CollapseHandler } from "../../../../src/viewmodels/structures/auto-collapse/CollapseHandler";
|
||||
import { MockPanelHandle } from "./mocks";
|
||||
|
||||
function setup() {
|
||||
const setCollapsed = jest.fn();
|
||||
const panelHandle = new MockPanelHandle();
|
||||
const collapseHandler = new CollapseHandler(setCollapsed);
|
||||
collapseHandler.setHandle(panelHandle as unknown as PanelImperativeHandle);
|
||||
return { collapseHandler, panelHandle, setCollapsed };
|
||||
}
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
describe("CollapseHandler", () => {
|
||||
it("should collapse panel on collapse()", () => {
|
||||
const { collapseHandler, panelHandle, setCollapsed } = setup();
|
||||
collapseHandler.collapse();
|
||||
expect(setCollapsed).toHaveBeenCalledWith(true);
|
||||
expect(panelHandle.collapse).toHaveBeenCalledTimes(1);
|
||||
expect(collapseHandler.isAutoCollapsed).toBe(true);
|
||||
});
|
||||
|
||||
it("should expand panel on expand()", () => {
|
||||
const { collapseHandler, panelHandle, setCollapsed } = setup();
|
||||
collapseHandler.expand();
|
||||
expect(setCollapsed).toHaveBeenCalledWith(false);
|
||||
expect(panelHandle.resize).toHaveBeenCalledTimes(1);
|
||||
expect(collapseHandler.isAutoCollapsed).toBe(false);
|
||||
});
|
||||
|
||||
it("should update restoreWidth on updateRestoreWidth()", () => {
|
||||
const { collapseHandler, panelHandle } = setup();
|
||||
collapseHandler.updateRestoreWidth();
|
||||
jest.runAllTimers();
|
||||
expect(panelHandle.getSize).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should update restoreWidth on setHandle", () => {
|
||||
const setCollapsed = jest.fn();
|
||||
const panelHandle = new MockPanelHandle();
|
||||
const collapseHandler = new CollapseHandler(setCollapsed);
|
||||
expect(collapseHandler.panelHandle).toBeUndefined();
|
||||
collapseHandler.setHandle(panelHandle as unknown as PanelImperativeHandle);
|
||||
expect(collapseHandler.panelHandle).toBe(panelHandle);
|
||||
expect(panelHandle.getSize).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user