feat(desktop): let thread pane expand on ultrawide monitors (#1407)

Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
This commit is contained in:
Tyler
2026-06-30 18:55:08 -04:00
committed by GitHub
co-authored by npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d Tyler Longwell
parent 5784ff0f1a
commit f86f97bbde
6 changed files with 201 additions and 6 deletions
@@ -2,17 +2,25 @@ import * as React from "react";
import {
AUXILIARY_PANEL_DEFAULT_WIDTH_PX,
AUXILIARY_PANEL_MAX_WIDTH_PX,
AUXILIARY_PANEL_MIN_WIDTH_PX,
clampAuxiliaryPanelWidth,
} from "@/shared/layout/AuxiliaryPanel";
const THREAD_PANEL_WIDTH_SESSION_KEY = "buzz.desktop.thread-panel-width";
function getViewportWidth(): number {
return typeof window === "undefined" ? 0 : window.innerWidth;
}
/**
* Clamp the stored panel width for the current viewport.
*
* The upper bound grows with the viewport (see {@link clampAuxiliaryPanelWidth}) so
* the pane can expand on ultrawide displays. `AuxiliaryPanelShell` additionally
* clamps the rendered width to `calc(100% - MIN)` at paint time, so a stored width
* larger than the current viewport never collapses the main pane.
*/
function clampThreadPanelWidth(width: number): number {
return Math.max(
AUXILIARY_PANEL_MIN_WIDTH_PX,
Math.min(AUXILIARY_PANEL_MAX_WIDTH_PX, width),
);
return clampAuxiliaryPanelWidth(width, getViewportWidth());
}
function getInitialThreadPanelWidth(): number {
@@ -25,4 +25,6 @@ export {
AUXILIARY_PANEL_MAX_WIDTH_PX,
AUXILIARY_PANEL_MIN_WIDTH_PX,
AUXILIARY_PANEL_SINGLE_COLUMN_BREAKPOINT_PX,
clampAuxiliaryPanelWidth,
getAuxiliaryPanelMaxWidth,
} from "@/shared/layout/auxiliaryPanelLayout";
@@ -0,0 +1,37 @@
import assert from "node:assert/strict";
import test from "node:test";
import {
AUXILIARY_PANEL_MAX_WIDTH_PX,
AUXILIARY_PANEL_MIN_WIDTH_PX,
clampAuxiliaryPanelWidth,
getAuxiliaryPanelMaxWidth,
} from "./auxiliaryPanelLayout.ts";
test("max width falls back to the static cap on narrow viewports", () => {
// On viewports where `viewportWidth - MIN` is below the static cap, the floor wins.
assert.equal(getAuxiliaryPanelMaxWidth(900), AUXILIARY_PANEL_MAX_WIDTH_PX);
assert.equal(getAuxiliaryPanelMaxWidth(0), AUXILIARY_PANEL_MAX_WIDTH_PX);
});
test("max width grows with the viewport, reserving the main pane", () => {
assert.equal(
getAuxiliaryPanelMaxWidth(3440),
3440 - AUXILIARY_PANEL_MIN_WIDTH_PX,
);
});
test("clamp keeps width within [min, viewport-aware max]", () => {
// Below the floor clamps up to the min.
assert.equal(
clampAuxiliaryPanelWidth(100, 3440),
AUXILIARY_PANEL_MIN_WIDTH_PX,
);
// A wide drag is allowed on an ultrawide viewport.
assert.equal(clampAuxiliaryPanelWidth(2000, 3440), 2000);
// The same wide value is clamped down on a small viewport.
assert.equal(
clampAuxiliaryPanelWidth(2000, 900),
AUXILIARY_PANEL_MAX_WIDTH_PX,
);
});
@@ -3,3 +3,29 @@ export const AUXILIARY_PANEL_MIN_WIDTH_PX = 300;
export const AUXILIARY_PANEL_SINGLE_COLUMN_BREAKPOINT_PX =
AUXILIARY_PANEL_MIN_WIDTH_PX * 2;
export const AUXILIARY_PANEL_MAX_WIDTH_PX = 720;
/**
* Upper bound for the auxiliary panel width clamp, given the current viewport width.
*
* On ultrawide displays the static {@link AUXILIARY_PANEL_MAX_WIDTH_PX} is too small,
* so the panel is allowed to grow with the viewport while always reserving at least
* {@link AUXILIARY_PANEL_MIN_WIDTH_PX} for the main pane. The static cap acts as a
* floor, so narrow viewports keep their existing behavior.
*/
export function getAuxiliaryPanelMaxWidth(viewportWidth: number): number {
return Math.max(
AUXILIARY_PANEL_MAX_WIDTH_PX,
viewportWidth - AUXILIARY_PANEL_MIN_WIDTH_PX,
);
}
/** Clamp a stored panel width into the allowed range for the current viewport. */
export function clampAuxiliaryPanelWidth(
width: number,
viewportWidth: number,
): number {
return Math.max(
AUXILIARY_PANEL_MIN_WIDTH_PX,
Math.min(getAuxiliaryPanelMaxWidth(viewportWidth), width),
);
}