react-native-swag-styles

Dynamic Styles for React Native and Expo Web

Highlights

  • Dynamic. Based on React Hook. It automatically re-renders when necessary.
  • Unopinionated. Use whatever component or theme library you want.
  • Simple to use. No HOC, no special syntax. Easily migrate from plain StyleSheet.
  • Strictly typed. Take full advantage of TypeScript. Get auto-completions in VSCode.

Installation

yarn add react-native-swag-styles

Usage

Replace StyleSheet.create with makeStyles with callback:

- import { StyleSheet } from 'react-native';
+ import { makeStyles } from 'react-native-swag-styles';

- const styles = StyleSheet.create({
+ const useStyles = makeStyles(() => ({
  underlayColor: '#333',
  container: {
    paddingTop: 24,
    paddingBottom: 32,
  },
-});
+}));

Use created style hook in component:

const Foo = () => {
  const styles = useStyles();
  return (
    <View style={styles.container}>
      <TouchableHighlight underlayColor={styles.underlayColor} />
    </View>
  );
};

To make the style dynamic, pass props to the style creator:

const useStyles = makeStyles((small: boolean) => {
  const iconSize = small ? 16 : 24;
  return {
    icon: {
      width: iconSize,
      height: iconSize,
    },
    // ...
  };
});

const Foo = () => {
  const styles = useStyles(true);
  // ...
};

Advanced Usage:

If you use a theming library, you can attach the theme hook when creating styles:

const useStyles = makeStyles(
  useAppTheme,
  // first argument is the return value of your theme hook
  ({ colors, insets }) => ({
    underlayColor: colors.grey,
    container: {
      paddingTop: insets.top,
      paddingBottom: insets.bottom,
    },
  })
);

You can also create styles using multiple hooks, as long as the hooks don’t take any argument:

const useStyles = makeStyles(
  useAppTheme,
  useWideScreen,
  useWindowDimensions,
  // The order of arguments matches the order of hooks above
  ({ colors, fonts }, isWideScreen, { width }) => {
    // ...
  }
);

Pass hooks and extra props together to the style creator:

const useStyles = makeStyles(
  useAppTheme,
  useWideScreen,
  ({ brandColor, colors, fonts }, isWideScreen, small: boolean) => {
    // ...
  }
);

Important Note: Hook returns and props must be plain (serializable) object/values for memoization to work properly. See fast-memoize.js.

Other APIs

createStyleSheet extends StyleSheet.create to support constant values:

import { createStyleSheet } from 'react-native-swag-styles';

const styles = createStyleSheet({
  text: 'some kind of string',
  regularStyle: {
    paddingTop: 24,
    paddingBottom: 32,
  },
});

Example

To see a full working example, with a custom theme, check out the example folder.

GitHub

https://github.com/ef-eng/react-native-swag-styles