Giter VIP home page Giter VIP logo

react-native-theming's Introduction

react-native-theming

An efficient and StyleSheet.create compatible theming library for React Native.

Demo

Installation

$ yarn add react-native-theming
or
$ npm install --save react-native-theming

Usage

Create themes

import { createTheme } from 'react-native-theming'

const themes = [
  createTheme({
    backgroundColor: 'white',
    textColor: 'black',
    buttonColor: 'blue',
    buttonText: 'white',
    icon: require('./icons/default.png'),
    statusBar: 'dark-content',
  }, 'Light'),
  createTheme({
    backgroundColor: 'black',
    textColor: 'white',
    buttonColor: 'yellow',
    buttonText: 'black',
    icon: require('./icons/colorful.png'),
    statusBar: 'light-content',
  }, 'Dark'),
];

Create Styles

Create styles as you would with StyleSheet.create. Except you can now use theme variables on your styles with an @ prefix followed by the name of the theme variable as declared in the theme. You can also construct your style including the theme variable, like 'rgba(@backgroundColor, 0.2)'.

import { createStyle } from 'react-native-theming';

const styles = createStyle({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '@backgroundColor',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color: '@textColor',
  },
  instructions: {
    textAlign: 'center',
    color: '#888',
    marginBottom: 5,
  },
  button: {
    margin: 10,
    padding: 10,
    backgroundColor: '@buttonColor',
    borderRadius: 3,
    flex: 1,
    alignItems: 'center',
  },
});

Create custom components

The theming library provides Theme.View, Theme.Image, Theme.Text, Theme.AnimatedView, Theme.AnimatedImage, Theme.Animated.Text components, which needs to be used in place of respective View, Image and Text for the theme to take affect. Custom components could be easily made themable as well.

import { createThemedComponent } from 'react-native-theming';
import { TouchableOpacity, StatusBar } from 'react-native';

const Button = createThemedComponent(TouchableOpacity);
const Bar = createThemedComponent(StatusBar, ['barStyle', 'backgroundColor']);

Create your themed view

It is not just the styles, but the themes could even be applied to the props. Not all properties will however support theming. For example, with the builtin components, only Theme.Image and Theme.AnimatedImage supports theming with source property. You can however create custom components with an array of props that needs theming support. In the above example, the StatusBar component has been themed with barStyle and backgroundColor props.

import React from 'react';
import Theme from 'react-native-theming';
import { View, Text, StatusBar } from 'react-native';

... Create your themes
... Create the styles
... Create custom components

export default class ThemeDemo extends Component {
  render() {
    return (
      <Theme.View style={styles.container}>
        <Bar barStyle="@statusBar" backgroundColor="@backgroundColor" />
        <Theme.Image source="@icon" />
        <Theme.Text style={styles.welcome}>
          React Native Theming Demo!
        </Theme.Text>
        <Theme.Text style={styles.instructions}>
          To experiment check app.js file
        </Theme.Text>
        <Text style={styles.instructions}>
          You can now create your themes using JSON. The styles declaration
          is directly compatible with StyleSheet.create. You just need to
          replace `StyleSheet.create` with `createStyle` and add your theme
          variables in the styles.
        </Text>
        <View style={{ flexDirection: 'row' }}>
          { themes.map(theme => (
            <Button key={theme.name} style={styles.button} onPress={() => theme.apply()}>
              <Theme.Text style={{ color: '@buttonText' }}>{theme.name}</Theme.Text>
            </Button>
            ))
          }
        </View>
      </Theme.View>
    );
  }
}

Applying Theme

Applying themes is just a matter of invoking apply method on the theme instance returned by the createTheme method. Check out the Button.onPress event in the above example. The first created theme becomes the default theme.

Try the demo

On Expo

or

check the code out.

react-native-theming's People

Contributors

blazk0 avatar dependabot[bot] avatar syaau avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-theming's Issues

Integration with React-Native-Navigation

Hello, Love the repo.
I have been wanting to implementing this library and been having success!
One problem that I need to be tacked before fully implemented into my app is switching TabBar & Navigation Bar Colours from react-native-navigation!

There docs are here, Any clue how to implement this? Thanks

Adding Typescript support

Is this repository still maintaining? last commits were for almost a year ago.
is there any plan in the near future to adding typescript support for this library?

Theming does not work with containerStyle etc. props

I am using a Card component from React Native Elements. In order to style the component, it requires one to use containerStyle. That does not work with react-native-theming. Everything that uses "style" works fine

