fix: responsive fix

This commit is contained in:
2024-02-22 19:49:13 +00:00
parent efe51a9b5e
commit b232410d83
13 changed files with 209 additions and 129 deletions
+57
View File
@@ -0,0 +1,57 @@
import { useCallback, useEffect, useRef, useState } from "react";
export const breakpoints = {
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
"2xl": 1536,
};
export type Breakpoint = keyof typeof breakpoints;
export const breakpointKeys = Object.keys(breakpoints);
export const breakpointValues = Object.values(breakpoints);
export const useBreakpoint = (onChange?: (breakpoint: number) => void) => {
const prevRef = useRef<number>(0);
const [curBreakpoint, setBreakpoint] = useState<number>(
getScreenBreakpoint()
);
const onResize = useCallback(() => {
const breakpointIdx = getScreenBreakpoint();
if (breakpointIdx >= 0 && prevRef.current !== breakpointIdx) {
if (onChange) {
onChange(breakpointIdx);
} else {
setBreakpoint(breakpointIdx);
}
prevRef.current = breakpointIdx;
}
}, [onChange]);
useEffect(() => {
window.addEventListener("resize", onResize);
onResize();
return () => {
window.removeEventListener("resize", onResize);
};
}, [onResize]);
const breakpoint = breakpointKeys[curBreakpoint];
return [curBreakpoint, breakpoint] as [number, Breakpoint];
};
export function getScreenBreakpoint() {
const width = typeof window !== "undefined" ? window.innerWidth : 0;
let breakpointIdx = breakpointValues.findIndex((i) => width <= i);
if (breakpointIdx < 0) {
breakpointIdx = breakpointKeys.length - 1;
}
return breakpointIdx;
}
+55
View File
@@ -0,0 +1,55 @@
import { useState } from "react";
import {
Breakpoint,
breakpointKeys,
getScreenBreakpoint,
useBreakpoint,
} from "./useBreakpoint";
export type BreakpointValues<T> = Partial<Record<Breakpoint, T | null>>;
export const useBreakpointValue = <T>(values: T | BreakpointValues<T>) => {
const [value, setValue] = useState(
typeof values === "object"
? getValueByBreakpoint(
values as BreakpointValues<T>,
getScreenBreakpoint()
)
: values
);
useBreakpoint((breakpoint) => {
if (typeof values !== "object") {
return;
}
const newValue = getValueByBreakpoint(
values as BreakpointValues<T>,
breakpoint
);
if (newValue !== value) {
setValue(newValue);
}
});
return value as T;
};
export function getValueByBreakpoint<T>(
values: BreakpointValues<T>,
breakpoint: number
) {
const valueEntries = Object.entries(values as never);
let resIdx = valueEntries.findIndex(([key]) => {
const bpIdx = breakpointKeys.indexOf(key);
return breakpoint <= bpIdx;
});
if (resIdx < 0) {
resIdx = valueEntries.length - 1;
}
const value = valueEntries[resIdx]?.[1] as T;
return value;
}