Improve project introduction and guides

Adopt the structure of the React README and improve the contribution
guidelines to include Facebook's CoC. Fix various links following the
move to a monorepo.
This commit is contained in:
Nicolas Gallagher
2017-12-26 09:01:00 +00:00
parent f52a851972
commit 1776891736
8 changed files with 297 additions and 402 deletions

View File

@@ -17,7 +17,7 @@ Fork, then clone the repo:
git clone https://github.com/your-username/react-native-web.git
```
Install dependencies (requires [yarn](https://yarnpkg.com/en/docs/install):
Install dependencies (requires [yarn](https://yarnpkg.com/en/docs/install)):
```
yarn
@@ -113,13 +113,13 @@ that we won't want to accept.
## Pull requests
**Before submitting a pull request,** please make sure the following is done:
**Before submitting a pull request**, please make sure the following is done:
1. Fork the repository and create your branch from `master`.
2. If you've added code that should be tested, add tests!
3. If you've changed APIs, update the documentation.
4. Ensure the tests pass (`yarn test`).
5. Lint and format your code (`yarn fmt && yarn lint`).
4. Lint and format your code (`yarn precommit`).
5. Ensure the tests pass (`yarn test`).
You can now submit a pull request, referencing any issues it addresses.

194
README.md
View File

@@ -1,127 +1,137 @@
# React Native for Web
[![Build Status][travis-image]][travis-url]
[![npm version][npm-image]][npm-url]
[![npm version][package-badge]][package-url] [![Build Status][ci-badge]][ci-url] [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request)
"React Native for Web" brings the platform-agnostic Components and APIs of
[React Native][react-native-url] to the Web.
Browse the [interactive
documentation](https://necolas.github.io/react-native-web/storybook/) or [try
it out](https://glitch.com/edit/#!/react-native-web-playground) on Glitch.
* **High-quality user interfaces**: React Native for Web makes it easy to
create [fast](packages/benchmarks/README.md), adaptive web UIs in
JavaScript. It provides native-like interactions, optimized vendor-prefixed
styles, support for all interaction types (touch, mouse, keyboard), accessible
experiences, built-in support for RTL layout, and integrates with React Dev
Tools.
## Features
* **Write once, render anywhere**: React Native for Web interoperates with
existing React DOM components and is compatible with the majority of the
React Native API. You can develop new components for native and web without
rewriting existing code. React Native for Web can also render to HTML and
critical CSS on the server using Node.js.
* Interoperability with ReactDOM components.
* Native-like touch handling.
* Built-in integration with web accessibility APIs.
* Built-in support for LTR and RTL layouts.
* Built-in expressive and reliable subset of CSS.
* Optimized, vendor-prefixed CSS with [good runtime performance](benchmarks/README.md).
* Server-side rendering of HTML and critical CSS.
* Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
React Native for Web is used extensively in production by [Twitter
Lite](https://mobile.twitter.com). The library's performance was experimentally
validated at scale including in emerging markets, and an independent audit
found Twitter Lite to be Twitter's most accessible app.
Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
## Quick start
Install in your existing app using `yarn` or `npm`:
The easiest way to get started with React Native for Web is to use this
[ready-to-go project on Glitch](https://glitch.com/edit/#!/react-native-web-playground).
You dont need to install anything to try it out.
If you are unfamiliar with setting up a React web project, please follow the
recommendations in the the official [React documentation](https://reactjs.org/).
## Documentation
You can find the React Native for Web API documentation [on the
website][website-url].
Please refer to the [React Native documentation][react-native-url] for details
about its design, the [Gesture Responder system](https://facebook.github.io/react-native/docs/gesture-responder-system.html),
and [animations](https://facebook.github.io/react-native/docs/animations.html).
### Installation
Install using `yarn` or `npm`:
```
yarn add react react-dom react-native-web
yarn add --dev babel-plugin-react-native-web
```
Add the `react-native-web` plugin to your Babel configuration. This will
alias `react-native` to `react-native-web` and exclude any modules not required
by the app.
### Guides
```json
{
"presets": [
"react-native"
],
"plugins": [
"react-native-web"
]
}
```
* [Getting started](website/guides/getting-started.md)
* [Style](website/guides/style.md)
* [Accessibility](website/guides/accessibility.md)
* [Internationalization](website/guides/internationalization.md)
* [Direct manipulation](website/guides/direct-manipulation.md)
* [Advanced use](website/guides/advanced.md)
(For React/ReactDOM 15.4 15.6 support, install `react-native-web@<0.1.0`)
## Examples
See the [Getting Started](docs/guides/getting-started.md) guide for more details.
## Documentation
The [interactive
documentation](https://necolas.github.io/react-native-web/storybook/) shows all
the supported APIs and Components.
Guides:
* [Getting started](docs/guides/getting-started.md)
* [Style](docs/guides/style.md)
* [Accessibility](docs/guides/accessibility.md)
* [Direct manipulation](docs/guides/direct-manipulation.md)
* [Internationalization](docs/guides/internationalization.md)
* [Advanced use](docs/guides/advanced.md)
* [Known issues](docs/guides/known-issues.md)
## Example code
There are several examples [on the website][website-url] and in the [website's
source code](./website). Here is an example to get you started:
```js
import React from 'react'
import { AppRegistry, Image, StyleSheet, Text, View } from 'react-native'
import React from 'react';
import { AppRegistry, 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>
)
// Styles
const styles = StyleSheet.create({
card: {
flexGrow: 1,
justifyContent: 'center'
},
title: {
fontSize: '1.25rem',
fontWeight: 'bold'
},
image: {
height: 40,
marginVertical: 10,
width: 40
class App extends React.Component {
render() {
return (
<View style={styles.box}>
<Text style={styles.text}>Hello, world!</Text>
</View>
);
}
})
}
// App registration and rendering
AppRegistry.registerComponent('MyApp', () => App)
AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-root') })
const styles = StyleSheet.create({
box: { padding: 10 },
text: { fontWeight: 'bold' }
});
AppRegistry.registerComponent('App', () => App);
AppRegistry.runApplication('App', { rootTag: document.getElementById('react-root') });
```
## Starter kits
This example will render the `App` into a container on the page.
* [Glitch](https://glitch.com/edit/#!/react-native-web-playground)
* [create-react-app](https://github.com/facebookincubator/create-react-app)
You'll notice that there is no reference to `react-dom`; the `App` component is
defined using the platform-agnostic APIs and Components introduced by React
Native. This allows the app to be rendered to web and native platforms.
## Related projects
## Contributing
* [react-primitives](https://github.com/lelandrichardson/react-primitives/)
* [react-sketchapp](https://github.com/airbnb/react-sketchapp)
* [reactxp](https://github.com/microsoft/reactxp)
* [react-native-web-player](https://github.com/dabbott/react-native-web-player)
The main purpose of this repository is to help evolve React web and native
development towards the platform-agnostic design of React Native, and in the
process make it faster and easier to build high-quality experiences for the web
with React. Development happens in the open on GitHub, and we are grateful for
contributing bugfixes and improvements. Read below to learn how you can take
part in improving React Native for Web.
### Code of conduct
Facebook has adopted a [Code of Conduct][code-of-conduct] that this project
expects all participants to adhere to. Please read the full text so that you
can understand what actions will and will not be tolerated.
### Contributing guide
Read the [contributing guide][contributing-url] to learn about the
development process, how to propose bugfixes and improvements, and how to build
and test your changes to React Native for Web.
### Good first issues
To help you get you familiar with the contribution process, there is a list of
[good first issues][good-first-issue-url] that contain bugs which have a
relatively limited scope. This is a great place to get started.
## License
React Native for Web is [BSD licensed](LICENSE).
React Native for Web is [BSD licensed](./LICENSE).
[npm-image]: https://badge.fury.io/js/react-native-web.svg
[npm-url]: https://yarnpkg.com/en/package/react-native-web
[package-badge]: https://img.shields.io/npm/v/react-native-web.svg?style=flat
[package-url]: https://yarnpkg.com/en/package/react-native-web
[ci-badge]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
[ci-url]: https://travis-ci.org/necolas/react-native-web
[website-url]: https://necolas.github.io/react-native-web/storybook/
[react-native-url]: https://facebook.github.io/react-native/
[travis-image]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
[travis-url]: https://travis-ci.org/necolas/react-native-web
[contributing-url]: ./.github/CONTRIBUTING.md
[good-first-issue-url]: https://github.com/necolas/react-native-web/labels/good%20first%20issue
[code-of-conduct]: https://code.facebook.com/codeofconduct

View File

@@ -17,7 +17,7 @@ equivalent in functionality. For example, the "React Native for Web" benchmark i
complete `View` implementation and the `StyleSheet` also converts React Native
styles to DOM styles, has deterministic resolution, and supports RTL layout.
## Benchmark results
## Results
Typical render timings*: mean ± two standard deviations.

View File

@@ -1,127 +1,6 @@
# React Native for Web
[![Build Status][travis-image]][travis-url]
[![npm version][npm-image]][npm-url]
# react-native-web
"React Native for Web" brings the platform-agnostic Components and APIs of
[React Native][react-native-url] to the Web.
React Native to the Web. It is used in production by Twitter Lite.
Browse the [interactive
documentation](https://necolas.github.io/react-native-web/storybook/) or [try
it out](https://glitch.com/edit/#!/react-native-web-playground) on Glitch.
## Features
* Interoperability with ReactDOM components.
* Native-like touch handling.
* Built-in integration with web accessibility APIs.
* Built-in support for LTR and RTL layouts.
* Built-in expressive and reliable subset of CSS.
* Optimized, vendor-prefixed CSS with [good runtime performance](benchmarks/README.md).
* Server-side rendering of HTML and critical CSS.
* Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
## Quick start
Install in your existing app using `yarn` or `npm`:
```
yarn add react react-dom react-native-web
yarn add --dev babel-plugin-react-native-web
```
Add the `react-native-web` plugin to your Babel configuration. This will
alias `react-native` to `react-native-web` and exclude any modules not required
by the app.
```json
{
"presets": [
"react-native"
],
"plugins": [
"react-native-web"
]
}
```
(For React/ReactDOM 15.4 15.6 support, install `react-native-web@<0.1.0`)
See the [Getting Started](docs/guides/getting-started.md) guide for more details.
## Documentation
The [interactive
documentation](https://necolas.github.io/react-native-web/storybook/) shows all
the supported APIs and Components.
Guides:
* [Getting started](docs/guides/getting-started.md)
* [Style](docs/guides/style.md)
* [Accessibility](docs/guides/accessibility.md)
* [Direct manipulation](docs/guides/direct-manipulation.md)
* [Internationalization](docs/guides/internationalization.md)
* [Advanced use](docs/guides/advanced.md)
* [Known issues](docs/guides/known-issues.md)
## Example code
```js
import React from 'react'
import { 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>
)
// Styles
const styles = StyleSheet.create({
card: {
flexGrow: 1,
justifyContent: 'center'
},
title: {
fontSize: '1.25rem',
fontWeight: 'bold'
},
image: {
height: 40,
marginVertical: 10,
width: 40
}
})
// App registration and rendering
AppRegistry.registerComponent('MyApp', () => App)
AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-root') })
```
## Starter kits
* [Glitch](https://glitch.com/edit/#!/react-native-web-playground)
* [create-react-app](https://github.com/facebookincubator/create-react-app)
## Related projects
* [react-primitives](https://github.com/lelandrichardson/react-primitives/)
* [react-sketchapp](https://github.com/airbnb/react-sketchapp)
* [reactxp](https://github.com/microsoft/reactxp)
* [react-native-web-player](https://github.com/dabbott/react-native-web-player)
## License
React Native for Web is [BSD licensed](LICENSE).
[npm-image]: https://badge.fury.io/js/react-native-web.svg
[npm-url]: https://yarnpkg.com/en/package/react-native-web
[react-native-url]: https://facebook.github.io/react-native/
[travis-image]: https://travis-ci.org/necolas/react-native-web.svg?branch=master
[travis-url]: https://travis-ci.org/necolas/react-native-web
Read more: https://github.com/necolas/react-native-web

View File

@@ -101,9 +101,9 @@ const StyledView = styled(View, styles.container);
## Use with react-sketchapp
Use with [react-sketchapp](http://airbnb.io/react-sketchapp/) requires that you
alias `react-native` to `react-sketchapp`. This will allow you to render your
existing React Native components in Sketch. Sketch-specific components like
`Artboard` should be imported from `react-sketchapp`.
alias `react-native` to `react-sketchapp`. This will allow you to render simple
React Native components in Sketch. Sketch-specific components like `Artboard`
should be imported from `react-sketchapp`.
If you're using `skpm`, you can rely on an [undocumented
feature](https://github.com/sketch-pm/skpm/blob/master/lib/utils/webpackConfig.js)

View File

@@ -1,18 +1,161 @@
# Getting started
This guide will help you to correctly configure build and test tools to work
with React Native for Web. (Alternatively, you can quickly setup a local
project using the starter kits listed in the README.)
This guide will help you to use and test React Native for Web once it has been installed.
It is recommended that your application provide a `Promise` and `Array.from`
polyfill.
## Web packager
## Adding to a new web app
[Webpack](https://webpack.js.org) is a popular build tool for web apps. Below is an
_example_ of how to configure a build that uses [Babel](https://babeljs.io/) to
compile your JavaScript for the web. Please refer to the webpack documentation
when setting up your project.
It's recommended to rely on Facebook's official React web starter kit
[create-react-app](https://github.com/facebookincubator/create-react-app)
which has built-in React Native for Web support (once you install
`react-native-web`).
## Adding to an existing web app
Add the `react-native-web` plugin to your Babel configuration. This will
alias `react-native` to `react-native-web` and exclude any modules not required
by the app.
```json
{
"presets": [
"react-native"
],
"plugins": [
"react-native-web"
]
}
```
## Client-side rendering
Render apps using `AppRegistry`:
```js
// index.web.js
import App from './src/App';
import React from 'react';
import { AppRegistry } from 'react-native';
// register the app
AppRegistry.registerComponent('App', () => App);
AppRegistry.runApplication('App', {
initialProps: {},
rootTag: document.getElementById('react-app')
});
```
Render components within existing apps:
```js
import AppHeader from './src/AppHeader';
import React from 'react';
import { render } from 'react-native';
render(<AppHeader />, document.getElementById('react-app-header'))
```
Components will also be rendered within a tree produced by calling
`ReactDOM.render` (i.e., an existing web app), but
otherwise it is not recommended.
## Server-side rendering
Server-side rendering is supported using `AppRegistry`:
```js
import App from './src/App';
import ReactDOMServer from 'react-dom/server'
import { AppRegistry } from 'react-native'
// register the app
AppRegistry.registerComponent('App', () => App)
// prerender the app
const { element, stylesheets } = AppRegistry.getApplication('App', { initialProps });
const initialHTML = ReactDOMServer.renderToString(element);
const initialStyles = stylesheets.map((sheet) => ReactDOMServer.renderToStaticMarkup(sheet)).join('\n');
// construct HTML document string
const document = `
<!DOCTYPE html>
<html>
<head>
${initialStyles}
</head>
<body>
${initialHTML}
`
```
## Web-specific code
Minor platform differences can use the `Platform` module.
```js
import { Platform } from 'react-native';
const styles = StyleSheet.create({
height: (Platform.OS === 'web') ? 200 : 100,
});
```
More significant platform differences should use platform-specific files (see
the webpack configuration below for resolving `*.web.js` files):
For example, with the following files in your project:
```
MyComponent.android.js
MyComponent.ios.js
MyComponent.web.js
```
And the following import:
```js
import MyComponent from './MyComponent';
```
React Native will automatically import the correct variant for each specific
target platform.
## Testing with Jest
[Jest](https://facebook.github.io/jest/) can be configured to improve snapshots
of `react-native-web` components.
```
{
"snapshotSerializers": [ "enzyme-to-json/serializer", "react-native-web/jest/serializer" ]
}
```
Jest also needs to map `react-native` to `react-native-web` (unless you are
using the Babel plugin).
```
{
"moduleNameMapper": {
"react-native": "<rootDir>/node_modules/react-native-web"
}
}
```
Please refer to the Jest documentation for more information.
## Web packaging for existing React Native apps
The web packaging landscape is diverse and fractured. Packaging web apps is
subtly different to packaging React Native apps and is also complicated by the
need to code-split non-trivial apps.
What follows is merely an _example_ of one basic way to package a web app
using [Webpack](https://webpack.js.org) and [Babel](https://babeljs.io/).
Install webpack-related dependencies, for example:
@@ -49,7 +192,7 @@ const babelLoaderConfiguration = {
cacheDirectory: true,
// This aliases 'react-native' to 'react-native-web' and includes only
// the modules needed by the app.
plugins: ['react-native-web/babel', 'transform-runtime'],
plugins: ['react-native-web', 'transform-runtime'],
// The 'react-native' preset is recommended (or use your own .babelrc).
presets: ['react-native']
}
@@ -119,122 +262,17 @@ To build for production:
Please refer to the Webpack documentation for more information on configuration.
### Client-side rendering
## Other notes
Rendering using `AppRegistry`:
### Safari flexbox performance
```js
// index.web.js
Safari prior to version 10.1 can suffer from extremely [poor flexbox
performance](https://bugs.webkit.org/show_bug.cgi?id=150445). The recommended
way to work around this issue (as used on mobile.twitter.com) is to set
`display:block` on Views in your element hierarchy that you know don't need
flexbox layout.
import App from './src/App';
import React from 'react';
import ReactNative, { AppRegistry } from 'react-native';
### Platform-specific component props
// register the app
AppRegistry.registerComponent('App', () => App);
AppRegistry.runApplication('App', {
initialProps: {},
rootTag: document.getElementById('react-app')
});
```
Rendering within existing web apps is also possible using `ReactNative`:
```js
import AppHeader from './src/AppHeader';
import React from 'react';
import ReactNative from 'react-native';
// use .hydrate if hydrating a SSR app
ReactNative.render(<AppHeader />, document.getElementById('react-app-header'))
```
And finally, `react-native-web` components will also be rendering within a tree
produced by calling `ReactDOM.render` (i.e., an existing web app), but
otherwise it is not recommended.
### Server-side rendering
Server-side rendering is supported using the `AppRegistry`:
```js
import App from './src/App';
import ReactDOMServer from 'react-dom/server'
import ReactNative, { AppRegistry } from 'react-native'
// register the app
AppRegistry.registerComponent('App', () => App)
// prerender the app
const { element, stylesheets } = AppRegistry.getApplication('App', { initialProps });
const initialHTML = ReactDOMServer.renderToString(element);
const initialStyles = stylesheets.map((sheet) => ReactDOMServer.renderToStaticMarkup(sheet)).join('\n');
// construct HTML document
const document = `
<!DOCTYPE html>
<html>
<head>
${initialStyles}
</head>
<body>
${initialHTML}
`
```
## Web-specific code
Minor platform differences can use the `Platform` module.
```js
import { Platform } from 'react-native';
const styles = StyleSheet.create({
height: (Platform.OS === 'web') ? 200 : 100,
});
```
More significant platform differences should use platform-specific files (see
the webpack configuration above for resolving `*.web.js` files):
For example, with the following files in your project:
```
MyComponent.android.js
MyComponent.ios.js
MyComponent.web.js
```
And the following import:
```js
import MyComponent from './MyComponent';
```
React Native will automatically import the correct variant for each specific
target platform.
## Testing with Jest
[Jest](https://facebook.github.io/jest/) can be configured to improve snapshots
of `react-native-web` components.
```
{
"snapshotSerializers": [ "enzyme-to-json/serializer", "react-native-web/jest/serializer" ]
}
```
Jest also needs to map `react-native` to `react-native-web` (unless you are
using Babel with the `react-native-web/babel` plugin).
```
{
"moduleNameMapper": {
"react-native": "<rootDir>/node_modules/react-native-web"
}
}
```
Please refer to the Jest documentation for more information.
There are properties that do not work across all platforms. All web-specific
props are annotated with `(web)` in the documentation.

View File

@@ -1,31 +0,0 @@
# Known issues
## Safari flexbox performance
Safari version prior to 10.1 can suffer from extremely [poor flexbox
performance](https://bugs.webkit.org/show_bug.cgi?id=150445). The recommended
way to work around this issue (as used on mobile.twitter.com) is to set
`display:block` on Views in your element hierarchy that you know don't need
flexbox layout.
## Missing modules and components
Not all of the views present on iOS/Android are currently available 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 or to guard the use of a
module with `Platform.OS` (e.g. `NativeModules`)
## Missing component props
There are properties that do not work across all platforms. All web-specific
props are annotated with `(web)` in the documentation.
## 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` for Web use, in anticipation
of the convergence between the iOS and Android components in React Native.

View File

@@ -5,22 +5,22 @@ application. React Native for Web implements the React Native style API in a
way that avoids *all* the [problems with CSS at
scale](https://speakerdeck.com/vjeux/react-css-in-js):
1. No local variables
2. Implicit dependencies
3. No dead code elimination
4. No code minification
5. No sharing of constants
6. Non-deterministic resolution
7. No isolation
1. No local variables.
2. Implicit dependencies.
3. No dead code elimination.
4. No code minification.
5. No sharing of constants.
6. Non-deterministic resolution.
7. No isolation.
At the same time, it has several benefits:
1. Simple API and expressive subset of CSS
2. Generates CSS; the minimum required
3. Good runtime performance
4. Support for static and dynamic styles
5. Support for RTL layouts
6. Easy pre-rendering of critical CSS
1. Simple API and expressive subset of CSS.
2. Generates CSS; the minimum required.
3. Good runtime performance.
4. Support for static and dynamic styles.
5. Support for RTL layouts.
6. Easy pre-rendering of critical CSS.
## Defining styles
@@ -43,6 +43,8 @@ const styles = StyleSheet.create({
See the `style` documentation of individual components for supported properties.
NOTE: React Native does not yet support `rem` or `em` units.
## Using styles
All the React Native components accept a `style` property. The value can be a
@@ -126,7 +128,7 @@ the CSS and takes precedence over the previous rules, resulting in a margin of
<div class="marginTop marginBottom margin"></div>
```
But in React Native the most *specific* style property takes precedence,
But in React Native the most *precise* style property takes precedence,
resulting in margins of `10, 0, 20, 0`.
```js
@@ -192,7 +194,7 @@ inline styles.
All this allows React Native for Web to support the rich functionality of React
Native styles (including RTL layouts and `setNativeProps`) while providing one
of the [fastest](https://github.com/necolas/react-native-web/blob/master/benchmarks/README.md),
of the [fastest](https://github.com/necolas/react-native-web/blob/master/packages/benchmarks/README.md),
safest, and most efficient styles-in-JavaScript solutions.
## FAQs
@@ -204,14 +206,11 @@ it does not concern itself with _where_ or _when_ those styles are applied to
elements.
Media Queries may not be most appropriate for component-based designs. React
Native provides the `Dimensions` API and `onLayout` props. If you do need Media
Queries, using the `matchMedia` DOM API has the benefit of allowing you to swap
out entire components, not just styles. There are also many React libraries
wrapping JavaScript Media Query API's, e.g.,
[react-media](https://github.com/reacttraining/react-media),
[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).
Native provides the `Dimensions` API and the component-scoped `onLayout` prop.
If you do choose to use Media Queries, using them in JavaScript via the
`matchMedia` DOM API has the benefit of allowing you to swap out entire
components, not just styles.
### What about pseudo-classes and pseudo-elements?