Files
frontend/src/hooks/responsive/useResponsiveStyle.ts

54 lines
1.7 KiB
TypeScript
Raw Normal View History

/**
* Hook
*/
import { useMemo } from 'react';
import { useBreakpoint } from './useBreakpoint';
import { ResponsiveValue, FineBreakpointKey, REVERSE_BREAKPOINT_ORDER } from './constants';
/**
*
*
* @param styles -
* @returns
*
* @example
* const containerStyle = useResponsiveStyle({
* padding: { xs: 8, md: 16, lg: 24 },
* fontSize: { xs: 14, lg: 16 }
* });
*/
export function useResponsiveStyle<T extends Record<string, ResponsiveValue<unknown>>>(
styles: T
): { [K in keyof T]: T[K] extends ResponsiveValue<infer V> ? V : never } {
const { fineBreakpoint } = useBreakpoint();
return useMemo(() => {
const result = {} as { [K in keyof T]: T[K] extends ResponsiveValue<infer V> ? V : never };
for (const key in styles) {
const value = styles[key];
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
(result as Record<string, unknown>)[key] = value;
} else {
const valueMap = value as Partial<Record<FineBreakpointKey, unknown>>;
const currentIndex = REVERSE_BREAKPOINT_ORDER.indexOf(fineBreakpoint);
let selectedValue: unknown = undefined;
for (let i = currentIndex; i < REVERSE_BREAKPOINT_ORDER.length; i++) {
const bp = REVERSE_BREAKPOINT_ORDER[i];
if (bp in valueMap) {
selectedValue = valueMap[bp];
break;
}
}
(result as Record<string, unknown>)[key] = selectedValue ?? valueMap.xs ?? Object.values(valueMap)[0];
}
}
return result;
}, [styles, fineBreakpoint]);
}