react-native-unistyles
Version:
Level up your React Native StyleSheet
80 lines (61 loc) • 2.15 kB
text/typescript
import { deepMergeObjects } from '../../../utils'
import { keyInObject } from '../../utils'
type Styles = Record<string, any>
type Normalize<TStyles extends Styles> = (key: keyof TStyles, value: TStyles[keyof TStyles]) => any
const createStylesValue = <TStyles extends Styles>(styles: Array<TStyles>, normalize: Normalize<TStyles>) =>
styles
.map((style) => {
const [key] = Object.keys(style)
if (!key) {
return undefined
}
return normalize(key, style[key])
})
.filter(Boolean)
.join(' ')
export const getObjectStyle = <TStyles extends Styles>(
styles: Array<TStyles>,
styleKey: string,
normalize: Normalize<TStyles>,
) => {
const breakpoints = new Set<string>()
const normalStyles: Array<TStyles> = []
styles.forEach((style) => {
const [property] = Object.keys(style)
if (!property) {
return
}
const value = style[property]
if (typeof value === 'object' && !Array.isArray(value)) {
Object.keys(value ?? {}).forEach((breakpoint) => breakpoints.add(breakpoint))
return
}
normalStyles.push(style)
})
const breakpointStyles = Array.from(breakpoints).flatMap((breakpoint) => {
const stylesPerBreakpoint = styles.flatMap((style) => {
const [property] = Object.keys(style)
if (!property) {
return []
}
const value = style[property]
if (typeof value === 'object' && !Array.isArray(value)) {
return keyInObject(value, breakpoint) ? [{ [property]: value[breakpoint] }] : []
}
return []
}) as Array<TStyles>
return [
{
[breakpoint]: {
[styleKey]: createStylesValue(stylesPerBreakpoint, normalize),
},
},
]
})
return deepMergeObjects<Record<string, any>>(
{
[styleKey]: createStylesValue(normalStyles, normalize),
},
...breakpointStyles,
)
}