npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-styled.macro

v0.12.0

Published

A Utility-first Styling Library for React Native

Downloads

36

Readme

Disclaimer: This library is still in Beta. Use with caution. The Roadmap for v1.0.0 is available here.

Features

  • Zero-overhead: Styles get injected via the StyleSheet API during compilation.
  • 🍂 Minimal footprint: Styles that are never used won't make it to the final App bundle.
  • 🎲 Variants support: Conditionally style based on Platform, Layout or Screen size ... etc.
  • 💅 Style props: Supports common style-related Component props e.g. numberOfLines.
  • 🔌 Customizable (Coming soon): Optionally override the default theme by adding styled.config.js file

Table of Contents

Getting started

Compatible 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.
  • It will map the given styles and resolve the necessary style attributes/props.
  • It will try to merge styles of the same variant if possible so we don't end up creating an object for every style e.g. text-2xl.
  • For the best performance, it will then use the good/old 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())

Available Styles

See docs/styles.md

Variants

Platform (Built-in)

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',
]);

Layout (Built-in)

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']);

Responsive

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']);

Dark mode

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>
	);
};

Best Practices

Group variant styles together

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.

Prior Art

  • Tailwind CSS (website): Tailwind is a great utility-first CSS framework. We borrowed the utility-first approach from there and re-imagined how it can be used in React Native apps to build user interfaces faster without additional Runtime overhead.

Alternatives

  • tailwind-react-native (github): A very promising Tailwind-like library made with React Native in mind.

License

MIT © Ahmed T. Ali