(core) Allow left pane to auto-expand on mouse over

Summary:
Tweak PagePanels to let the left pane automatically expand on mouse
over. This is to make pages more accessible when the panel is
collapsed.

In this context, when expanding, the left panel overlap the main
content, reducing visual clutter.

Test Plan: updated

Reviewers: jarek

Reviewed By: jarek

Subscribers: anaisconce, jarek

Differential Revision: https://phab.getgrist.com/D3516
This commit is contained in:
Cyprien P
2022-07-27 21:02:28 +02:00
parent c54dde3dba
commit 80f31bffc2
4 changed files with 189 additions and 23 deletions

View File

@@ -186,7 +186,7 @@ export class FocusLayer extends Disposable implements FocusLayerOptions {
* Because elements getting removed from the DOM don't always trigger 'blur' event, this also
* uses MutationObserver to watch for the element to get removed from DOM.
*/
function watchElementForBlur(elem: Element, callback: () => void) {
export function watchElementForBlur(elem: Element, callback: () => void) {
const maybeDone = () => {
if (document.activeElement !== elem) {
lis.dispose();

View File

@@ -5,6 +5,10 @@
import {safeJsonParse} from 'app/common/gutil';
import {IDisposableOwner, Observable} from 'grainjs';
export interface SessionObs<T> extends Observable<T> {
pauseSaving(yesNo: boolean): void;
}
/**
* Creates and returns an Observable tied to sessionStorage, to make its value stick across
* reloads and navigation, but differ across browser tabs. E.g. whether a side pane is open.
@@ -20,13 +24,19 @@ import {IDisposableOwner, Observable} from 'grainjs';
* import {StringUnion} from 'app/common/StringUnion';
* const SomeTab = StringUnion("foo", "bar", "baz");
* tab = createSessionObs(owner, "tab", "baz", SomeTab.guard); // Type Observable<"foo"|"bar"|"baz">
*
* You can disable saving to sessionStorage:
* panelWidth.pauseSaving(true);
* doStuff();
* panelWidth.pauseSaving(false);
*
*/
export function createSessionObs<T>(
owner: IDisposableOwner|null,
key: string,
_default: T,
isValid: (val: any) => val is T,
) {
): SessionObs<T> {
function fromString(value: string|null): T {
const parsed = value == null ? null : safeJsonParse(value, null);
return isValid(parsed) ? parsed : _default;
@@ -34,9 +44,10 @@ export function createSessionObs<T>(
function toString(value: T): string|null {
return value === _default || !isValid(value) ? null : JSON.stringify(value);
}
let _pauseSaving = false;
const obs = Observable.create<T>(owner, fromString(window.sessionStorage.getItem(key)));
obs.addListener((value: T) => {
if (_pauseSaving) { return; }
const stored = toString(value);
if (stored == null) {
window.sessionStorage.removeItem(key);
@@ -44,7 +55,7 @@ export function createSessionObs<T>(
window.sessionStorage.setItem(key, stored);
}
});
return obs;
return Object.assign(obs, {pauseSaving(yesNo: boolean) { _pauseSaving = yesNo; }});
}
/** Helper functions to check simple types, useful for the `isValid` argument to createSessionObs. */