diff --git a/examples/components/App.js b/examples/components/App.js
new file mode 100644
index 00000000..cefd87d7
--- /dev/null
+++ b/examples/components/App.js
@@ -0,0 +1,198 @@
+import GridView from './GridView'
+import Heading from './Heading'
+import MediaQueryWidget from './MediaQueryWidget'
+import React, { Image, StyleSheet, Text, TextInput, Touchable, View } from '../../src'
+
+export default class App extends React.Component {
+ static propTypes = {
+ mediaQuery: React.PropTypes.object,
+ style: View.propTypes.style
+ }
+
+ render() {
+ const { mediaQuery } = this.props
+ const rootStyles = {
+ ...(styles.root.common),
+ ...(mediaQuery.small.matches && styles.root.mqSmall),
+ ...(mediaQuery.large.matches && styles.root.mqLarge)
+ }
+
+ return (
+
+ React Native for Web
+ React Native Web takes the core components from React
+ Native and brings them to the web. These components provide
+ simple building blocks – touch handling, flexbox layout,
+ scroll views – from which more complex components and apps can be
+ constructed.
+
+
+
+ Image
+ Inner content}
+ defaultSource={{
+ uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAIAAAAP3aGbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wkGESkdPWMDggAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAD5UlEQVR42u3UMQ0AAAgEMcC/x7eCCgaSVsIN10kK4IORADAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAswLAkAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAALi04UQW9HF910gAAAABJRU5ErkJggg=='
+ }}
+ onError={(e) => { console.log('Image.onError', e) }}
+ onLoad={(e) => { console.log('Image.onLoad', e) }}
+ onLoadEnd={() => { console.log('Image.onLoadEnd') }}
+ onLoadStart={() => { console.log('Image.onLoadStart') }}
+ resizeMode={'contain'}
+ source={{
+ height: 400,
+ uri: 'http://facebook.github.io/react/img/logo_og.png',
+ width: 400
+ }}
+ style={{
+ borderWidth: '5px'
+ }}
+ testID='Example.image'
+ />
+
+ Text
+ { console.log('Text.onPress', e) }}
+ testID={'Example.text'}
+ >
+ PRESS ME.
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vel
+ lectus urna. Aliquam vitae justo porttitor, aliquam erat nec,
+ venenatis diam. Vivamus facilisis augue non urna mattis ultricies.
+ Suspendisse et vulputate enim, a maximus nulla. Vivamus imperdiet
+ hendrerit consequat. Aliquam lorem quam, elementum eget ex nec,
+ ultrices porttitor nibh. Nulla pellentesque urna leo, a aliquet elit
+ rhoncus a. Aenean ultricies, nunc a interdum dictum, dui odio
+ scelerisque mauris, a fringilla elit ligula vel sem. Sed vel aliquet
+ ipsum, sed rhoncus velit. Vivamus commodo pretium libero id placerat.
+
+
+ TRUNCATED after 1 line.
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vel
+ lectus urna. Aliquam vitae justo porttitor, aliquam erat nec,
+ venenatis diam. Vivamus facilisis augue non urna mattis ultricies.
+ Suspendisse et vulputate enim, a maximus nulla. Vivamus imperdiet
+ hendrerit consequat.
+
+
+ TextInput
+ { console.log('TextInput.onBlur', e) }}
+ onChange={(e) => { console.log('TextInput.onChange', e) }}
+ onChangeText={(e) => { console.log('TextInput.onChangeText', e) }}
+ onFocus={(e) => { console.log('TextInput.onFocus', e) }}
+ onSelectionChange={(e) => { console.log('TextInput.onSelectionChange', e) }}
+ />
+
+
+
+
+
+
+
+
+ Touchable
+ { console.log('Touchable.onLongPress', e) }}
+ onPress={(e) => { console.log('Touchable.onPress', e) }}
+ onPressIn={(e) => { console.log('Touchable.onPressIn', e) }}
+ onPressOut={(e) => { console.log('Touchable.onPressOut', e) }}
+ >
+
+ Touchable area (press, long press)
+
+
+
+ View
+ Default layout
+
+ {[ 1, 2, 3, 4, 5, 6 ].map((item, i) => {
+ return (
+
+ {item}
+
+ )
+ })}
+
+
+ Row layout
+
+ {[ 1, 2, 3, 4, 5, 6 ].map((item, i) => {
+ return (
+
+ {item}
+
+ )
+ })}
+
+
+ pointerEvents
+
+ {['box-none', 'box-only', 'none'].map((value, i) => {
+ return (
+
+ )
+ })}
+
+
+ )
+ }
+}
+
+const styles = StyleSheet.create({
+ root: {
+ common: {
+ margin: '0 auto'
+ },
+ mqSmall: {
+ maxWidth: '400px'
+ },
+ mqLarge: {
+ maxWidth: '600px'
+ }
+ },
+ row: {
+ flexDirection: 'row',
+ flexWrap: 'wrap'
+ },
+ box: {
+ alignItems: 'center',
+ flexGrow: 1,
+ justifyContent: 'center',
+ borderWidth: '1px'
+ },
+ boxFull: {
+ width: '100%'
+ },
+ pointerEventsBox: {
+ alignItems: 'center',
+ borderWidth: '1px',
+ flexGrow: 1,
+ height: '100px',
+ justifyContent: 'center'
+ },
+ touchableArea: {
+ alignItems: 'center',
+ borderWidth: 1,
+ height: '200px',
+ justifyContent: 'center'
+ }
+})
diff --git a/examples/components/GridView.js b/examples/components/GridView.js
new file mode 100644
index 00000000..79ae086d
--- /dev/null
+++ b/examples/components/GridView.js
@@ -0,0 +1,67 @@
+import React, { StyleSheet, View } from '../../src'
+
+const { Component, PropTypes } = React
+
+const styles = StyleSheet.create({
+ root: {
+ overflow: 'hidden'
+ },
+ contentContainer: {
+ flexDirection: 'row',
+ flexGrow: 1
+ },
+ // distribute all space (rather than extra space)
+ column: {
+ flexBasis: '0%'
+ }
+})
+
+export default class GridView extends Component {
+ static propTypes = {
+ alley: PropTypes.string,
+ children: PropTypes.oneOfType([
+ PropTypes.element,
+ PropTypes.arrayOf(PropTypes.element)
+ ]),
+ gutter: PropTypes.string,
+ style: PropTypes.object
+ }
+
+ static defaultProps = {
+ alley: '0',
+ gutter: '0'
+ }
+
+ render() {
+ const { alley, children, gutter, style, ...other } = this.props
+
+ const rootStyle = {
+ ...style,
+ ...styles.root
+ }
+
+ const contentContainerStyle = {
+ ...styles.contentContainer,
+ margin: `0 calc(-0.5 * ${alley})`,
+ padding: `0 ${gutter}`
+ }
+
+ const newChildren = React.Children.map(children, (child) => {
+ return child && React.cloneElement(child, {
+ style: {
+ ...child.props.style,
+ ...styles.column,
+ margin: `0 calc(0.5 * ${alley})`
+ }
+ })
+ })
+
+ return (
+
+
+ {newChildren}
+
+
+ )
+ }
+}
diff --git a/examples/components/Heading.js b/examples/components/Heading.js
new file mode 100644
index 00000000..5571af2c
--- /dev/null
+++ b/examples/components/Heading.js
@@ -0,0 +1,31 @@
+import React from 'react'
+import { StyleSheet, Text } from '../../src'
+
+const headingStyles = StyleSheet.create({
+ size: {
+ xlarge: {
+ fontSize: '2rem',
+ marginBottom: '1em'
+ },
+ large: {
+ fontSize: '1.5rem',
+ marginBottom: '1em',
+ marginTop: '1em'
+ },
+ normal: {
+ fontSize: '1.25rem',
+ marginBottom: '0.5em',
+ marginTop: '0.5em'
+ }
+ }
+})
+
+const Heading = ({ children, size = 'normal' }) => (
+
+)
+
+export default Heading
diff --git a/examples/components/MediaQueryWidget.js b/examples/components/MediaQueryWidget.js
new file mode 100644
index 00000000..c7c057ff
--- /dev/null
+++ b/examples/components/MediaQueryWidget.js
@@ -0,0 +1,36 @@
+import React, { StyleSheet, Text, View } from '../../src'
+
+const styles = StyleSheet.create({
+ root: {
+ alignItems: 'center',
+ borderWidth: 1,
+ margin: '10px 0',
+ padding: 10,
+ textAlign: 'center'
+ },
+ heading: {
+ fontWeight: 'bold',
+ padding: 5
+ }
+})
+
+const MediaQueryWidget = ({ mediaQuery = {} }) => {
+ const active = Object.keys(mediaQuery).reduce((active, alias) => {
+ if (mediaQuery[alias].matches) {
+ active = {
+ alias,
+ mql: mediaQuery[alias]
+ }
+ }
+ return active
+ }, {})
+
+ return (
+
+ Active Media Query
+ {`"${active.alias}"`} {active.mql.media}
+
+ )
+}
+
+export default MediaQueryWidget
diff --git a/examples/index.js b/examples/index.js
index 2f6ccf98..12f2d8e3 100644
--- a/examples/index.js
+++ b/examples/index.js
@@ -1,210 +1,22 @@
-import React, { Image, StyleSheet, Text, TextInput, Touchable, View } from '../src'
+import { MediaProvider, matchMedia } from 'react-media-queries'
+import App from './components/App'
+import createGetter from 'react-media-queries/lib/createMediaQueryGetter'
+import createListener from 'react-media-queries/lib/createMediaQueryListener'
+import React, { StyleSheet } from '../src'
import ReactDOM from 'react-dom'
-const Heading = ({ children, size = 'normal' }) => (
-
+const mediaQueries = {
+ small: '(min-width: 300px)',
+ medium: '(min-width: 400px)',
+ large: '(min-width: 500px)'
+}
+const ResponsiveApp = matchMedia()(App)
+
+ReactDOM.render(
+
+
+ ,
+ document.getElementById('react-root')
)
-const headingStyles = StyleSheet.create({
- size: {
- xlarge: {
- fontSize: '2rem',
- marginBottom: '1em'
- },
- large: {
- fontSize: '1.5rem',
- marginBottom: '1em',
- marginTop: '1em'
- },
- normal: {
- fontSize: '1.25rem',
- marginBottom: '0.5em',
- marginTop: '0.5em'
- }
- }
-})
-
-class Example extends React.Component {
- static propTypes = {
- style: View.propTypes.style
- }
-
- render() {
- return (
-
- React Native Web
- React Native Web takes the core components from React
- Native and brings them to the web. These components provide
- simple building blocks – touch handling, flexbox layout,
- scroll views – from which more complex components and apps can be
- constructed.
-
- Image
- Inner content}
- defaultSource={{
- uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAIAAAAP3aGbAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wkGESkdPWMDggAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAD5UlEQVR42u3UMQ0AAAgEMcC/x7eCCgaSVsIN10kK4IORADAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAswLAkAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAADAvAsADDAjAsAMMCDAvAsAAMCzAsAMMCMCzAsAAMC8CwAMMCMCzAsAAMC8CwAMMCMCwAwwIMC8CwAAwLMCwAwwIwLMCwAAwLwLAAwwIwLADDAgwLwLAADAswLADDAjAswLAALi04UQW9HF910gAAAABJRU5ErkJggg=='
- }}
- onError={(e) => { console.log('Image.onError', e) }}
- onLoad={(e) => { console.log('Image.onLoad', e) }}
- onLoadEnd={() => { console.log('Image.onLoadEnd') }}
- onLoadStart={() => { console.log('Image.onLoadStart') }}
- resizeMode={'contain'}
- source={{
- height: 400,
- uri: 'http://facebook.github.io/react/img/logo_og.png',
- width: 400
- }}
- style={{
- borderWidth: '5px'
- }}
- testID='Example.image'
- />
-
- Text
- { console.log('Text.onPress', e) }}
- testID={'Example.text'}
- >
- PRESS ME.
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vel
- lectus urna. Aliquam vitae justo porttitor, aliquam erat nec,
- venenatis diam. Vivamus facilisis augue non urna mattis ultricies.
- Suspendisse et vulputate enim, a maximus nulla. Vivamus imperdiet
- hendrerit consequat. Aliquam lorem quam, elementum eget ex nec,
- ultrices porttitor nibh. Nulla pellentesque urna leo, a aliquet elit
- rhoncus a. Aenean ultricies, nunc a interdum dictum, dui odio
- scelerisque mauris, a fringilla elit ligula vel sem. Sed vel aliquet
- ipsum, sed rhoncus velit. Vivamus commodo pretium libero id placerat.
-
-
- TRUNCATED after 1 line.
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vel
- lectus urna. Aliquam vitae justo porttitor, aliquam erat nec,
- venenatis diam. Vivamus facilisis augue non urna mattis ultricies.
- Suspendisse et vulputate enim, a maximus nulla. Vivamus imperdiet
- hendrerit consequat.
-
-
- TextInput
- { console.log('TextInput.onBlur', e) }}
- onChange={(e) => { console.log('TextInput.onChange', e) }}
- onChangeText={(e) => { console.log('TextInput.onChangeText', e) }}
- onFocus={(e) => { console.log('TextInput.onFocus', e) }}
- onSelectionChange={(e) => { console.log('TextInput.onSelectionChange', e) }}
- />
-
-
-
-
-
-
-
-
- Touchable
- { console.log('Touchable.onLongPress', e) }}
- onPress={(e) => { console.log('Touchable.onPress', e) }}
- onPressIn={(e) => { console.log('Touchable.onPressIn', e) }}
- onPressOut={(e) => { console.log('Touchable.onPressOut', e) }}
- >
-
- Touchable area (press, long press)
-
-
-
- View
- Default layout
-
- {[ 1, 2, 3, 4, 5, 6 ].map((item, i) => {
- return (
-
- {item}
-
- )
- })}
-
-
- Row layout
-
- {[ 1, 2, 3, 4, 5, 6 ].map((item, i) => {
- return (
-
- {item}
-
- )
- })}
-
-
- pointerEvents
-
- {['box-none', 'box-only', 'none'].map((value, i) => {
- return (
-
- )
- })}
-
-
- )
- }
-}
-
-const styles = StyleSheet.create({
- root: {
- maxWidth: '600px',
- margin: '0 auto'
- },
- row: {
- flexDirection: 'row',
- flexWrap: 'wrap'
- },
- box: {
- alignItems: 'center',
- flexGrow: 1,
- justifyContent: 'center',
- borderWidth: '1px'
- },
- boxFull: {
- width: '100%'
- },
- pointerEventsBox: {
- alignItems: 'center',
- borderWidth: '1px',
- flexGrow: 1,
- height: '100px',
- justifyContent: 'center'
- },
- touchableArea: {
- alignItems: 'center',
- borderWidth: 1,
- height: '200px',
- justifyContent: 'center'
- }
-})
-
-ReactDOM.render(, document.getElementById('react-root'))
-
document.getElementById('react-stylesheet').textContent = StyleSheet.renderToString()
diff --git a/package.json b/package.json
index 1172907f..ac5be6ad 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"react": "^0.14.0",
"react-addons-test-utils": "^0.14.0",
"react-dom": "^0.14.0",
+ "react-media-queries": "^2.0.0",
"webpack": "^1.12.2",
"webpack-dev-server": "^1.12.1"
},