react-native-unistyles
Version:
Level up your React Native StyleSheet
70 lines (51 loc) • 2.01 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)
}