JavaScripting

The definitive source of the best
JavaScript libraries, frameworks, and plugins.


  • ×

    Uranium

    Universal css-in-js media queries for React Native and React
    Filed under  › 

    • 🔾15%Overall
    • 121
    • 19.2 days
    • 🕩6
    • 👥4

    Uranium

    Adds media-query support to css-in-js in React Native and React.

    
    export default () => <View css={styles.base} />
    
    const styles = {
      base: {
        height: 120,
    
        '@media (min-width: 600px)': {
          height: 56,
        },
      },
    }
    
    iOS Web
    iOS Uranium Example web Uranium example

    Also works with android and server-side rendering

    This can be used with react-native-web for a basic write-once, run-anywhere React Native app.

    Installation

    If using in React Native, install react-native-match-media

    Make sure global.matchMedia is set:

    import matchMedia from 'react-native-match-media'
    
    // Only for native, will already be set on web
    global.matchMedia = matchMedia
    

    Then:

    npm -S i tuckerconnelly/uranium
    

    Usage

    Use the css property to add styles with media queries.

    Then wrap your component in Uranium

    import React, { PropTypes } from 'react'
    import { View } from 'react-native'
    import Uranium from 'uranium'
    
    import Shadows from './styles/Shadows'
    
    const MyComponent = () =>
      <View css={styles.base}>
        <Text>Some text</Text>
      </View>
    
    export default Uranium(MyComponent)
    
    
    const styles = {
      base: {
        backgroundColor: 'red',
    
        '@media (min-width: 480px)': {
          backgroundColor: 'blue',
        }
      },
    }
    

    animate() function

    Uranium adds the animate() function to make animations simple in React Native, and to take into account the current screen size/media query when animating.

    It supports the following signatures:

    animate(from: Object, to: Object, on: Animated.AnimatedValue)
    animate(props: Array<string>, from: Object, to: Object, on: Animated.AnimatedValue)
    animate(prop: string, from: number, to: number, on: AnimatedValue)
    

    It expects the AnimatedValue to animate from 0 to 1.

    Here it is used in a component:

    import React from 'react'
    import { View, Animated } from 'react-native'
    import Uranium, { animate } from 'uranium'
    
    class ExpandOnPress extends Component {
      state = { expanded: false }
    
      _expandAV = new Animated.Value(0)
    
      _toggleExpanded() {
        Animated.timing(this._expandAV, {
          toValue: this.state.expanded ? 0 : 1,
          duration: 300,
        })
    
        this.setState({ expanded: !this.state.expanded })
      }
    
      render() {
        return (
          <View
            css={[
              styles.base,
              animate(styles.notExpanded, styles.expanded, this._expandAV),
              animate('opacity', 0.25, 1, this._expandAV)
            ]}
            onPress={this._toggleExpanded} />
        )
      }
    }
    
    export default Uranium(ExpandOnClick)
    
    const styles = {
      base: {
        backgroundColor: 'blue',
      },
    
      notExpanded: {
        width: 20,
        height: 20,
      },
    
      expanded: {
        width: 40,
        height: 40,
      }
    }
    

    This will animate all the styles on styles.notExpanded to all the styles on styles.expanded on the _expandAV AnimatedValue.

    So width will animate from 20 to 40, and height will also animate from 20 to 40.

    This also animates opacity from '0.25' to '1'.

    If styles.notExpanded contained a property you didn't want to animate, like borderRadius, you could have specified specific values to animate:

    animate(['width', 'height'], styles.notExpanded, styles.expanded, this._expandAV)
    
    ...
    
    styles = {
      notExpanded: {
        width: 20,
        height: 20,
        borderRadius: 2,
      },
    
      expanded: {
        width: 40,
        height: 40,
      }
    }
    

    Note! The AnimatedValue must go from 0 to 1 (and vice versa).

    Inspiration

    Many thanks to the creators of Radium who inspired this library.

    In fact, the name is a play on Radium: Universal Radium = Uranium :)

    Connect

    Follow the creator on Twitter, @TuckerConnelly

    License

    MIT

    Show All