<ThemedCard containerStyle={styles.cardContainer} image={require('../../assets/images/notecards.jpg')} imageStyle={{overflow: 'hidden', borderTopRightRadius: 15, borderTopLeftRadius: 15}} borderRadius={15}> <Theme.Text style={styles.titleText}>{text}</Theme.Text> <ThemedAppText text="Last Edited: 5 Days Ago" style={styles.lastEdited} /> <ThemedAppText text="Last Viewed: Today" style={styles.lastViewed}/> </ThemedCard>

cardContainer: { backgroundColor: '@mainColor', borderRadius: 15, height: 200, width: 150, margin: 20, flex: 1, flexDirection: 'row', justifyContent: 'center', elevation: 2, shadowColor: 'rgba(0, 0, 0, 1)', shadowOpacity: 1, shadowRadius: 1, borderColor: '@mainColor' },

export const ThemedCard = createThemedComponent(Card);

Need some way to stop logging so many things on the console

There is a log statement which shows up on every view render i suppose, one on the createThemedComponent.js:91.
This maybe one of the reasons for slowing down the app when the JS debugger isnt hooked in since the JS code then runs on the device/simulator.
This leads to significant lags in the app.

How can i apply placeholderTextColor text color based on theme.

How can we implement placeholderTextColor dynamically

eg.

Theme File

const AppThemes = [
  createTheme({
    fontColor: '#222222',
    backgroundColor: '#FFFFFF',
   rgbaBackground: '255,255,255'
  }, 'Theme1'),
  createTheme({
    backgroundColor: '#222222',
   fontColor: '#FFFFFF',
   rgbaBackground: '0,0,0'
  }, 'Theme1'),
];

Component File
import { TextInput } from 'react-native'

const Input = createThemedComponent(TextInput);
.
.
<Input placeholder='Email' placeholderTextColor='@fontColor' style={styles.inputCtrl} />
.
.
.

IN above example placeholderTextColor is not updating on theme switching. anything we can do it with or implement it like We have in

Any idea what is issue or is there already feature in library??

Thank you in advance

Failed prop type: Invalid props.style key `id` supplied to `View`.

I'm seeing the following warning when using react-native-theming:

Warning: Failed prop type: Invalid props.style key `id` supplied to `View`.
Bad object: {
  "id": 1,
  "marginVertical": 4,
  "opacity": 1
}
Valid keys: [
  "display",
  "width",
  "height",
  "start",
  "end",
  "top",
  "left",
  "right",
  "bottom",
  "minWidth",
  "maxWidth",
  "minHeight",
  "maxHeight",
  "margin",
  "marginVertical",
  "marginHorizontal",
  "marginTop",
  "marginBottom",
  "marginLeft",
  "marginRight",
  "marginStart",
  "marginEnd",
  "padding",
  "paddingVertical",
  "paddingHorizontal",
  "paddingTop",
  "paddingBottom",
  "paddingLeft",
  "paddingRight",
  "paddingStart",
  "paddingEnd",
  "borderWidth",
  "borderTopWidth",
  "borderStartWidth",
  "borderEndWidth",
  "borderRightWidth",
  "borderBottomWidth",
  "borderLeftWidth",
  "position",
  "flexDirection",
  "flexWrap",
  "justifyContent",
  "alignItems",
  "alignSelf",
  "alignContent",
  "overflow",
  "flex",
  "flexGrow",
  "flexShrink",
  "flexBasis",
  "aspectRatio",
  "zIndex",
  "direction",
  "shadowColor",
  "shadowOffset",
  "shadowOpacity",
  "shadowRadius",
  "transform",
  "transformMatrix",
  "decomposedMatrix",
  "scaleX",
  "scaleY",
  "rotation",
  "translateX",
  "translateY",
  "backfaceVisibility",
  "backgroundColor",
  "borderColor",
  "borderTopColor",
  "borderRightColor",
  "borderBottomColor",
  "borderLeftColor",
  "borderStartColor",
  "borderEndColor",
  "borderRadius",
  "borderTopLeftRadius",
  "borderTopRightRadius",
  "borderTopStartRadius",
  "borderTopEndRadius",
  "borderBottomLeftRadius",
  "borderBottomRightRadius",
  "borderBottomStartRadius",
  "borderBottomEndRadius",
  "borderStyle",
  "opacity",
  "elevation"
]
    in View (at createAnimatedComponent.js:134)
    in AnimatedComponent (at TouchableOpacity.js:245)

This only happens when I switch from a real colour to an "@" colour:

