Implement new separator design (#33599)

* Remove `onFocus` and `onBlur` handlers

react-resizable-panels fixed the issue where focus-visible was not
working as expected, so we no longer need this bit of code.

* Implement new hover/focus separator

* Collapse the panel when clicking on the new focus separator

* Remove `isFocusedViaKeyboard` from snapshot

* Update tests and storybook

* Expand panel only on double click

* Add animation

* Fix tests

* Don't render border when type is bar

* Single click to expand, double click to collapse

* Change focus separator color
This commit is contained in:
R Midhun Suresh
2026-06-03 12:29:49 +00:00
committed by GitHub
parent 47f76c7d7a
commit 2c8fafdec4
14 changed files with 325 additions and 90 deletions
@@ -15,7 +15,6 @@ import {
type ResizerViewSnapshot,
} from "@element-hq/web-shared-components";
import { debounce } from "lodash";
import whatInput from "what-input";
import SettingsStore from "../../settings/SettingsStore";
import { SettingLevel } from "../../settings/SettingLevel";
@@ -25,13 +24,11 @@ function getInitialState(): ResizerViewSnapshot {
return {
isCollapsed: true,
initialSize: 0,
isFocusedViaKeyboard: false,
};
}
return {
isCollapsed: false,
initialSize: SettingsStore.getValue("RoomList.panelSize") ?? undefined,
isFocusedViaKeyboard: false,
};
}
@@ -87,12 +84,18 @@ export class ResizerViewModel
};
private onSeparatorClick = (): void => {
// When panel is collapsed, single click should expand the panel.
if (this.panelHandle?.isCollapsed()) {
const lastSize = SettingsStore.getValue("RoomList.panelSize");
this.panelHandle.resize(`${lastSize ?? 100}%`);
}
};
public onDoubleClick = (): void => {
// When the panel is expanded, double click should collapse.
if (!this.panelHandle?.isCollapsed()) this.panelHandle?.collapse();
};
public onPointerUp = (): void => {
this.mouseClickHandler.onPointerUp();
};
@@ -104,28 +107,6 @@ export class ResizerViewModel
public onPointerDown = (): void => {
this.mouseClickHandler.onPointerDown();
};
public onFocus = (): void => {
/**
* The intention here is to make the separator visible when it is focused by keyboard
* navigation i.e tabbing through the app.
*
* There's a good reason to take this approach instead of just relying on the focus-visible
* selector:
* When exactly an element gets focus-visible is determined by browser heuristics and usually
* interacting with the mouse will not give an element focus-visible.
* However with this separator on chrome, mouse interaction occasionally gives it focus-visible.
* The leads to flakey separator behaviour.
*/
const currentNavigation = whatInput.ask();
if (currentNavigation === "keyboard") {
this.snapshot.merge({ isFocusedViaKeyboard: true });
}
};
public onBlur = (): void => {
this.snapshot.merge({ isFocusedViaKeyboard: false });
};
}
/**