Gathering detailed insights and metrics for stitches-rn-maki
Gathering detailed insights and metrics for stitches-rn-maki
React Native implementation of Stitches (CSS-in-JS library)
npm install stitches-rn-maki
Typescript
Module System
Min. Node Version
Node Version
NPM Version
42.7
Supply Chain
57.8
Quality
66.6
Maintenance
50
Vulnerability
93.8
License
TypeScript (57.34%)
JavaScript (42.66%)
Total Downloads
123
Last Day
1
Last Week
3
Last Month
7
Last Year
123
114 Commits
1 Branches
1 Contributors
Minified
Minified + Gzipped
Latest Version
0.4.0
Package Id
stitches-rn-maki@0.4.0
Unpacked Size
165.96 kB
Size
30.79 kB
File Count
23
NPM Version
9.8.1
Node Version
18.18.2
Publised On
05 May 2024
Cumulative downloads
Total Downloads
Last day
0%
1
Compared to previous day
Last week
200%
3
Compared to previous week
Last month
0%
7
Compared to previous month
Last year
0%
123
Compared to previous year
1
2
30
1npm install stitches-native
or if you use yarn
:
1yarn add stitches-native
For the most part Stitches Native behaves exactly as Stitches so you should follow the Stitches documentation to learn the basic principles and how to setup everything.
Due to the inherit differences between the Web and native platforms (iOS + Android) the implementation of Stitches Native differs slightly from the original Web version of Stitches.
First of all, CSS in React Native doesn't have CSS Variables, cascade, inheritance, keyframes, pseudo elements/classes, or global styles which means that some features that are available in Stitches are not possible to implement in Stitches Native.
Below you can see a list of all supported and unsupported features of Stitches Native.
Feature | Supported |
---|---|
styled | ✅ |
createStitches | ✅ |
defaultThemeMap | ✅ |
css | ✅ (Simplified version) |
theme | ✅ (Use useTheme in components/hooks) |
createTheme | ✅ (Only returned by createStitches ) |
useTheme | 🆕 (Stitches Native specific) |
ThemeProvider | 🆕 (Stitches Native specific) |
styled().attrs() | 🆕 (Stitches Native specific) |
globalCss | ❌ (No global styles in RN) |
keyframes | ❌ (No CSS keyframes in RN) |
getCssText | ❌ (SSR not applicable to RN) |
Nesting | ❌ (No CSS cascade in RN) |
Selectors | ❌ (No CSS selectors in RN) |
Locally scoped tokens | ❌ (No CSS variables in RN) |
Pseudo elements | ❌ (No pseudo elements/classes in RN) |
createStitches
functionThe createStitches
function doesn't need prefix
or insertionMethod
since they are not used in the native implementation.
1import { createStitches } from 'stitches-native';
2
3createStitches({
4 theme: object,
5 media: object,
6 utils: object,
7 themeMap: object,
8});
The return value of createStitches
doesn't include globalCss
, keyframes
, or getCssText
since they are not available in native platforms. React Native doesn't have any CSS keyframes based animations and all animations should be handled by the Animated API or with libraries such as react-native-reanimated.
The return value of createStitches
consist of the following:
1const { styled, css, theme, createTheme, useTheme, ThemeProvider, config } = 2 createStitches({ 3 /*...*/ 4 });
The following token types are supported in React Native: borderStyles
, borderWidths
, colors
, fonts
, fontSizes
, fontWeights
, letterSpacings
, lineHeights
, radii
, sizes
, space
, zIndices
.
The only unsupported token types are shadows
and transitions
. Shadows in React Native cannot be expressed with a single string token like on the Web where CSS box-shadow
accepts a string that fully describes the shadow. In React Native shadows are defined differently on iOS and Android. On iOS you need to set the various shadow properties separately:
1shadowOffset: { 2 width: number, 3 height: number 4}, 5shadowOpacity: number, 6shadowRadius: number
On Android there is a completely different elevation system that doesn't let you alter individual shadow properties but instead you have to set a single number as the elevation level:
1elevation: number;
So, instead of having shadows as part of the design tokens in the theme
we can quite easily define shadow utilities inside utils
:
1createStitches({ 2 utils: { 3 shadow: (level: 'small' | 'medium' | 'large') => { 4 return { 5 small: { 6 elevation: 2, 7 shadowOffset: { width: 0, height: 1 }, 8 shadowRadius: 3, 9 shadowOpacity: 0.1, 10 shadowColor: '#000', 11 }, 12 medium: { 13 elevation: 5, 14 shadowOffset: { width: 0, height: 3 }, 15 shadowRadius: 6, 16 shadowOpacity: 0.2, 17 shadowColor: '#000', 18 }, 19 large: { 20 elevation: 10, 21 shadowOffset: { width: 0, height: 6 }, 22 shadowRadius: 12, 23 shadowOpacity: 0.4, 24 shadowColor: '#000', 25 }, 26 }[level]; 27 }, 28 }, 29});
You can then use the shadow util like this:
1const Comp = styled('View', { 2 shadow: 'medium', 3});
The other unsupported token type is transitions
which conflicts with how animations are handled in React Native. Read more about animations in the Animations docs.
css
helperUnlike on the Web there is no concept of className
in React Native so the css
function is basically an identity function providing only TS types for the style object and returning exactly the same object back (or if given multiple objects merges them together). The returned object can be appended after the first argument of a styled component.
1const styles = css({ 2 backgroundColor: '$background', // <- get autocomplete for theme values 3}); 4 5const SomeComp = styled( 6 'View', 7 { 8 /* ...other styles... */ 9 }, 10 styles // <- you can add as many shared styles as you want 11); 12 13<AnotherComp css={styles} />;
createTheme
Stitches Native handles theming differently than Stitches. Since there are no CSS Variables in React Native theming is handled via React Context in a similar way as other CSS-in-JS libraries such as styled-components handle theming.
1const { theme, createTheme, ThemeProvider } = createStitches({ 2 colors: { 3 background: '#fff', 4 text: '#000', 5 }, 6}); 7 8const darkTheme = createTheme({ 9 colors: { 10 background: '#000', 11 text: '#fff', 12 }, 13}); 14 15function App() { 16 // In a real world scenario this value should probably live in React Context 17 const [darkMode, setDarkMode] = useState(false); 18 19 return ( 20 <ThemeProvider theme={darkMode ? darkTheme : theme}> 21 {/*...*/} 22 </ThemeProvider> 23 ); 24}
You can get the current theme via the useTheme
hook:
1import { useTheme } from '../your-stitches-config'; 2 3function Example() { 4 const theme = useTheme(); 5 6 // Access theme tokens 7 // theme.colors|space|radii|etc.x 8 9 return ( 10 <View style={{ backgroundColor: theme.colors.background }}>{/*...*/}</View> 11 ); 12}
Stitches Native supports theme token aliases the same way as Stitches with a minor difference related to TypeScript support:
1createStitches({ 2 colors: { 3 black: '#000', 4 primary: '$black' as const, 5 }, 6 space: { 7 1: 8, 8 2: 16, 9 3: 32, 10 max: '$3' as const, 11 }, 12});
Note the usage of as const
for token alias values. It is required if you want to have the correct type for the theme token value when accessing it via useTheme
hook:
1import { useTheme } from '../your-stitches-config'; 2 3function Example() { 4 const theme = useTheme(); 5 6 const x = theme.colors.primary; // <-- type of `x` is `string` 7 const y = theme.space.max; // <--- type of `y` is `number` even though the value in the theme is `'$3'`, yey 😎 8 9 return <View style={{ backgroundColor: x, padding: y }}>{/*...*/}</View>; 10}
⚠️ NOTE: without
as const
the type of the token will always bestring
!
For string
type tokens, you don't necessarily need to use as const
since the types align correctly without it, but you might want to do so anyway to be consistent.
media
Responsive styles are not very common in React Native applications since you usually have a clearly constrained device environment where the app is used. However, some times you might need to tweak a style for very small or large phones or build an app that needs to adapt to tablet devices. For these use cases Stitches Native has support for two kinds of responsive styles:
Simple boolean flags in the media
config can be used to distinguish between device types, eg. phone vs. tablet. You can utilize getDeviceType()
or isTablet()
from react-native-device-info to get the device type.
1const isTablet = DeviceInfo.isTablet();
2
3const { ... } = createStitches({
4 media: {
5 phone: !isTablet,
6 tablet: isTablet,
7 },
8});
Then you can apply different prop values for variants of a styled components based on the device type:
1const ButtonText = styled('Text', { 2 // base styles 3 4 variants: { 5 color: { 6 primary: { 7 color: '$primary', 8 }, 9 secondary: { 10 color: '$secondary', 11 }, 12 }, 13 }, 14}); 15 16<ButtonText color={{ '@phone': 'primary', '@tablet': 'secondary' }}> 17 Hello 18</ButtonText>;
It's also possible to have a more Web-like breakpoint system based on the dimensions of the device. The syntax for the queries follows the CSS range queries syntax which means that there is no need to use min-width
or max-width
.
Examples of supported range queries:
(width > 750px)
(width >= 750px)
(width < 1080px)
(width <= 1080px)
(750px > width >= 1080px)
⚠️ NOTE: Only width based media queries are currently supported.
1const { ... } = createStitches({ 2 media: { 3 md: '(width >= 750px)', 4 lg: '(width >= 1080px)', 5 xl: '(width >= 1284px)', 6 xxl: '(width >= 1536px)', 7 }, 8});
⚠️ NOTE: The order of the media query keys matters and the responsive styles are applied in the order determined by
Object.entries
method.
Using media queries works the same way as device type flags:
1const ButtonText = styled('Text', { 2 // base styles 3 4 variants: { 5 color: { 6 primary: { 7 color: '$primary', 8 }, 9 secondary: { 10 color: '$secondary', 11 }, 12 }, 13 }, 14}); 15 16<ButtonText 17 color={{ 18 '@initial': 'primary', 19 '@md': 'secondary', 20 '@lg': 'tertiary', 21 }} 22> 23 Hello 24</ButtonText>;
.attrs
In React Native it is quite common that a component exposes props (other than style
) that accept a style object - a good example of this is the ScrollView
component that has contentContainerStyle
prop. Using theme tokens with these kind of props can be accomplished with the useTheme
hook:
1function Comp() { 2 const theme = useTheme(); 3 4 return ( 5 <ScrollView contentContainerStyle={{ padding: theme.space[2] }}> 6 {/* ... */} 7 </ScrollView> 8 ); 9} 10 11const ScrollView = styled('ScrollView', { 12 flex: 1, 13});
This approach is fine but a bit convoluted since you have to import a hook just to access the theme tokens. There is a better way with the chainable .attrs
method which can be used to attach additional props to a Stitches styled component (this method was popularized by styled-components).
⚠️ NOTE: this method does not exist in the original Web version of Stitches.
1function Example() { 2 return <ScrollView>{/*...*/}</ScrollView>; 3} 4 5const ScrollView = styled('ScrollView', { 6 flex: 1, 7}).attrs((props) => ({ 8 contentContainerStyle: { 9 padding: props.theme.space[2], 10 }, 11}));
It is also possible to access the variants of the component within .attrs
:
1function Example() { 2 return <ScrollView spacious>{/*...*/}</ScrollView>; 3} 4 5const ScrollView = styled('ScrollView', { 6 flex: 1, 7 variants: { 8 spacious: { 9 true: { 10 // some styles... 11 }, 12 false: { 13 // some styles... 14 }, 15 }, 16 }, 17}).attrs((props) => ({ 18 contentContainerStyle: { 19 padding: props.theme.space[props.spacious ? 4 : 2], 20 }, 21}));
No vulnerabilities found.
No security vulnerabilities found.