think/packages/client/src/hooks/use-dragable-width.tsx

80 lines
1.9 KiB
TypeScript
Raw Normal View History

2022-05-16 09:23:59 +00:00
import { clamp } from 'helpers/clamp';
import { getStorage, setStorage } from 'helpers/storage';
2022-05-26 03:04:10 +00:00
import { useCallback, useMemo, useRef } from 'react';
2022-05-24 09:33:30 +00:00
import { useQuery } from 'react-query';
2022-02-20 11:51:55 +00:00
2022-05-26 03:04:10 +00:00
import { IsOnMobile } from './use-on-mobile';
2022-03-12 02:31:03 +00:00
const key = 'dragable-menu-width';
2022-02-20 11:51:55 +00:00
2022-05-04 04:07:09 +00:00
const DEFAULT_PC_MIN_WIDTH = 240;
const DEFAULT_PC_MAX_WIDTH = 600;
const DEFAULT_MOBILE_MIN_WIDTH = 24;
const DEFAULT_MOBILE_MAX_WIDTH = 240;
// 收起宽度24
2022-02-20 11:51:55 +00:00
const COLLAPSED_WIDTH = 24;
export const useDragableWidth = () => {
2022-05-26 03:04:10 +00:00
const { isMobile } = IsOnMobile.useHook();
const [minWidth, maxWidth] = useMemo(
() =>
isMobile ? [DEFAULT_MOBILE_MIN_WIDTH, DEFAULT_MOBILE_MAX_WIDTH] : [DEFAULT_PC_MIN_WIDTH, DEFAULT_PC_MAX_WIDTH],
[isMobile]
);
2022-05-24 09:33:30 +00:00
const { data: currentWidth, refetch } = useQuery<number>(key, () => {
2022-05-04 04:07:09 +00:00
const nextWidth = getStorage(key, minWidth);
2022-02-20 11:51:55 +00:00
2022-05-04 04:07:09 +00:00
if (nextWidth <= COLLAPSED_WIDTH) {
return COLLAPSED_WIDTH;
}
2022-02-20 11:51:55 +00:00
2022-05-04 04:07:09 +00:00
return clamp(nextWidth, minWidth, maxWidth);
});
const prevWidthRef = useRef<number>(maxWidth);
const updateWidth = useCallback(
(size) => {
if (isMobile && size < maxWidth) {
size = minWidth;
}
setStorage(key, size);
prevWidthRef.current = size;
2022-05-24 09:33:30 +00:00
refetch();
2022-05-01 14:07:22 +00:00
},
2022-05-26 03:04:10 +00:00
[isMobile, minWidth, maxWidth, refetch]
2022-05-01 14:07:22 +00:00
);
2022-02-20 11:51:55 +00:00
2022-05-04 04:07:09 +00:00
const toggleCollapsed = useCallback(() => {
const isCollapsed = currentWidth <= COLLAPSED_WIDTH;
2022-02-20 11:51:55 +00:00
2022-05-04 04:07:09 +00:00
if (!isCollapsed) {
prevWidthRef.current = currentWidth;
setStorage(key, COLLAPSED_WIDTH);
} else {
let nextWidth = prevWidthRef.current;
2022-02-20 11:51:55 +00:00
2022-05-04 04:07:09 +00:00
if (nextWidth >= maxWidth) {
nextWidth = maxWidth;
}
if (nextWidth <= minWidth) {
nextWidth = minWidth;
}
setStorage(key, nextWidth);
}
2022-05-24 09:33:30 +00:00
refetch();
}, [refetch, currentWidth, minWidth, maxWidth]);
2022-05-04 04:07:09 +00:00
2022-02-20 11:51:55 +00:00
return {
2022-05-04 04:07:09 +00:00
minWidth,
maxWidth,
width: currentWidth,
isCollapsed: currentWidth <= COLLAPSED_WIDTH,
2022-02-20 11:51:55 +00:00
toggleCollapsed,
updateWidth,
};
};