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 🙏

© 2025 – Pkg Stats / Ryan Hefner

react-native-patina

v0.1.6

Published

A simple, type-aware theming library

Downloads

180

Readme

react-native-patina

This tiny theming library has two main parts:

You can use these parts either together or separately. Both come with deep, automatic support for both Flow & Typescript.

This library is unopinionated about what a theme should contain. A "theme" is just a plain Javascript object with whatever properties you like (including methods). Here is an example of a pair of themes:

const darkTheme = {
  backgroundColor: '#000000',
  foregroundColor: '#ffffff',
  rem: (size: number) => Math.round(size * 16)
}

const lightTheme = {
  ...darkTheme,
  backgroundColor: '#ffffff',
  foregroundColor: '#000000'
}

type AppTheme = typeof darkTheme

Using ThemeContext

The ThemeContext object can help distribute a theme object throughout your app. Compared to just using the React context API directly, ThemeContext adds a way for non-React code to also get access to the current theme. This can be important if you have Redux actions or other logic that might also care about appearances.

First, create a ThemeContext object based on your initial theme:

import { makeThemeContext } from 'react-native-patina'

// The ThemeContext contains a bunch of methods your app
// can call directly:
export const {
  ThemeProvider,
  useTheme,
  withTheme,
  changeTheme,
  getTheme,
  watchTheme
} = makeThemeContext(darkTheme)

Next, use the ThemeContext.ThemeProvider component to inject the current theme into your React component tree:

const YourApp = () => (
  <ThemeProvider>
    <AllYourScenes />
  </ThemeProvider>
)

The ThemeContext.useTheme hook lets your function-style components access the current theme:

const HeaderText = props => {
  const theme = useTheme()

  // Note: See cacheStyles for how to optimize this:
  const style = {
    color: theme.foregroundColor,
    fontSize: theme.rem(1.2)
  }
  return <Text style={style}>{props.message}</Text>
}

Or, if you are using class-based components, use the ThemeContext.withTheme wrapper to inject a theme property into your component:

class HeaderTextInner {
  render() {
    const { theme } = this.props

    // Note: See cacheStyles for how to optimize this:
    const style = {
      color: theme.foregroundColor,
      fontSize: theme.rem(1.2)
    }
    return <Text style={style}>{this.props.message}</Text>
  }
}

export const HeaderText = withTheme(HeaderTextInner)

To change the current theme, just call ThemeContext.changeTheme:

changeTheme(lightTheme)

This will automatically re-render any React components that use the theme.

If non-React code needs to access the theme, use ThemeContext.getTheme to read the current theme:

StatusBar.setBackgroundColor(getTheme().statusBarColor)

You can also use ThemeProvider.watchTheme to subscribe to updates:

const unsubscribe = watchTheme(theme => {
  StatusBar.setBackgroundColor(theme.statusBarColor)
})

// Call unsubscribe() later if you want to clean up.

Using cacheStyles

The examples above use inline React Native styles, which are slow. Your app will perform much better if it uses StyleSheet.create to build its style sheets ahead of time. On the other hand, just calling StyleSheet.create at startup won't work, because then the styles won't change when the theme changes.

The cacheStyles helper function solves this by memoizing (caching) calls to StyleSheet.create:

import { cacheStyles } from 'react-native-patina'

export const getStyles = cacheStyles((theme: AppTheme) => ({
  header: {
    color: theme.foregroundColor,
    fontSize: theme.rem(1.2)
  },

  text: {
    color: theme.foregroundColor,
    fontSize: theme.rem(1)
  }
}))

This example uses cacheStyles to wrap a getStyles function with caching. This getStyles function accepts the current theme and returns a matching set of styles. From then on, as long as the theme doesn't change, getStyles will continue to return the same cached value:

const HeaderText = props => {
  const theme = ThemeContext.useTheme()
  const styles = getStyles(theme)

  return <Text style={styles.header}>{props.message}</Text>
}

By default, cacheStyles will only remember the last-used theme. If your app frequently switches between several themes, you can increase the cache size to keep more than one style sheet around at once:

import { setCacheSize } from 'react-native-patina'

setCacheSize(4) // Remember style sheets for the last 4 themes