module.exports = createStyle({
  button: {
    backgroundColor: "@themeButton",
    borderColor: "@themeButton",
    borderWidth: 1,
    borderRadius: 4,
    marginVertical: 10,
    paddingHorizontal: 16,
    alignSelf: "stretch",
    justifyContent: "center"
  }});

could it support a nested structure?

Hi, I would love it if I can do this:

createStyle({
  someModule: {
    someStyle: 'red'
  },
  anotherModule: ...
}

and then refer to it like '@someModule.someStyle'. As I have quite some styles grouped like that it would be hard to flatten into a list.

Passing forwardRef

Hi,
I am passing TextInput into ThemedComponent.I need pass ref to child component which is TextInput.
I need your help that how i can pass ref or forwardRef to child component.
Bellow is code that how i am exactly doing.

const textInput = createThemedComponent(TextInput);

Issue with forwardRef

Hi, this is my code and I get this error

Failed prop type: Invalid prop 'forwardRef' supplied to Theme.undefined, expected a ReactNode.

My code:


import React from 'react';
import {createThemedComponent} from 'react-native-theming';
import {createStyle} from 'react-native-theming';
import {Portal} from 'react-native-portalize';
import {Modalize} from 'react-native-modalize';
import normalize from 'react-native-normalize';

import * as Haptics from 'expo-haptics';

import {Text, View} from "native";
import {isApple} from "utils/platform";

const ModalizeThemed = createThemedComponent(Modalize, ['modalStyle']);
type BaseProps = Modalize;

interface Props extends BaseProps {
    headerText?: string | null;
    contentStyle?: any;
    headerComponent?: any,
}

export class BottomSheet extends React.Component<Props> {
    static defaultProps: {
        headerText: null,
        headerComponent: null,
        children: null,
        open: () => void,
        close: () => void,
        contentStyle: {},
    };

    private modalRef: Modalize | null;

    constructor(props: Props) {
        super(props);
        this.open = this.open.bind(this)
        this.close = this.close.bind(this)
    }

    public open: () => void = () => {
        this.modalRef?.open();
    };

    public close: () => void = () => {
        this.modalRef?.close();
    };

    render() {
        const {headerText, headerComponent, children, contentStyle, ...props} = this.props;

        return (
            <Portal>
                <ModalizeThemed
                    ref={(ref: Modalize) => {this.modalRef = ref}}
                    modalStyle={[styles.modal, contentStyle]}
                    modalTopOffset={60}
                    closeSnapPointStraightEnabled={false}
                    onPositionChange={(pos: string) => pos === 'top' ? Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy) : null}
                    HeaderComponent={
                        <View>
                            {(headerText && !headerComponent) && (<View style={styles.headerContainer}><Text size="h3" style={styles.headerText}>{headerText}</Text></View>)}
                            {headerComponent && headerComponent}
                        </View>
                    }
                    {...props}>
                    <View style={styles.contentContainer}>
                        {children}
                    </View>
                </ModalizeThemed>
            </Portal>
        );
    }
}

const styles = createStyle({
    headerContainer: {
        borderTopLeftRadius: normalize(15),
        borderTopRightRadius: normalize(15),
        borderBottomWidth: 1,
        borderBottomColor: '@containerBackgroundColor',
        justifyContent: 'center',
        height: normalize(40),
        width: '100%',
        backgroundColor: '@cardBackgroundColor',
    },
    headerText: {
        // fontSize: normalize(isApple(14,16)),
        width: '100%',
        textAlign: 'center',
        fontWeight: isApple('600', 'bold'),
    },
    contentContainer: {
        flex: 1,
    },
    modal: {
        backgroundColor: '@containerBackgroundColor',
    },
});


But everything is rendering properly

Any ideas? Thanks

rgba not working

Great Library and pretty use full as well,

I have one issue which i am not able to figuring out how to do

Theme File

const AppThemes = [
  createTheme({
    backgroundColor: '#FFFFFF',
   rgbaBackground: '255,255,255'
  }, 'Theme1'),
  createTheme({
    backgroundColor: '#222222',
   rgbaBackground: '0,0,0'
  }, 'Theme1'),
];

For example: I have backgroundColor in css file.

 button: {
    backgroundColor: '@backgroundColor',
  }

It is working fine with above code.

But if i try to use rgba Value like:

button:{
    backgroundColor: 'rgba(@rgbaBackground,0.2)',
}

which is giving error. I want to keep opacity dynamic only need rgb value of base color from theme.

Any idea how can i do that????

Library needs to be updated

I am using this library but It keeps on showing warnings regarding components lifecycle. Will you be able to update the code?
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.