forked from mirrors/thatmattlove-hyperglass
64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
import { useMemo, useCallback } from 'react';
|
|
import { getColor, isLight } from '@chakra-ui/theme-tools';
|
|
import { useTheme } from '~/context';
|
|
|
|
import type { TOpposingOptions } from './types';
|
|
|
|
export type UseIsDarkCallbackReturn = (color: string) => boolean;
|
|
|
|
/**
|
|
* Parse the color string to determine if it's a Chakra UI theme key, and determine if the
|
|
* opposing color should be black or white.
|
|
*/
|
|
export function useIsDark(color: string): boolean {
|
|
const isDarkFn = useIsDarkCallback();
|
|
return useMemo((): boolean => isDarkFn(color), [color, isDarkFn]);
|
|
}
|
|
|
|
export function useIsDarkCallback(): UseIsDarkCallbackReturn {
|
|
const theme = useTheme();
|
|
return useCallback(
|
|
(color: string): boolean => {
|
|
if (typeof color === 'string' && color.match(/[a-zA-Z]+\.[a-zA-Z0-9]+/g)) {
|
|
color = getColor(theme, color, color);
|
|
}
|
|
let opposingShouldBeDark = true;
|
|
try {
|
|
opposingShouldBeDark = isLight(color)(theme);
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
return opposingShouldBeDark;
|
|
},
|
|
[theme],
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Determine if the foreground color for `color` should be white or black.
|
|
*/
|
|
export function useOpposingColor(color: string, options?: TOpposingOptions): string {
|
|
const isBlack = useIsDark(color);
|
|
|
|
return useMemo(() => {
|
|
if (isBlack) {
|
|
return options?.dark ?? 'black';
|
|
} else {
|
|
return options?.light ?? 'white';
|
|
}
|
|
}, [isBlack, options?.dark, options?.light]);
|
|
}
|
|
|
|
export function useOpposingColorCallback(options?: TOpposingOptions): (color: string) => string {
|
|
const isDark = useIsDarkCallback();
|
|
return useCallback(
|
|
(color: string) => {
|
|
const isBlack = isDark(color);
|
|
if (isBlack) {
|
|
return options?.dark ?? 'black';
|
|
}
|
|
return options?.light ?? 'white';
|
|
},
|
|
[isDark, options?.dark, options?.light],
|
|
);
|
|
}
|