UNPKG

@react-native-ohos/react-native-unistyles

Version:
99 lines (81 loc) 3.16 kB
import type { Optional, RNStyle, RNValue } from '../types' import { getValueForBreakpoint } from './breakpoints' import { isAndroid, isIOS } from '../common' import { withPlugins } from './withPlugins' export const proxifyFunction = ( key: string, fn: Function, variant?: Record<string, Optional<string>> ): Function => new Proxy(fn, { apply: (target, thisArg, argumentsList) => withPlugins(key, parseStyle(target.apply(thisArg, argumentsList), variant)) }) export const isPlatformColor = <T extends {}>(value: T): boolean => { if (isIOS) { return 'semantic' in value && typeof value.semantic === 'object' } return isAndroid && 'resource_paths' in value && typeof value.resource_paths === 'object' } export const parseStyle = <T extends RNStyle>( style: T, variant: Record<string, Optional<string>> = {}, parseMediaQueries = true ): T => Object .entries(style || {}) .reduce((acc, [key, value]) => { // nested objects if (key === 'shadowOffset' || key === 'textShadowOffset') { acc[key] = parseStyle(value, variant) return acc } // transforms if (key === 'transform' && Array.isArray(value)) { acc[key] = value .map(value => parseStyle(value, variant)) .filter(value => { // remove undefined values if (typeof value === 'object') { return Object.values(value).at(0) !== undefined } return true }) return acc } if ((key === 'boxShadow' || key === 'filter') && Array.isArray(value)) { acc[key] = value .map(value => parseStyle(value, variant, false)) .filter(value => Object.keys(value).length === 1) return acc } if (key === 'fontVariant' && Array.isArray(value)) { acc[key] = value return acc } // values or platform colors if (typeof value !== 'object' || isPlatformColor(value)) { acc[key as keyof T] = value return acc } if (key === 'variants') { return { ...acc, ...(Object .keys(value) as Array<keyof typeof value>) .reduce((acc, key) => ({ ...acc, // this will parse the styles of the selected variant (or default if it is undefined), if selected variant has no styles then it will fallback to default styles ...parseStyle((value)[key][variant[key as keyof typeof variant]?.toString() || 'default'] ?? (value)[key].default ?? {}) }), {}) } } // don't parse media queries and breakpoints if (!parseMediaQueries) { return { ...acc, [key]: value } } return { ...acc, [key]: getValueForBreakpoint(value as Record<string, RNValue>) } }, {} as T)