JSPM

@material-native-ui/theme-provider

0.0.5
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 31
  • Score
    100M100P100Q62083F
  • License MIT

React Native Theme a abstraction over StyleSheet.

Package Exports

  • @material-native-ui/theme-provider

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@material-native-ui/theme-provider) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

React Native Theme Provider

A theme abstraction over React Native StyleSheet. Thanks to @brankeye for great work this package forked from react-native-pain

Nested Theme Support

Usage

Step 1

Install react-native-theme-provider using yarn or npm.

yarn add @material-native-ui/theme-provider
npm install @material-native-ui/theme-provider

Step 2

Wrap your App with a theme provider.

import React from "react";
import { ThemeProvider } from "@material-native-ui/theme-provider";

const defaultTheme = {
    spacing: (spacing) => 8 * spacing,
}


const themes = {
  light: {
    ...defaultTheme,
    name: "light",
    // some light theme properties
    palette: {
        default: 'rgba(100, 100, 100, .5)',
        primary: '#40A3D0',
        secondary: '#F5FF62',
    }
  },
  dark: {
    ...defaultTheme,
    name: "dark",
    // some dark theme properties
    palette: {
        default: 'rgba(200, 200, 200, .5)',
        primary: '#ffbb00',
        secondary: '#ff6501',
    }
  }
};

class App extends React.Component {
  state = {
    currentTheme: themes.light
  };

  changeTheme = () => {
    const { name } = this.state.currentTheme;
    const nextTheme = name === "light" ? themes.dark : themes.light;
    this.setState({
      currentTheme: nextTheme
    });
  };

  render() {
    const { currentTheme } = this.state;
    return (
      <ThemeProvider theme={currentTheme}>
        <App changeTheme={this.changeTheme} />
      </ThemeProvider>
    );
  }
}

Step 3

import React, { Component } from 'react'
import { Text, TouchableOpacity, View } from 'react-native'
import StyleSheet, { withStyles } from '@material-native-ui/theme-provider'

class App extends Component {
  render() {
    const { styles, changeTheme } = this.props
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Awesome Theme Provider</Text>
        <View style={styles.actions}>
          <TouchableOpacity style={styles.button} onPress={changeTheme('dark')}>
            <Text>dark</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.button} onPress={changeTheme('light')}>
            <Text>light</Text>
          </TouchableOpacity>
        </View>
      </View>
    )
  }
}

const style = StyleSheet.create(
  (theme) => ({
    container: {
      flexGrow: 1,
      paddingTop: theme.spacing(4),
      paddingBottom: theme.spacing(2),
      paddingLeft: theme.spacing(2),
      paddingRight: theme.spacing(2),
    },
    title: {
      marginBottom: theme.spacing(2),
    },
    button: {
      borderRadius: 5,
      justifyContent: 'center',
      flexDirection: 'row',
      backgroundColor: theme.palette.default,
    },
    actions: {
      flexDirection: 'row',
    },
  })
)
export default withStyles(style)(App)

Nested Theme

        <ThemeProvider theme={themes.green}>
            <Button color={'primary'} text="Submit" />
            <ThemeProvider theme={themes.blue}>
              <Button color={'primary'} text="Submit" />
            </ThemeProvider>
        <ThemeProvider theme={themes.light}>

useStyle hook

import React, { Component } from 'react'
import StyleSheet, { useStyle } from '@material-native-ui/theme-provider'

const style = StyleSheet.create(
  (theme) => ({
    container: {
      flexGrow: 1,
      paddingTop: theme.spacing(4),
      paddingBottom: theme.spacing(2),
      paddingLeft: theme.spacing(2),
      paddingRight: theme.spacing(2),
    },   
  })
)
const App = function({ children }) {
    const style = useStyle(style)
    
    return (
      <View style={styles.container}>
            {/* content */}
      </View>
    )
}

withTheme props

import React, { Component } from 'react'
import  { withTheme } from '@material-native-ui/theme-provider'
import {
  NavigationContainer,
  DefaultTheme,
} from '@react-navigation/native';

class App extends Component {
  render() {
    const { styles, theme } = this.props
    const MyTheme = {
      ...DefaultTheme,
      colors: {
        ...DefaultTheme.colors,
        primary: theme.palette.primary,
      },
    };
    return (
      <NavigationContainer theme={MyTheme}>
            {/* content */}
      </NavigationContainer>
    )
  }
}

export default withTheme(App)

useTheme hook

import React, { Component } from 'react'
import {
  NavigationContainer,
  DefaultTheme,
} from '@react-navigation/native';
const App = function({ children }) {
    const theme = useTheme()
    const MyTheme = { //send theme to react navigation theme
      ...DefaultTheme,
      colors: {
        ...DefaultTheme.colors,
        primary: theme.palette.primary,
      },
    };
    return (
      
      <NavigationContainer theme={MyTheme}> 
            {/* content */}
      </NavigationContainer>
    )
}

with type script

import React, { Component } from 'react'
import { Text, TextStyle, TouchableOpacity, View, ViewStyle } from 'react-native'
import StyleSheet, { withStyles } from '@material-native-ui/theme-provider'

interface InterfaceStyles {
  container: ViewStyle
  button: ViewStyle
  actions: ViewStyle
  title: TextStyle
}

interface InterfaceProps {
  styles: InterfaceStyles
  changeTheme: Function
}

class App extends Component<InterfaceProps> {
  render() {
    const { styles, changeTheme } = this.props
    return (
      <View style={styles.container}>
        // children
      </View>
    )
  }
}

const style = StyleSheet.create(
  (theme): InterfaceStyles => ({
    //styles
  })
)
export default withStyles(style)(App)

customize

Use it in your components.

import Theme, { StylesConsumer, withStyles } from "@material-native-ui/theme-provider";

// with theme
const style = Theme.create((theme) => ({
  container: {
    color: theme.textColor,
    // Theme inherits all properties from StyleSheet
    ...Theme.absoluteFillObject,
  }
}));

// or without theme
const style = Theme.create({
  color: "blue",
});

// or create a stylesheet directly
// but do not pass this to style prop on consumer/hoc
const stylesheet = Theme.sheet({
  color: "blue",
})

// as consumer
const ThemedText = (props) => (
  <StylesConsumer style={style}>
    {(styles) => (
      <Text {...props} styles={styles} />
    )}
  </StylesConsumer>
);

export default ThemedText;

// or as hoc
const ThemedText = (({ styles, ...props }) => (
  <Text {...props} styles={styles} />
));

export default withStyles(style)(ThemedText);

Road map

state react-native react-native-web
fork from react-native-paint
provide theme as props
useStyle hook
useTheme hook
reWrite with type script

Example