⚛️ A Utility-First Styling Library for React Native
Disclaimer: This library is still in Beta. Use with caution. The Roadmap for v1.0.0 is available here.
A Utility-first Styling Library for React Native.
numberOfLines
.styled.config.js
fileCompatible with React Native v0.62.0 or later
yarn add react-native-styled.macro babel-plugin-macros
Add babel-plugin-macros
to your Babel config (if you haven't already)
// babel.config.js
module.exports = function (api) {
return {
plugins: ['macros'],
// ... other stuff
};
};
To use the library simply import the macro as follows:
import styled from 'react-native-styled.macro';
const Heading = ({ text }) => (
<Text
{...styled([
'my-4',
'text-2xl',
'text-gray-900',
'font-semibold',
'letter-wide',
])}
>
{text}
</Text>
);
The compiled output for the above code will look something like the following:
import { Text } from 'react-native';
+import { StyleSheet } from 'react-native';
+import { rem } from 'react-native-styled.macro/path/not/relevant';
-import styled from 'react-native-styled.macro';
+const styles = StyleSheet.create({
+ _default: {
+ marginVertical: rem(1),
+ fontSize: rem(1.5),
+ color: '#1a202c',
+ fontWeight: '600',
+ letterSpacing: rem(0.025),
+ },
+});
const Heading = ({ text }) => (
<Text
- {...styled([
- 'my-4',
- 'text-2xl',
- 'text-gray-900',
- 'font-semibold',
- 'letter-wide',
- ])}
+ {...{
+ style: styles._default,
+ }}
>
{text}
</Text>
);
How does it work?
styled
(you can name it anything) is a Babel Macro which means it will be executed during compilation.text-2xl
.StyleSheet.create
to create the styles as you should normally do by yourself in a React Native app.The output for any code you write will look more or less the same as above. The only exception is a style with multiple variants because we need to add logic to switch styles at runtime (same as you would do e.g. using Platform.select()
)
See docs/styles.md
Enables Platform-specific style. Based on the value of Platform.OS.
Possible values: android
, ios
, web
or whatever the value of Platform.OS
.
Example:
styled([
'bg-white',
'web:bg-purple-600',
'android:bg-green-600',
'ios:bg-blue-600',
]);
Enables Layout-specific style. Based on the value of I18nManager.isRTL
.
Possible keys: ltr
or rtl
.
Example:
styled(['text-auto', 'rtl:text-right', 'ltr:text-left']);
Built on the top of React Native's useWindowDimensions hook. Possible keys: sm
, md
, lg
, xl
or custom values (see below).
Example
import styled from 'react-native-styled.macro';
import { useWindowVariant } from 'react-native-styled.macro/lib';
const MyComponent = () => {
const windowVariant = useWindowVariant();
return (
<Text
{...styled(['w-full', 'md:w-64'], {
...windowVariant /* other variants */,
})}
>
My text
</Text>
);
};
You can also pass custom breakpoints as follows:
// Note: passing a custom object will remove the default breakpoints e.g. `sm`.
useWindowVariant({
tablet: 640,
laptop: 768,
// .. anything really
});
// use it later
styled(['tablet:w-full', 'laptop:w-64']);
Since styled
accepts arbitrary keys as variants supporting Dark mode can be easily acheived as follows:
import { useColorScheme } from 'react-native';
import styled from 'react-native-styled.macro';
const MyComponent = () => {
// Can either be 'dark' or 'light'
const colorScheme = useColorScheme();
return (
<Text
{...styled(['text-black', 'dark:text-white'], {
dark: colorScheme === 'dark',
})}
>
My text
</Text>
);
};
Do NOT
styled(['web:bg-gray-100', 'bg-white', 'text-black', 'web:rounded']);
Do
styled(['bg-white', 'text-black', 'web:rounded', 'web:bg-gray-100']);
In addition to the readability concern, it also enables some compile-time optimizations.
MIT © Ahmed T. Ali