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 rnsxTheme 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
DynamicColorobject, 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
DynamicFontobject will automatically switch between defined font families to present a bolder options for better legibility. -
Internationalization: All directional tokens use
sande(standing forstartandend) 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 ems 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