@screensdev/styles
Version:
Cross-platform styles for React Native without the complexity.
76 lines (74 loc) • 2.44 kB
JavaScript
'use client';
import { useMemo } from 'react';
import { StyleSheet } from 'react-native';
import { isContainerQuery, useCachedContainerWidth } from "./container.js";
import { useThemeContext } from "./theme.js";
import { parseStyle } from "./parseStyle.js";
import { useVariantMap } from "./useVariantMap.js";
import { isMediaQuery, useCachedScreenSize } from "./media.js";
/**
* Hook that creates dynamic styles
* @param stylesheet - The stylesheet to use
* @param variantsMap - The map of variants to use
* @returns - RN compatible styles
*/
export const useStyles = (stylesheet, variantsMap) => {
const variants = useVariantMap(variantsMap);
const {
breakpoints,
theme
} = useThemeContext();
const queryMap = useMemo(() => {
return Object.entries({
...stylesheet,
...variantsMap
}).reduce((acc, [_key, value]) => {
if (!value || typeof value === 'string') {
return acc;
}
const parsedValue = typeof value === 'function' ? value(theme) : value;
const responsiveKeys = Object.getOwnPropertySymbols(parsedValue);
if (!responsiveKeys.length) {
return acc;
}
responsiveKeys.forEach(query => {
const queryString = query.description;
if (!queryString) {
return;
}
if (isContainerQuery(queryString)) {
acc.containerQueries.add(query);
return;
}
if (isMediaQuery(queryString)) {
acc.mediaQueries.add(query);
return;
}
});
return acc;
}, {
containerQueries: new Set(),
mediaQueries: new Set()
});
}, [stylesheet, theme, variantsMap]);
const screenSize = useCachedScreenSize(queryMap.mediaQueries, breakpoints);
const containerWidth = useCachedContainerWidth(queryMap.containerQueries);
const dynamicStyleSheet = useMemo(() => Object.entries(stylesheet || {}).reduce((acc, [key, value]) => {
if (typeof value === 'function') {
return {
...acc,
[key]: parseStyle(value(theme), containerWidth, screenSize, variants, breakpoints)
};
}
return StyleSheet.create({
...acc,
[key]: parseStyle(value, containerWidth, screenSize, variants, breakpoints)
});
}, {}), [containerWidth, stylesheet, theme, variants, screenSize, breakpoints]);
return {
theme,
styles: dynamicStyleSheet
};
};
//# sourceMappingURL=useStyles.js.map
;