rnsx
is an accessible styling solution for React Native.
It takes heavy inspiration from Tailwind CSS's tokens to create simplified inline stylesheets.
yarn add rnsx
# or
npm install rnsx
Theme configuration is heavily inspired by Tailwind CSS.
import { DynamicColor, DynamicFont, makeTheme } from 'rnsx';
export const myTheme = makeTheme({
// Define the base em value (default: 4)
em: 5,
// Use top-level attributes to override the default theme
fonts: {
'mori.400': DynamicFont.create({
regular: 'PPMori-Regular',
bold: 'PPMori-SemiBold',
}),
'fraktion.400': DynamicFont.create({
regular: 'PPFraktion-SemiBold',
bold: 'PPFraktion-Bold',
}),
},
// Use nested `extend` attributes to append to the default theme
extend: {
spacing: {
'8xl': '96em,
},
tracking: {
loose: 1,
},
colors: {
success: DynamicColor.create({
light: '#95E99E',
dark: '#366B4B',
}),
failure: DynamicColor.create({
light: '#FF9781',
dark: '#983B35',
}),
},
},
});
Check out the source code to see theme defaults.
This makes it possible for the sx
function to automagically fill in your configuration via Intellisense.
type MyTheme = typeof myTheme;
declare module 'rsnx' {
interface CustomTheme extends MyTheme {}
}
It's required to install this at the root of your app so the useSx
hook can have access to your theme and accessibility info.
import { SxProvider } from 'rnsx';
export default function App() {
return (
<SxProvider theme={myTheme}>
<RestOfApp />
</SxProvider>
);
}
import { useSx } from 'rnsx';
export function ExampleComponent() {
const sx = useSx();
return (
<View style={sx({ padding: { x: '3em', y: 2 } })}>
<Text style={sx({ font: { family: 'mori', weight: 400, size: '3em' } })}>
This is an example!
</Text>
</View>
);
}
Using the styled
HOC, you can create "atom" components. An atom is the smallest building block of your design system, and with this HOC you can skip the useSx
hook altogether!
import { View as RNView } from 'react-native';
import { styled } from 'rsnx';
export const View = styled(RNView);
// ...
// Use `sx` prop directly! No more `useSx`!
return <View sx={{ padding: { x: 3 } }} />;
It's recommended to use hex values for colors rather than their direct names. Why?
Everywhere a color can be used with sx
, you can adjust the opacity.
- sx({ bg: 'background' })
+ sx({ bg: { color: 'background', opacity: 0.5 } })
This functionality only works when your colors are defined as hex values.
rnsx
takes three things (so far!) into consideration when it comes to accessibility:
-
Light and dark mode: using the
DynamicColor
object, we can automatically switch between light and dark mode colors on both iOS and Android (as opposed to only iOS via the DynamicColorIOS API). -
Bold text: when a user enables the bold text setting, the
DynamicFont
object will automatically switch between defined font families to present a bolder options for better legibility. -
Internationalization: All directional tokens use
s
ande
(standing forstart
andend
) rather than left and right to support RTL languages.
More accessibility considerations will be added in the future.
This library is best paired with other a11y-forward React Native libraries, such as:
In React Native, an individual numeric value is treated as a pt
(instead of a px
on the web). rnsx
extends this by borrowing a new type of value from the web: the em
.
The default theme defines an em
as 4pt (though this can be overriden in your custom theme).
So, whereas a value of 3
would result in 3pt, a value of 3em
would result in 12pt (using a multiplier of 4).
The difference is entirely up to you! If you choose, you don't even have to use em
s and just pass all your numeric values as just that — numbers.
Since this library just uses the existing style
prop, you can pass an array of sx
function calls (with possibly falsy values!).
<View
style={[
sx({ bg: 'background' }),
error && sx({ bg: { color: 'failure', opacity: 0.5 }})
]}
>
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with create-react-native-library