import { useMemo, type PropsWithChildren } from 'react' import type { ColorValue, TextStyle } from 'react-native' import type { HexColorToken } from '@helpwave/hightide-design/primitive-tokens' import type { IconStyle } from '../../icons' import { HexColorUtils } from '../../utils/hex' import { ContentThemeContext, useContentTheme, type ContentThemeContextValue } from './ContentThemeContext' export type ContentThemeRootProviderProps = PropsWithChildren & ContentThemeContextValue export const ContentThemeRootProvider = ({ children, foreground, background, textStyle, iconStyle, }: ContentThemeRootProviderProps) => { const value = useMemo((): ContentThemeContextValue => ({ foreground, background, textStyle, iconStyle, }), [foreground, background, textStyle, iconStyle]) return ( {children} ) } type ColorOverride = | ColorValue | ((prev: HexColorToken) => ColorValue) type TextStyleOverride = | TextStyle | ((prev: TextStyle, foreground: HexColorToken) => TextStyle) type IconStyleOverride = | IconStyle | ((prev: IconStyle, foreground: HexColorToken) => IconStyle) export type ContentThemeOverrideProviderProps = PropsWithChildren & { foreground?: ColorOverride, background?: ColorOverride, textStyle?: TextStyleOverride, iconStyle?: IconStyleOverride, isKeepingTextColor?: boolean, isKeepingIconColor?: boolean, } const resolveColorOverride = ( override: ColorOverride | undefined, previous: HexColorToken ): HexColorToken | undefined => { if (override === undefined) { return undefined } const raw = typeof override === 'function' ? override(previous) : override return HexColorUtils.tryParseColorValue(raw) } export const ContentThemeOverrideProvider = ({ children, foreground: foregroundOverride, background: backgroundOverride, textStyle: textStyleOverride, iconStyle: iconStyleOverride, isKeepingIconColor = false, isKeepingTextColor = false, }: ContentThemeOverrideProviderProps) => { const parent = useContentTheme() const value = useMemo((): ContentThemeContextValue => { const newForeground = resolveColorOverride(foregroundOverride, parent.foreground) const newBackground = resolveColorOverride(backgroundOverride, parent.background) let textStyle = typeof textStyleOverride === 'function' ? textStyleOverride(parent.textStyle, parent.foreground) : textStyleOverride ?? parent.textStyle if (!isKeepingTextColor && newForeground !== undefined) { textStyle = { ...textStyle, color: newForeground } } let iconStyle = typeof iconStyleOverride === 'function' ? iconStyleOverride(parent.iconStyle, parent.foreground) : iconStyleOverride ?? parent.iconStyle if (!isKeepingIconColor && newForeground !== undefined) { iconStyle = { ...iconStyle, color: newForeground } } return { foreground: newForeground ?? parent.foreground, background: newBackground ?? parent.background, textStyle, iconStyle, } }, [parent, foregroundOverride, textStyleOverride, iconStyleOverride, backgroundOverride, isKeepingTextColor, isKeepingIconColor]) return ( {children} ) }