Refactor and improve layout resizing

This commit is contained in:
Gregory Schier
2023-03-25 21:16:10 -07:00
parent 391a436ed3
commit ae4a43f406
14 changed files with 294 additions and 289 deletions

View File

@@ -1,4 +1,5 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import { useCallback } from 'react';
import { buildKeyValueKey, getKeyValue, setKeyValue } from '../lib/keyValueStore';
const DEFAULT_NAMESPACE = 'app';
@@ -13,7 +14,8 @@ export function keyValueQueryKey({
return ['key_value', { namespace, key: buildKeyValueKey(key) }];
}
export function useKeyValue<T extends string | number | boolean>({
// eslint-disable-next-line @typescript-eslint/ban-types
export function useKeyValue<T extends Object>({
namespace = DEFAULT_NAMESPACE,
key,
defaultValue,
@@ -31,9 +33,23 @@ export function useKeyValue<T extends string | number | boolean>({
mutationFn: (value) => setKeyValue<T>({ namespace, key, value }),
});
const set = useCallback(
(value: ((v: T) => T) | T) => {
if (typeof value === 'function') {
mutate.mutate(value(query.data ?? defaultValue));
} else {
mutate.mutate(value);
}
},
[query.data, defaultValue],
);
const reset = useCallback(() => mutate.mutate(defaultValue), [defaultValue]);
return {
value: query.data,
isLoading: query.isLoading,
set: (value: T) => mutate.mutate(value),
set,
reset,
};
}

View File

@@ -1,27 +1,37 @@
import { useCallback } from 'react';
import { clamp } from '../lib/clamp';
import { useCallback, useMemo } from 'react';
import { useKeyValue } from './useKeyValue';
const START_WIDTH = 200;
const MIN_WIDTH = 110;
const MAX_WIDTH = 500;
const MIN_WIDTH = 150;
const COLLAPSE_WIDTH = MIN_WIDTH * 0.25;
export enum SidebarDisplayKeys {
width = 'sidebar_width',
hidden = 'sidebar_hidden',
export const sidebarDisplayKey = 'sidebar_display';
export const sidebarDisplayDefaultValue: SidebarDisplay = { hidden: false, width: START_WIDTH };
export interface SidebarDisplay {
hidden: boolean;
width: number;
}
export function useSidebarDisplay() {
const hiddenKv = useKeyValue<boolean>({ key: SidebarDisplayKeys.hidden, defaultValue: false });
const widthKv = useKeyValue<number>({ key: SidebarDisplayKeys.width, defaultValue: START_WIDTH });
const hidden = hiddenKv.value;
const width = widthKv.value ?? START_WIDTH;
const display = useKeyValue<SidebarDisplay>({
key: sidebarDisplayKey,
defaultValue: sidebarDisplayDefaultValue,
});
const hidden = display.value?.hidden ?? false;
const width = display.value?.width ?? START_WIDTH;
const set = useCallback((v: number) => widthKv.set(clamp(v, MIN_WIDTH, MAX_WIDTH)), []);
const reset = useCallback(() => widthKv.set(START_WIDTH), []);
const hide = useCallback(() => hiddenKv.set(true), []);
const show = useCallback(() => hiddenKv.set(false), []);
const toggle = useCallback(() => hiddenKv.set(!hiddenKv.value), [hiddenKv.value]);
const set = useCallback(
(width: number) => {
const hidden = width < COLLAPSE_WIDTH;
display.set({ hidden, width: Math.max(MIN_WIDTH, width) });
},
[display.set],
);
const hide = useCallback(() => display.set((v) => ({ ...v, hidden: true })), [display.set]);
const show = useCallback(() => display.set((v) => ({ ...v, hidden: false })), [display.set]);
const toggle = useMemo(() => (hidden ? show : hide), [hidden, show, hide]);
const reset = display.reset;
return { width, hidden, set, reset, hide, show, toggle };
}