mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-03-26 01:04:13 +08:00
Update README; add guides to docs
This commit is contained in:
197
README.md
197
README.md
@@ -2,114 +2,56 @@
|
||||
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
[![npm version][npm-image]][npm-url]
|
||||

|
||||

|
||||
|
||||
[React Native][react-native-url] components and APIs for the Web. Flexbox
|
||||
layout and JavaScript styling.
|
||||
|
||||
* [Discord: #react-native-web on reactiflux][discord-url]
|
||||
* [Gitter: react-native-web][gitter-url]
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Quick start](#quick-start)
|
||||
* [Overview](#overview)
|
||||
* [Example](#example)
|
||||
* [APIs](#apis)
|
||||
* [Components](#components)
|
||||
* [Contributing](#contributing)
|
||||
* [Thanks](#thanks)
|
||||
* [License](#license)
|
||||
[React Native][react-native-url] components and APIs for the Web.
|
||||
|
||||
## Quick start
|
||||
|
||||
You can [try the latest version on CodePen](http://codepen.io/necolas/pen/PZzwBR).
|
||||
|
||||
To install in your app:
|
||||
|
||||
```
|
||||
npm install --save react@0.14 react-dom@0.14 react-native-web
|
||||
```
|
||||
|
||||
Or [try it on CodePen](http://codepen.io/necolas/pen/PZzwBR).
|
||||
|
||||
Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
|
||||
|
||||
## Overview
|
||||
|
||||
### Importing
|
||||
This is a web implementation of React Native components and APIs. The React
|
||||
Native components are good web application building blocks, and provide a common
|
||||
foundation for component libraries.
|
||||
|
||||
All API's, components, and a Web-specific `React` are provided by the
|
||||
`react-native-web` module:
|
||||
|
||||
```js
|
||||
import React, { Image, StyleSheet, Text, View } from 'react-native-web'
|
||||
```
|
||||
|
||||
### Client-side rendering
|
||||
|
||||
Client-side rendering requires that you use the module's `React` export.
|
||||
`React.render` is a thin wrapper around `ReactDOM.render` that renders your
|
||||
application and the style sheet. Styles are updated if new bundles are loaded
|
||||
asynchronously.
|
||||
|
||||
```js
|
||||
// client.js
|
||||
import App from './components/App'
|
||||
import React from 'react-native-web'
|
||||
|
||||
React.render(<App />, document.getElementById('react-root'))
|
||||
```
|
||||
|
||||
### Server-side rendering
|
||||
|
||||
Server-side rendering is done by calling `React.renderToString` or
|
||||
`React.renderToStaticMarkup`, the output of both includes the style sheet.
|
||||
|
||||
```js
|
||||
// server.js
|
||||
import App from './components/App'
|
||||
import React from 'react-native-web'
|
||||
|
||||
const html = React.renderToString(<App />);
|
||||
|
||||
const Html = () => (
|
||||
<html>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta content="initial-scale=1,width=device-width" name="viewport" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="react-root" dangerouslySetInnerHTML={{ __html: html }} />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
```
|
||||
|
||||
### Styling
|
||||
|
||||
React Native for Web allows you to [define styles using
|
||||
JavaScript](docs/guides/style.md), either with inline styles or
|
||||
[`StyleSheet.create`](docs/apis/StyleSheet.md).
|
||||
|
||||
The `View` component makes it easy to build common layouts with flexbox, such
|
||||
as stacked and nested boxes with margin and padding. See this [guide to
|
||||
flexbox][flexbox-guide-url].
|
||||
|
||||
### Accessibility
|
||||
|
||||
The most common and best supported [accessibility
|
||||
features](docs/guides/accessibility.md) of the Web are leveraged through 4
|
||||
props available on most components: `accessible`, `accessibilityLabel`,
|
||||
`accessibilityLiveRegion`, and `accessibilityRole`.
|
||||
For example, the [`View`](docs/apis/View.md) component makes it easy to build
|
||||
common layouts with flexbox, such as stacked and nested boxes with margin and
|
||||
padding. And the [`StyleSheet`](docs/guides/style.md) API converts styles
|
||||
defined in JavaScript to "atomic" CSS.
|
||||
|
||||
## Example
|
||||
|
||||
More examples can be found in the [`examples` directory](examples).
|
||||
|
||||
```js
|
||||
import React, { Image, StyleSheet, Text, View } from 'react-native-web'
|
||||
import React, { AppRegistry, Image, StyleSheet, Text, View } from 'react-native'
|
||||
|
||||
// Components
|
||||
const Card = ({ children }) => <View style={styles.card}>{children}</View>
|
||||
const Title = ({ children }) => <Text style={styles.title}>{children}</Text>
|
||||
const Photo = ({ uri }) => <Image source={{ uri }} style={styles.image} />
|
||||
const App = () => (
|
||||
<Card>
|
||||
<Title>App Card</Title>
|
||||
<Photo uri="/some-photo.jpg" />
|
||||
</Card>
|
||||
)
|
||||
|
||||
// App registration and rendering
|
||||
AppRegistry.registerComponent('MyApp', () => App)
|
||||
AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-root') })
|
||||
|
||||
// Styles
|
||||
const styles = StyleSheet.create({
|
||||
card: {
|
||||
flexGrow: 1,
|
||||
@@ -121,73 +63,52 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
image: {
|
||||
height: 40,
|
||||
marginRight: 10,
|
||||
marginVertical: 10,
|
||||
width: 40
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## APIs
|
||||
## Documentation
|
||||
|
||||
### [`StyleSheet`](docs/apis/StyleSheet.md)
|
||||
Guides:
|
||||
|
||||
StyleSheet is a style abstraction that transforms inline styles to CSS on the
|
||||
client or the server. It provides a minimal CSS reset targeting elements and
|
||||
pseudo-elements beyond the reach of React inline styles.
|
||||
* [Accessibility](docs/guides/accessibility.md)
|
||||
* [Client and server rendering](docs/guides/rendering.md)
|
||||
* [Direct manipulation](docs/guides/direct-manipulation.md)
|
||||
* [Known issues](docs/guides/known-issues.md)
|
||||
* [React Native](docs/guides/react-native.md)
|
||||
* [Style](docs/guides/style.md)
|
||||
|
||||
## Components
|
||||
Exported modules:
|
||||
|
||||
### [`Image`](docs/components/Image.md)
|
||||
|
||||
An accessibile image component with support for image resizing, default image,
|
||||
and child content.
|
||||
|
||||
### [`ListView`](docs/components/ListView.md)
|
||||
|
||||
(TODO)
|
||||
|
||||
### [`ScrollView`](docs/components/ScrollView.md)
|
||||
|
||||
A scrollable view with event throttling.
|
||||
|
||||
### [`Text`](docs/components/Text.md)
|
||||
|
||||
Displays text inline and supports basic press handling.
|
||||
|
||||
### [`TextInput`](docs/components/TextInput.md)
|
||||
|
||||
Accessible single- and multi-line text input via a keyboard.
|
||||
|
||||
### [`Touchable`](docs/components/Touchable.md)
|
||||
|
||||
Touch bindings for press and long press.
|
||||
|
||||
### [`View`](docs/components/View.md)
|
||||
|
||||
The fundamental UI building block using flexbox for layout.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [contribution guidelines][contributing-url]. Contributions are
|
||||
welcome!
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to current and past members of the React and React Native teams (in
|
||||
particular Vjeux and Pete Hunt).
|
||||
|
||||
Thanks to [react-tappable](https://github.com/JedWatson/react-tappable) for
|
||||
backing the current implementation of `Touchable`.
|
||||
* Components
|
||||
* [`ActivityIndicator`](docs/components/ActivityIndicator.md)
|
||||
* [`Image`](docs/components/Image.md)
|
||||
* [`ListView`](docs/components/ListView.md)
|
||||
* [`Portal`](docs/components/Portal.md)
|
||||
* [`ScrollView`](docs/components/ScrollView.md)
|
||||
* [`Text`](docs/components/Text.md)
|
||||
* [`TextInput`](docs/components/TextInput.md)
|
||||
* [`TouchableHighlight`](docs/components/TouchableHighlight.md)
|
||||
* [`TouchableOpacity`](docs/components/TouchableOpacity.md)
|
||||
* [`TouchableWithoutFeedback`](docs/components/TouchableWithoutFeedback.md)
|
||||
* [`View`](docs/components/View.md)
|
||||
* APIs
|
||||
* [`AppRegistry`](docs/apis/AppRegistry.md)
|
||||
* [`AppState`](docs/apis/AppState.md)
|
||||
* [`AsyncStorage`](docs/apis/AsyncStorage.md)
|
||||
* [`Dimensions`](docs/apis/Dimensions.md)
|
||||
* [`NativeMethods`](docs/apis/NativeMethods.md)
|
||||
* [`NetInfo`](docs/apis/NetInfo.md)
|
||||
* [`PixelRatio`](docs/apis/PixelRatio.md)
|
||||
* [`Platform`](docs/apis/Platform.md)
|
||||
* [`StyleSheet`](docs/apis/StyleSheet.md)
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2015 Nicolas Gallagher. Released under the [MIT
|
||||
license](http://www.opensource.org/licenses/mit-license.php).
|
||||
React Native for Web is [BSD licensed](LICENSE).
|
||||
|
||||
[contributing-url]: https://github.com/necolas/react-native-web/blob/master/CONTRIBUTING.md
|
||||
[discord-url]: http://join.reactiflux.com
|
||||
[flexbox-guide-url]: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
|
||||
[gitter-url]: https://gitter.im/necolas/react-native-web
|
||||
[npm-image]: https://badge.fury.io/js/react-native-web.svg
|
||||
[npm-url]: https://npmjs.org/package/react-native-web
|
||||
[react-native-url]: https://facebook.github.io/react-native/
|
||||
|
||||
@@ -27,5 +27,10 @@ module.exports = {
|
||||
}),
|
||||
new webpack.optimize.DedupePlugin(),
|
||||
new webpack.optimize.OccurenceOrderPlugin()
|
||||
]
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'react-native': '../../src'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@ Remove a handler by passing the change event `type` and the `handler`.
|
||||
|
||||
## Examples
|
||||
|
||||
To see the current state, you can check `AppStateIOS.currentState`, which will
|
||||
be kept up-to-date. This example will only ever appear to say "Current state
|
||||
is: active" because the app is only visible to the user when in the `active`
|
||||
state, and the null state will happen only momentarily.
|
||||
To see the current state, you can check `AppState.currentState`, which will be
|
||||
kept up-to-date. This example will only ever appear to say "Current state is:
|
||||
active" because the app is only visible to the user when in the `active` state,
|
||||
and the null state will happen only momentarily.
|
||||
|
||||
```js
|
||||
class Example extends React.Component {
|
||||
|
||||
@@ -9,12 +9,13 @@ The most common and best supported accessibility features of the Web are
|
||||
exposed as the props: `accessible`, `accessibilityLabel`,
|
||||
`accessibilityLiveRegion`, and `accessibilityRole`.
|
||||
|
||||
React Native for Web does not provide a way to directly control the rendered
|
||||
HTML element. The `accessibilityRole` prop is used to infer an [analogous HTML
|
||||
element][html-aria-url] to use in addition, where possible. While this may
|
||||
contradict some ARIA recommendations, it also helps avoid certain HTML5
|
||||
conformance errors and accessibility anti-patterns (e.g., giving a `heading`
|
||||
role to a `button` element).
|
||||
React Native for Web does not provide a way to directly control the type of the
|
||||
rendered HTML element. The `accessibilityRole` prop is used to infer an
|
||||
[analogous HTML element][html-aria-url] to use in addition to the resulting
|
||||
ARIA `role`, where possible. While this may contradict some ARIA
|
||||
recommendations, it also helps avoid certain HTML5 conformance errors and
|
||||
accessibility anti-patterns (e.g., giving a `heading` role to a `button`
|
||||
element).
|
||||
|
||||
For example:
|
||||
|
||||
@@ -24,7 +25,8 @@ For example:
|
||||
* `<Text accessibilityRole='link' href='/' />` => `<a role='link' href='/' />`.
|
||||
* `<View accessibilityRole='main' />` => `<main role='main' />`.
|
||||
|
||||
See the component documentation for more details.
|
||||
Other ARIA properties should be set via [direct
|
||||
manipulation](./direct-manipulation.md).
|
||||
|
||||
[aria-in-html-url]: https://w3c.github.io/aria-in-html/
|
||||
[html-accessibility-url]: http://www.html5accessibility.com/
|
||||
|
||||
115
docs/guides/direct-manipulation.md
Normal file
115
docs/guides/direct-manipulation.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Direct manipulation
|
||||
|
||||
It is sometimes necessary to make changes directly to a component without using
|
||||
state/props to trigger a re-render of the entire subtree – in the browser, this
|
||||
is done by directly modifying a DOM node. `setNativeProps` is the React Native
|
||||
equivalent to setting properties directly on a DOM node. Use direct
|
||||
manipulation when frequent re-rendering creates a performance bottleneck Direct
|
||||
manipulation will not be a tool that you reach for frequently.
|
||||
|
||||
## `setNativeProps` and `shouldComponentUpdate`
|
||||
|
||||
`setNativeProps` is imperative and stores state in the native layer (DOM,
|
||||
UIView, etc.) and not within your React components, which makes your code more
|
||||
difficult to reason about. Before you use it, try to solve your problem with
|
||||
`setState` and `shouldComponentUpdate`.
|
||||
|
||||
## Avoiding conflicts with the render function
|
||||
|
||||
If you update a property that is also managed by the render function, you might
|
||||
end up with some unpredictable and confusing bugs because anytime the component
|
||||
re-renders and that property changes, whatever value was previously set from
|
||||
`setNativeProps` will be completely ignored and overridden.
|
||||
|
||||
## Why use `setNativeProps` on Web?
|
||||
|
||||
Using `setNativeProps` in web-specific code is required when making changes to
|
||||
`className` or `style`, as these properties are controlled by React Native for
|
||||
Web and setting them directly may cause unintended rendering issues.
|
||||
|
||||
```js
|
||||
setOpacityTo(value) {
|
||||
this._childElement.setNativeProps({
|
||||
style: { opacity: value }
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
## Composite components and `setNativeProps`
|
||||
|
||||
Composite components are not backed by a DOM node, so you cannot call
|
||||
`setNativeProps` on them. Consider this example:
|
||||
|
||||
```js
|
||||
const MyButton = (props) => (
|
||||
<View>
|
||||
<Text>{props.label}</Text>
|
||||
</View>
|
||||
)
|
||||
|
||||
const App = () => (
|
||||
<TouchableOpacity>
|
||||
<MyButton label="Press me!" />
|
||||
</TouchableOpacity>
|
||||
)
|
||||
```
|
||||
|
||||
If you run this you will immediately see this error: `Touchable` child must
|
||||
either be native or forward `setNativeProps` to a native component. This occurs
|
||||
because `MyButton` isn't directly backed by a native view whose opacity should
|
||||
be set. You can think about it like this: if you define a component with
|
||||
`React.Component/createClass` you would not expect to be able to set a style
|
||||
prop on it and have that work - you would need to pass the style prop down to a
|
||||
child, unless you are wrapping a native component. Similarly, we are going to
|
||||
forward `setNativeProps` to a native-backed child component.
|
||||
|
||||
## Forward `setNativeProps` to a child
|
||||
|
||||
All we need to do is provide a `setNativeProps` method on our component that
|
||||
calls `setNativeProps` on the appropriate child with the given arguments.
|
||||
|
||||
```js
|
||||
class MyButton extends React.Component {
|
||||
setNativeProps(nativeProps) {
|
||||
this._root.setNativeProps(nativeProps)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View ref={component => this._root = component}>
|
||||
<Text>{this.props.label}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can now use `MyButton` inside of `TouchableOpacity`!
|
||||
|
||||
## `setNativeProps` to clear `TextInput` value
|
||||
|
||||
Another very common use case of `setNativeProps` is to clear the value of a
|
||||
`TextInput`. For example, the following code demonstrates clearing the input
|
||||
when you tap a button:
|
||||
|
||||
```js
|
||||
class App extends React.Component {
|
||||
_handlePress() {
|
||||
this._textInput.setNativeProps({ text: '' })
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<TextInput
|
||||
ref={component => this._textInput = component}
|
||||
style={styles.textInput}
|
||||
/>
|
||||
<TouchableOpacity onPress={this._handlePress.bind(this)}>
|
||||
<Text>Clear text</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
28
docs/guides/known-issues.md
Normal file
28
docs/guides/known-issues.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Known issues
|
||||
|
||||
## Missing modules and Views
|
||||
|
||||
This is an initial release of React Native for Web, therefore, not all of the
|
||||
views present on iOS/Android are released on Web. We are very much interested in
|
||||
the community's feedback on the next set of modules and views.
|
||||
|
||||
Not all the modules or views for iOS/Android can be implemented on Web. In some
|
||||
cases it will be necessary to use a Web counterpart.
|
||||
|
||||
## Missing component props
|
||||
|
||||
There are properties that do not work across all platforms. All web-specific
|
||||
props are annotated with `(web)` in the documentaiton.
|
||||
|
||||
## Platform parity
|
||||
|
||||
There are some known issues in React Native where APIs could be made more
|
||||
consistent between platforms. For example, React Native for Web includes
|
||||
`ActivityIndicator` and a horizontal `ProgressBar`.
|
||||
|
||||
Other parts of React Native, such as the `Animated` and `PanResponder` APIs,
|
||||
are highly complex and have not yet been ported to React Native for Web. Given
|
||||
the difficulties keeping these APIs in sync with React Native, we'd prefer the
|
||||
APIs to be published as separate npm packages. If not, we will consider a web
|
||||
implementation, possibly using the [Web Animations
|
||||
API/polyfill](https://github.com/web-animations/web-animations-js)
|
||||
40
docs/guides/react-native.md
Normal file
40
docs/guides/react-native.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# React Native
|
||||
|
||||
This is an experimental feature to support: using community-developed React
|
||||
Native components on the Web; and rendering React Native apps to Web.
|
||||
|
||||
Use a module loader that supports package aliases (e.g., webpack), and alias
|
||||
`react-native` to `react-native-web`.
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
|
||||
module.exports = {
|
||||
resolve: {
|
||||
alias: {
|
||||
'react-native': 'react-native-web'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Web-specific implementations can use the `*.web.js` naming pattern, which
|
||||
webpack will resolve.
|
||||
|
||||
Minor platform differences can use the `Platform` module.
|
||||
|
||||
```js
|
||||
import { AppRegistry, Platform, StyleSheet } from 'react-native'
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
height: (Platform.OS === 'web') ? 200 : 100
|
||||
})
|
||||
|
||||
AppRegistry.registerComponent('MyApp', () => MyApp)
|
||||
|
||||
if (Platform.OS === 'web') {
|
||||
AppRegistry.runApplication('MyApp', {
|
||||
rootTag: document.getElementById('react-root')
|
||||
});
|
||||
}
|
||||
```
|
||||
57
docs/guides/rendering.md
Normal file
57
docs/guides/rendering.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Client and Server rendering
|
||||
|
||||
## Client-side rendering
|
||||
|
||||
```js
|
||||
// client.js
|
||||
|
||||
import React, { AppRegistry } from 'react-native'
|
||||
import MyApp from './MyApp'
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerApp('MyApp', () => MyApp)
|
||||
|
||||
// mount the app within the `rootTag` and run it
|
||||
AppRegistry.runApplication('MyApp', { initialProps, rootTag: document.getElementById('react-root') })
|
||||
|
||||
// DOM render
|
||||
React.render(<div />, document.getElementById('sidebar-app'))
|
||||
|
||||
// Server render
|
||||
React.renderToString(<div />)
|
||||
```
|
||||
|
||||
## Server-side rendering
|
||||
|
||||
Pre-rendering React apps on the server is a key feature for Web applications.
|
||||
React Native for Web extends `AppRegistry` to provide support for server-side
|
||||
rendering.
|
||||
|
||||
```js
|
||||
// server.js
|
||||
|
||||
import React, { AppRegistry } from 'react-native'
|
||||
import MyApp from './MyApp'
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerApp('MyApp', () => MyApp)
|
||||
|
||||
// prerender the app
|
||||
const { html, style } = AppRegistry.prerenderApplication('MyApp', { initialProps })
|
||||
|
||||
// construct full page markup
|
||||
const HtmlShell = (html, style) => (
|
||||
<html>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta content="initial-scale=1,width=device-width" name="viewport" />
|
||||
{style}
|
||||
</head>
|
||||
<body>
|
||||
<div id="react-root" dangerouslySetInnerHTML={{ __html: html }} />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
||||
React.renderToStaticMarkup(<HtmlShell html={html} style={style} />)
|
||||
```
|
||||
@@ -42,7 +42,7 @@ documentation of individual components.
|
||||
|
||||
## Using styles
|
||||
|
||||
All the core components accept a `style` attribute.
|
||||
All the React Native components accept a `style` attribute.
|
||||
|
||||
```js
|
||||
<Text style={styles.text} />
|
||||
@@ -52,20 +52,27 @@ All the core components accept a `style` attribute.
|
||||
A common pattern is to conditionally add style based on a condition:
|
||||
|
||||
```js
|
||||
// either
|
||||
<View style={{
|
||||
...styles.base,
|
||||
...(this.state.active && styles.active)
|
||||
}} />
|
||||
|
||||
// or
|
||||
<View style={[
|
||||
styles.base,
|
||||
this.state.active && styles.active
|
||||
]} />
|
||||
```
|
||||
|
||||
## Composing styles
|
||||
|
||||
In order to let a call site customize the style of your component children, you
|
||||
can pass styles around. Use `View.propTypes.style` and `Text.propTypes.style` in
|
||||
order to make sure only styles are being passed.
|
||||
order to make sure only valid styles are being passed.
|
||||
|
||||
```js
|
||||
export default class List extends React.Component {
|
||||
class List extends React.Component {
|
||||
static propTypes = {
|
||||
style: View.propTypes.style,
|
||||
elementStyle: View.propTypes.style,
|
||||
@@ -108,11 +115,11 @@ class List extends React.Component {
|
||||
return (
|
||||
<View
|
||||
children={children}
|
||||
style={{
|
||||
...this.props.style,
|
||||
style={[
|
||||
this.props.style,
|
||||
// override border-color when scrolling
|
||||
...(isScrolling && { borderColor: 'transparent' })
|
||||
}}
|
||||
isScrolling && { borderColor: 'transparent' }
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -125,19 +132,17 @@ class List extends React.Component {
|
||||
it does not concern itself with _where_ or _when_ those styles are applied to
|
||||
elements.
|
||||
|
||||
Changing styles in response to device adaptation can be controlled using
|
||||
JavaScript Media Query API's. There are several React libraries that provide a
|
||||
means to do this, e.g.,
|
||||
There are various React libraries wrapping JavaScript Media Query API's, e.g.,
|
||||
[react-media-queries](https://github.com/bloodyowl/react-media-queries),
|
||||
[media-query-fascade](https://github.com/tanem/media-query-facade), or
|
||||
[react-responsive](https://github.com/contra/react-responsive). This approach
|
||||
has the benefit of co-locating breakpoint-specific DOM and style changes.
|
||||
[react-responsive](https://github.com/contra/react-responsive). This has the
|
||||
benefit of co-locating breakpoint-specific DOM and style changes.
|
||||
|
||||
## Pseudo-classes and pseudo-elements
|
||||
|
||||
Pseudo-classes like `:hover` and `:focus` can be implemented with the `onHover`
|
||||
and `onFocus` events. Pseudo-elements are not supported; elements should be
|
||||
used instead.
|
||||
Pseudo-classes like `:hover` and `:focus` can be implemented with the events
|
||||
(e.g. `onFocus`). Pseudo-elements are not supported; elements should be used
|
||||
instead.
|
||||
|
||||
## How it works
|
||||
|
||||
@@ -149,7 +154,7 @@ corresponding `className`'s.
|
||||
By doing this, the total size of the generated CSS is determined by the
|
||||
total number of unique declarations (rather than the total number of rules in
|
||||
the application), making it viable to inline the style sheet when pre-rendering
|
||||
on the server.
|
||||
on the server. Styles are updated if new module bundle are loaded asynchronously.
|
||||
|
||||
JavaScript definition:
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import GridView from './GridView'
|
||||
import Heading from './Heading'
|
||||
import MediaQueryWidget from './MediaQueryWidget'
|
||||
import React, { Image, StyleSheet, ScrollView, Text, TextInput, Touchable, View } from '../../src'
|
||||
import React, { Image, StyleSheet, ScrollView, Text, TextInput, TouchableHighlight, View } from 'react-native'
|
||||
|
||||
export default class App extends React.Component {
|
||||
static propTypes = {
|
||||
@@ -25,7 +25,8 @@ export default class App extends React.Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<View accessibilityRole='main' style={rootStyles}>
|
||||
<ScrollView accessibilityRole='main'>
|
||||
<View style={rootStyles}>
|
||||
<Heading size='xlarge'>React Native for Web</Heading>
|
||||
<Text>React Native Web takes the core components from <Text
|
||||
accessibilityRole='link' href='https://facebook.github.io/react-native/'>React
|
||||
@@ -107,7 +108,7 @@ export default class App extends React.Component {
|
||||
/>
|
||||
|
||||
<Heading size='large'>Touchable</Heading>
|
||||
<Touchable
|
||||
<TouchableHighlight
|
||||
accessibilityLabel={'Touchable element'}
|
||||
activeHighlight='lightblue'
|
||||
activeOpacity={0.8}
|
||||
@@ -119,7 +120,7 @@ export default class App extends React.Component {
|
||||
<View style={styles.touchableArea}>
|
||||
<Text>Touchable area (press, long press)</Text>
|
||||
</View>
|
||||
</Touchable>
|
||||
</TouchableHighlight>
|
||||
|
||||
<Heading size='large'>View</Heading>
|
||||
<Heading>Default layout</Heading>
|
||||
@@ -205,7 +206,8 @@ export default class App extends React.Component {
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 from '../src'
|
||||
import React, { AppRegistry } from '../src'
|
||||
|
||||
const mediaQueries = {
|
||||
small: '(min-width: 300px)',
|
||||
@@ -10,10 +10,14 @@ const mediaQueries = {
|
||||
large: '(min-width: 500px)'
|
||||
}
|
||||
const ResponsiveApp = matchMedia()(App)
|
||||
|
||||
React.render(
|
||||
const WrappedApp = () => (
|
||||
<MediaProvider getMedia={createGetter(mediaQueries)} listener={createListener(mediaQueries)}>
|
||||
<ResponsiveApp />
|
||||
</MediaProvider>,
|
||||
document.getElementById('react-root')
|
||||
</MediaProvider>
|
||||
)
|
||||
|
||||
AppRegistry.registerComponent('Example', () => WrappedApp)
|
||||
|
||||
AppRegistry.runApplication('Example', {
|
||||
rootTag: document.getElementById('react-root')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user