From c7c1f29016c945af7dcd0ba8dbf0d6b6f70846d1 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Tue, 5 Jun 2018 10:36:54 -0700 Subject: [PATCH] Reorganize documentation Close #1092 Close #1095 --- .github/ISSUE_TEMPLATE/bug.md | 3 + README.md | 217 +++++------ .../website => docs}/guides/accessibility.md | 0 {packages/website => docs}/guides/advanced.md | 0 docs/guides/client-side-rendering.md | 42 +++ .../guides/direct-manipulation.md | 0 docs/guides/getting-started.md | 116 ++++++ .../guides/internationalization.md | 0 docs/guides/multi-platform-apps.md | 154 ++++++++ docs/guides/server-side-rendering.md | 33 ++ {packages/website => docs}/guides/style.md | 0 docs/guides/web-recipes.md | 51 +++ packages/website/guides/getting-started.md | 353 ------------------ 13 files changed, 510 insertions(+), 459 deletions(-) rename {packages/website => docs}/guides/accessibility.md (100%) rename {packages/website => docs}/guides/advanced.md (100%) create mode 100644 docs/guides/client-side-rendering.md rename {packages/website => docs}/guides/direct-manipulation.md (100%) create mode 100644 docs/guides/getting-started.md rename {packages/website => docs}/guides/internationalization.md (100%) create mode 100644 docs/guides/multi-platform-apps.md create mode 100644 docs/guides/server-side-rendering.md rename {packages/website => docs}/guides/style.md (100%) create mode 100644 docs/guides/web-recipes.md delete mode 100644 packages/website/guides/getting-started.md diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index ae56f184..44ddaf93 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -33,6 +33,9 @@ Steps to reproduce: **Expected behavior** **Environment (include versions). Did this work in previous versions?** diff --git a/README.md b/README.md index 0a95a9ed..ff607ed3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ using Node.js. Who is using React Native in production web apps? [Twitter](https://mobile.twitter.com), [Major League Soccer](https://matchcenter.mlssoccer.com), -[Flipkart](https://www.flipkart.com/), Playstation, Uber, [The +[Flipkart](https://www.flipkart.com/), Uber, [The Times](https://github.com/newsuk/times-components). Browser support: Chrome, Firefox, Edge, Safari 7+, IE 10+. @@ -38,34 +38,56 @@ The easiest way to get started is to edit this anything to try it out. For installation and configuration details please read the [getting -started](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/getting-started.md) +started](https://github.com/necolas/react-native-web/blob/master/docs/guides/getting-started.md) guide. ## Documentation -You can find the API documentation [on the website][website-url]. - -Please refer to the [React Native documentation][react-native-url] for more -design details, and for information about the [Gesture Responder +Please refer to the [React Native documentation][react-native-url] for the +overall API, design details, and information about 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). +Some components and APIs are extended with additional features for the web. And +in a few cases, features present for Android or iOS are missing on the web. +These differences are documented [on the website][website-url]. + ### Guides -* [Getting started](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/getting-started.md) -* [Style](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/style.md) -* [Accessibility](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/accessibility.md) -* [Internationalization](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/internationalization.md) -* [Direct manipulation](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/direct-manipulation.md) -* [Experimental / unstable use](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/advanced.md) +These guides provide a detailed look at using React Native to create accessible +web experiences. Certain web-specific patterns are documented in the "web +recipes" guide. + +* [Getting started](https://github.com/necolas/react-native-web/blob/master/docs/guides/getting-started.md) +* [Client-side rendering](https://github.com/necolas/react-native-web/blob/master/docs/guides/client-side-rendering.md) +* [Server-side rendering](https://github.com/necolas/react-native-web/blob/master/docs/guides/server-side-rendering.md) +* [Style](https://github.com/necolas/react-native-web/blob/master/docs/guides/style.md) +* [Accessibility](https://github.com/necolas/react-native-web/blob/master/docs/guides/accessibility.md) +* [Internationalization](https://github.com/necolas/react-native-web/blob/master/docs/guides/internationalization.md) +* [Direct manipulation](https://github.com/necolas/react-native-web/blob/master/docs/guides/direct-manipulation.md) +* [Web recipes](https://github.com/necolas/react-native-web/blob/master/docs/guides/web-recipes.md) +* [Multi-platform apps](https://github.com/necolas/react-native-web/blob/master/docs/guides/multi-platform-apps.md) +* [Experimental / unstable use](https://github.com/necolas/react-native-web/blob/master/docs/guides/advanced.md) + +## Integrations + +Examples of using React Native for Web with other web tools: + +* [Docz](https://github.com/pedronauck/docz/tree/master/examples/react-native-flow) +* [Gatsby](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-react-native-web) +* [Next.js](https://github.com/zeit/next.js/tree/master/examples/with-react-native-web) +* [Phenomic](https://github.com/phenomic/phenomic/tree/master/examples/react-native-web-app) +* [Razzle](https://github.com/jaredpalmer/razzle/tree/master/examples/with-react-native-web) +* [Storybook](https://github.com/necolas/react-native-web/tree/master/packages/website/storybook/.storybook) +* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/master/examples/react-native) ## Examples -There are examples [on the website][website-url] ([source -code](https://github.com/necolas/react-native-web/blob/master/packages/website). -And all the [React Native examples][examples-url] ([source -code](https://github.com/necolas/react-native-web/blob/master/packages/examples)) -are also available. Here is an example to get you started: +Check out all the [React Native examples][examples-url] ([source +code](https://github.com/necolas/react-native-web/blob/master/packages/examples)). +There are more examples [on the website][website-url] ([source +code](https://github.com/necolas/react-native-web/blob/master/packages/website)). +And here is a simple example to get you started: ```js import React from 'react'; @@ -96,104 +118,87 @@ 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. -## Integrations - -Examples of using React Native for Web with other web tools: - -* [Gatsby](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-react-native-web) -* [Next.js](https://github.com/zeit/next.js/tree/master/examples/with-react-native-web) -* [Phenomic](https://github.com/phenomic/phenomic/tree/master/examples/react-native-web-app) -* [Razzle](https://github.com/jaredpalmer/razzle/tree/master/examples/with-react-native-web) -* [Storybook](https://github.com/necolas/react-native-web/tree/master/packages/website/storybook/.storybook) -* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/master/examples/react-native) - -Example recipes for web-specific UI patterns: - -* [Links](https://codesandbox.io/s/53r88k5opx) -* [Hover styles](https://codesandbox.io/s/o9q8vy70l5) -* [Root element styles](https://codesandbox.io/s/52x1871vjl) - ## Compatibility with React Native React Native v0.55 ### Components -| Name | Status | Notes | -| :----------------------- | :------------------ | :---- | -| ActivityIndicator | Available | | -| ART | Available | | -| Button | Available | | -| CheckBox | Available | | -| FlatList | Available | | -| Image | Available (partial) | Missing multiple sources and HTTP headers. | -| ImageBackground | Available | | -| KeyboardAvoidingView | Available (mock) | | -| ListView | Available | | -| Modal | Not started | | -| Picker | Available | | -| RefreshControl | Not started | | -| SafeAreaView | Available | | -| ScrollView | Available (partial) | Missing momentum scroll events. | -| SectionList | Available | | -| Slider | Not started | | -| StatusBar | Mock | | -| SwipeableFlatList | Available | | -| SwipeableListView | Available | | -| Switch | Available | | -| Text | Available (partial) | Missing `onLongPress` support. | -| TextInput | Available (partial) | Missing rich text features and auto-expanding behaviour. | -| Touchable | Available | Includes additional support for mouse and keyboard interactions. | -| TouchableHighlight | Available | | -| TouchableNativeFeedback | Not started | | -| TouchableOpacity | Available | | -| TouchableWithoutFeedback | Available | | -| View | Available | | -| VirtualizedList | Available | | -| WebView | Not started | | -| YellowBox | Mock | | +| Name | Status | Notes | +| :----------------------- | :----- | :---- | +| ActivityIndicator | ✓ | | +| ART | ✓ | | +| Button | ✓ | | +| CheckBox | ✓ | | +| FlatList | ✓ | | +| Image | ✓ | Missing multiple sources ([#515](https://github.com/necolas/react-native-web/issues/515)) and HTTP headers ([#1019](https://github.com/necolas/react-native-web/issues/1019)). | +| ImageBackground | ✓ | | +| KeyboardAvoidingView | (✓) | Mock. No equivalent web APIs. | +| ListView | ✓ | | +| Modal | ✘ | Not started ([#1020](https://github.com/necolas/react-native-web/issues/1020)). | +| Picker | ✓ | | +| RefreshControl | ✘ | Not started ([#1027](https://github.com/necolas/react-native-web/issues/1027)). | +| SafeAreaView | ✓ | | +| ScrollView | ✓ | Missing momentum scroll events ([#1021](https://github.com/necolas/react-native-web/issues/1021)) and `pagingEnabled` ([#1057](https://github.com/necolas/react-native-web/issues/1057)). | +| SectionList | ✓ | | +| Slider | ✘ | Not started ([#1022](https://github.com/necolas/react-native-web/issues/1022)). | +| StatusBar | (✓) | Mock. No equivalent web APIs. | +| SwipeableFlatList | ✓ | | +| SwipeableListView | ✓ | | +| Switch | ✓ | | +| Text | ✓ | Missing `onLongPress` ([#1011](https://github.com/necolas/react-native-web/issues/1011)) and `numberOfLines` ([#13](https://github.com/necolas/react-native-web/issues/13)) support. | +| TextInput | ✓ | Missing `onContentSizeChange` ([#793](https://github.com/necolas/react-native-web/issues/793)), rich text features ([#1023](https://github.com/necolas/react-native-web/issues/1023)), and auto-expanding behaviour ([#795](https://github.com/necolas/react-native-web/issues/795)). | +| Touchable | ✓ | Includes additional support for mouse and keyboard interactions. | +| TouchableHighlight | ✓ | | +| TouchableNativeFeedback | ✘ | Not started ([#1024](https://github.com/necolas/react-native-web/issues/1024)). | +| TouchableOpacity | ✓ | | +| TouchableWithoutFeedback | ✓ | | +| View | ✓ | | +| VirtualizedList | ✓ | | +| WebView | ✘ | Not started ([1025](https://github.com/necolas/react-native-web/issues/1025)). | +| YellowBox | (✓) | Mock. No YellowBox functionality. | ### Modules -| Name | Status | Notes | -| :----------------------- | :------------------ | :---- | -| AccessibilityInfo | Mock | No equivalent web APIs. | -| Alert | Not started | | -| Animated | Available | Missing `useNativeDriver` support. | -| AppRegistry | Available | Includes additional support for SSR with `getApplication`. | -| AppState | Available | | -| AsyncStorage | Available | | -| BackHandler | Mock | No equivalent web APIs. | -| CameraRoll | Not started | No equivalent web APIs. | -| Clipboard | Available | | -| ColorPropType | Available | | -| DeviceInfo | Available (partial) | | -| Dimensions | Available | | -| Easing | Available | | -| EdgeInsetsPropType | Available | | -| Geolocation | Available | | -| I18nManager | Available | Includes additional support for runtime switch to RTL. | -| ImageEditor | Not started | No equivalent web APIs. | -| ImageStore | Not started | No equivalent web APIs. | -| InteractionManager | Available (partial) | | -| Keyboard | Mock | | -| LayoutAnimation | Available (partial) | Missing transform to web animation. | -| Linking | Available | | -| NativeEventEmitter | Available | | -| NativeMethodsMixin | Available | | -| NativeModules | Available (partial) | Mocked. Missing ability to load native modules. | -| NetInfo | Available (partial) | Missing functionality to detect extensive connections. | -| PanResponder | Available | | -| PixelRatio | Available | | -| Platform | Available | | -| PointPropType | Available | | -| Settings | Not started | | -| Share | Available | Only available over HTTPS. Read about the [Web Share API](https://wicg.github.io/web-share/). | -| StyleSheet | Available | | -| TextPropTypes | Available | | -| UIManager | Available | | -| Vibration | Available | | -| ViewPropTypes | Available | | +| Name | Status | Notes | +| :----------------------- | :----- | :---- | +| AccessibilityInfo | (✓) | Mock. No equivalent web APIs. | +| Alert | ✘ | Not started ([#1026](https://github.com/necolas/react-native-web/issues/1026)). | +| Animated | ✓ | Missing `useNativeDriver` support. | +| AppRegistry | ✓ | Includes additional support for server rendering with `getApplication`. | +| AppState | ✓ | | +| AsyncStorage | ✓ | | +| BackHandler | (✓) | Mock. No equivalent web APIs. | +| CameraRoll | ✘ | No equivalent web APIs. | +| Clipboard | ✓ | | +| ColorPropType | ✓ | | +| DeviceInfo | (✓) | Limited information. | +| Dimensions | ✓ | | +| Easing | ✓ | | +| EdgeInsetsPropType | ✓ | | +| Geolocation | ✓ | | +| I18nManager | ✓ | Includes additional support for runtime switch to RTL. | +| ImageEditor | ✘ | No equivalent web APIs. | +| ImageStore | ✘ | No equivalent web APIs. | +| InteractionManager | (✓) | | +| Keyboard | (✓) | Mock. | +| LayoutAnimation | (✓) | Missing translation to web animations. | +| Linking | ✓ | | +| NativeEventEmitter | ✓ | | +| NativeMethodsMixin | ✓ | | +| NativeModules | (✓) | Mocked. Missing ability to load native modules. | +| NetInfo | ✓ | Missing functionality to detect expensive connections as there are no equivalent web APIs. | +| PanResponder | ✓ | | +| PixelRatio | ✓ | | +| Platform | ✓ | | +| PointPropType | ✓ | | +| Settings | ✘ | No equivalent web APIs. | +| Share | ✓ | Only available over HTTPS. Read about the [Web Share API](https://wicg.github.io/web-share/). | +| StyleSheet | ✓ | | +| TextPropTypes | ✓ | | +| UIManager | ✓ | | +| Vibration | ✓ | | +| ViewPropTypes | ✓ | | ## Contributing diff --git a/packages/website/guides/accessibility.md b/docs/guides/accessibility.md similarity index 100% rename from packages/website/guides/accessibility.md rename to docs/guides/accessibility.md diff --git a/packages/website/guides/advanced.md b/docs/guides/advanced.md similarity index 100% rename from packages/website/guides/advanced.md rename to docs/guides/advanced.md diff --git a/docs/guides/client-side-rendering.md b/docs/guides/client-side-rendering.md new file mode 100644 index 00000000..e2c47df1 --- /dev/null +++ b/docs/guides/client-side-rendering.md @@ -0,0 +1,42 @@ +# 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') +}); +``` + +Or render individual components: + +```js +import AppHeader from './src/AppHeader'; +import React from 'react'; +import { render } from 'react-native'; + +render(, 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.) + +You might need to adjust the styles of the HTML document's root elements for +your app to fill the viewport. + +```html + + +
+``` diff --git a/packages/website/guides/direct-manipulation.md b/docs/guides/direct-manipulation.md similarity index 100% rename from packages/website/guides/direct-manipulation.md rename to docs/guides/direct-manipulation.md diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md new file mode 100644 index 00000000..8b04391c --- /dev/null +++ b/docs/guides/getting-started.md @@ -0,0 +1,116 @@ +# Getting started + +This guide will help you render components and applications with React Native +for Web. + +Your application may need to polyfill `Promise`, `Object.assign`, `Array.from`, +and [`ResizeObserver`](https://github.com/que-etc/resize-observer-polyfill) as +necessary for your desired browser support. + +If you're not familiar with setting up a new React web project, please follow +the recommendations in the [React documentation](https://reactjs.org/). + +## Install + +``` +yarn add react react-dom react-native-web +``` + +And if you need to use `ART`: + +``` +yarn add react-art +``` + +## Starter kits + +Web: [create-react-app](https://github.com/facebookincubator/create-react-app) +includes built-in support for aliasing `react-native-web` to `react-native`. + +``` +create-react-app my-app +``` + +Multi-platform: [create-react-native-app](https://github.com/react-community/create-react-native-app) +includes experimental support for Web. + +``` +create-react-native-app my-app --with-web-support +``` + +## Configuring a module bundler + +If you have a custom setup, you may choose to configure your module bundler to +alias the package to `react-native`. + +For example, modify your [webpack](https://github.com/webpack/webpack) +configuration as follows: + +```js +// webpack.config.js +module.exports = { + // ...the rest of your config + + resolve: { + alias: { + 'react-native$': 'react-native-web' + } + } +} +``` + +Now you can create your components and applications with the React Native API. + +## Configuring Babel + +If you need to do the aliasing with Babel you can use +[babel-plugin-module-resolver](https://www.npmjs.com/package/babel-plugin-module-resolver) + +``` +{ + "plugins": [ + ["module-resolver", { + "alias": { + "^react-native$": "react-native-web" + } + }] + ] +} +``` + +## Configuring Jest + +[Jest](https://facebook.github.io/jest/) can be configured using the provided +preset. This will map `react-native` to `react-native-web` and provide +appropriate mocks: + +``` +{ + "preset": "react-native-web" +} +``` + +Please refer to the Jest documentation for more information. + +## Configuring Flow + +[Flow](https://flow.org) can be configured to understand the aliased module: + +``` +[options] +module.name_mapper='^react-native$' -> 'react-native-web' +``` + +You may also need to include a custom libdef +([example](https://gist.github.com/paularmstrong/f60b40d16fc83e1e8e532d483336f9bb)) +in your config. + +## Other notes + +### Safari flexbox performance + +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. diff --git a/packages/website/guides/internationalization.md b/docs/guides/internationalization.md similarity index 100% rename from packages/website/guides/internationalization.md rename to docs/guides/internationalization.md diff --git a/docs/guides/multi-platform-apps.md b/docs/guides/multi-platform-apps.md new file mode 100644 index 00000000..af9c3300 --- /dev/null +++ b/docs/guides/multi-platform-apps.md @@ -0,0 +1,154 @@ +# Multi-platform applications + +## 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. + +## Web packaging for existing React Native 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/). (You can +also the React Native bundler, [Metro](https://github.com/facebook/metro), to +build web apps.) + +Packaging web apps is subtly different to packaging React Native apps and is +complicated by the need to tree-shake and code-split non-trivial apps. + +Install webpack-related dependencies, for example: + +``` +yarn add --dev babel-loader url-loader webpack webpack-cli webpack-dev-server +``` + +React Native's Babel preset rewrites ES modules to CommonJS modules, preventing +bundlers from automatically performing "tree-shaking" to remove unused modules +from your web app build. To help with this, you can install the following Babel +plugin: + +``` +yarn install --dev babel-plugin-react-native-web +``` + +Create a `web/webpack.config.js` file: + +```js +// web/webpack.config.js + +const path = require('path'); +const webpack = require('webpack'); + +const appDirectory = path.resolve(__dirname, '../'); + +// This is needed for webpack to compile JavaScript. +// Many OSS React Native packages are not compiled to ES5 before being +// published. If you depend on uncompiled packages they may cause webpack build +// errors. To fix this webpack can be configured to compile to the necessary +// `node_module`. +const babelLoaderConfiguration = { + test: /\.js$/, + // Add every directory that needs to be compiled by Babel during the build. + include: [ + path.resolve(appDirectory, 'index.web.js'), + path.resolve(appDirectory, 'src'), + path.resolve(appDirectory, 'node_modules/react-native-uncompiled') + ], + use: { + loader: 'babel-loader', + options: { + cacheDirectory: true, + // The 'react-native' preset is recommended to match React Native's packager + presets: ['react-native'], + // Re-write paths to import only the modules needed by the app + plugins: ['react-native-web'] + } + } +}; + +// This is needed for webpack to import static images in JavaScript files. +const imageLoaderConfiguration = { + test: /\.(gif|jpe?g|png|svg)$/, + use: { + loader: 'url-loader', + options: { + name: '[name].[ext]' + } + } +}; + +module.exports = { + entry: [ + // load any web API polyfills + // path.resolve(appDirectory, 'polyfills-web.js'), + // your web-specific entry file + path.resolve(appDirectory, 'index.web.js') + ], + + // configures where the build ends up + output: { + filename: 'bundle.web.js', + path: path.resolve(appDirectory, 'dist') + }, + + // ...the rest of your config + + module: { + rules: [ + babelLoaderConfiguration, + imageLoaderConfiguration + ] + }, + + resolve: { + // This will only alias the exact import "react-native" + alias: { + 'react-native$': 'react-native-web' + }, + // If you're working on a multi-platform React Native app, web-specific + // module implementations should be written in files using the extension + // `.web.js`. + extensions: [ '.web.js', '.js' ] + } +} +``` + +To run in development from the root of your application: + +``` +./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors +``` + +To build for production: + +``` +./node_modules/.bin/webpack -p --config ./web/webpack.config.js +``` + +Please refer to the Webpack documentation for more information on configuration. diff --git a/docs/guides/server-side-rendering.md b/docs/guides/server-side-rendering.md new file mode 100644 index 00000000..4e445f8e --- /dev/null +++ b/docs/guides/server-side-rendering.md @@ -0,0 +1,33 @@ +# Server-side rendering + +Server-side rendering to HTML is supported using `AppRegistry`: + +```js +import App from './src/App'; +import ReactDOMServer from 'react-dom/server'; +import { AppRegistry } from 'react-native-web'; + +// register the app +AppRegistry.registerComponent('App', () => App); + +// prerender the app +const { element, getStyleElement } = AppRegistry.getApplication('App', { initialProps }); +// first the element +const html = ReactDOMServer.renderToString(element); +// then the styles (optionally include a nonce if your CSP policy requires it) +const css = ReactDOMServer.renderToStaticMarkup(getStyleElement({ nonce })); + +// example HTML document string +const document = ` + + + + +${css} + +
+${html} +
+ +` +``` diff --git a/packages/website/guides/style.md b/docs/guides/style.md similarity index 100% rename from packages/website/guides/style.md rename to docs/guides/style.md diff --git a/docs/guides/web-recipes.md b/docs/guides/web-recipes.md new file mode 100644 index 00000000..e388f8d9 --- /dev/null +++ b/docs/guides/web-recipes.md @@ -0,0 +1,51 @@ +# Web recipes + +Examples of how to implement web patterns with React Native. + +#### `html` and `body` styles + +The `html` and `body` elements require certain styles to support full-screen +React Native apps, and disable "features" like pull-to-refresh in mobile +browsers. Using the `body` as the root scroll view is [not reliably +supported](https://github.com/necolas/react-native-web/issues/829). + +[Example code](https://codesandbox.io/s/52x1871vjl). + +#### Hover styles + +Relying on the web's native hover styles can result in several unwanted UX +consequences. Hover styles might be displayed during touch interactions and can +remain visually "stuck". Furthermore, there's no way to delay or persist hover +for accessibility purposes. This recipe shows how to apply hover styles that +integrate with the Responder event system (e.g., the `Touchable*` press styles) +and display styles *only* when the mouse is active. It can also be used as the +basis for programmatic hover delays and rendering of components (e.g., hover +cards). + +[Example code](https://codesandbox.io/s/o9q8vy70l5) + +#### Link styles + +Cross-platform link components are straight-forward to create and can be +combined with the hover recipe. + +[Example code](https://codesandbox.io/s/53r88k5opx) + + diff --git a/packages/website/guides/getting-started.md b/packages/website/guides/getting-started.md deleted file mode 100644 index 2f877d93..00000000 --- a/packages/website/guides/getting-started.md +++ /dev/null @@ -1,353 +0,0 @@ -# Getting started - -This guide will help you render components and applications with React Native -for Web. - -Your application may need to polyfill `Promise`, `Object.assign`, `Array.from`, -and [`ResizeObserver`](https://github.com/que-etc/resize-observer-polyfill) as -necessary for your desired browser support. - -If you're not familiar with setting up a new React web project, please follow -the recommendations in the [React documentation](https://reactjs.org/). - -## Install - -``` -yarn add react react-dom react-native-web -``` - -And if you need to use `ART`: - -``` -yarn add react-art -``` - -## Starter kits - -Web: [create-react-app](https://github.com/facebookincubator/create-react-app) -includes built-in support for aliasing `react-native-web` to `react-native`. - -``` -create-react-app my-app -``` - -Multi-platform: [create-react-native-app](https://github.com/react-community/create-react-native-app) -includes experimental support for Web. - -``` -create-react-native-app my-app --with-web-support -``` - -## Configuring a module bundler - -If you have a custom setup, you may choose to configure your module bundler to -alias the package to `react-native`. - -For example, modify your [webpack](https://github.com/webpack/webpack) -configuration as follows: - -```js -// webpack.config.js -module.exports = { - // ...the rest of your config - - resolve: { - alias: { - 'react-native$': 'react-native-web' - } - } -} -``` - -Now you can create your components and applications with the React Native API. - -## Configuring babel - -If you need to do the aliasing with Babel you can use -[babel-plugin-module-resolver](https://www.npmjs.com/package/babel-plugin-module-resolver) - -``` -{ - "plugins": [ - ["module-resolver", { - "alias": { - "^react-native$": "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') -}); -``` - -Or render individual components: - -```js -import AppHeader from './src/AppHeader'; -import React from 'react'; -import { render } from 'react-native'; - -render(, 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.) - -You might need to adjust the styles of the HTML document's root elements for -your app to fill the viewport. - -```html - - -
-``` - -## Server-side rendering - -Server-side rendering to HTML is supported using `AppRegistry`: - -```js -import App from './src/App'; -import ReactDOMServer from 'react-dom/server'; -import { AppRegistry } from 'react-native-web'; - -// register the app -AppRegistry.registerComponent('App', () => App); - -// prerender the app -const { element, getStyleElement } = AppRegistry.getApplication('App', { initialProps }); -// first the element -const html = ReactDOMServer.renderToString(element); -// then the styles (optionally include a nonce if your CSP policy requires it) -const css = ReactDOMServer.renderToStaticMarkup(getStyleElement({ nonce })); - -// example HTML document string -const document = ` - - - - -${css} - -
-${html} -
- -` -``` - -## Testing with Jest - -[Jest](https://facebook.github.io/jest/) can be configured using the provided -preset. This will map `react-native` to `react-native-web` and provide -appropriate mocks: - -``` -{ - "preset": "react-native-web" -} -``` - -Please refer to the Jest documentation for more information. - -## Using Flow - -[Flow](https://flow.org) can be configured to understand the aliased module: - -``` -[options] -module.name_mapper='^react-native$' -> 'react-native-web' -``` - -You may also need to include a custom libdef -([example](https://gist.github.com/paularmstrong/f60b40d16fc83e1e8e532d483336f9bb)) -in your config. - -## Multi-platform applications - -### 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. - -## Web packaging for existing React Native 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/). (You can -also the React Native bundler, [Metro](https://github.com/facebook/metro), to -build web apps.) - -Packaging web apps is subtly different to packaging React Native apps and is -complicated by the need to tree-shake and code-split non-trivial apps. - -Install webpack-related dependencies, for example: - -``` -yarn add --dev babel-loader url-loader webpack webpack-cli webpack-dev-server -``` - -React Native's Babel preset rewrites ES modules to CommonJS modules, preventing -bundlers from automatically performing "tree-shaking" to remove unused modules -from your web app build. To help with this, you can install the following Babel -plugin: - -``` -yarn install --dev babel-plugin-react-native-web -``` - -Create a `web/webpack.config.js` file: - -```js -// web/webpack.config.js - -const path = require('path'); -const webpack = require('webpack'); - -const appDirectory = path.resolve(__dirname, '../'); - -// This is needed for webpack to compile JavaScript. -// Many OSS React Native packages are not compiled to ES5 before being -// published. If you depend on uncompiled packages they may cause webpack build -// errors. To fix this webpack can be configured to compile to the necessary -// `node_module`. -const babelLoaderConfiguration = { - test: /\.js$/, - // Add every directory that needs to be compiled by Babel during the build. - include: [ - path.resolve(appDirectory, 'index.web.js'), - path.resolve(appDirectory, 'src'), - path.resolve(appDirectory, 'node_modules/react-native-uncompiled') - ], - use: { - loader: 'babel-loader', - options: { - cacheDirectory: true, - // The 'react-native' preset is recommended to match React Native's packager - presets: ['react-native'], - // Re-write paths to import only the modules needed by the app - plugins: ['react-native-web'] - } - } -}; - -// This is needed for webpack to import static images in JavaScript files. -const imageLoaderConfiguration = { - test: /\.(gif|jpe?g|png|svg)$/, - use: { - loader: 'url-loader', - options: { - name: '[name].[ext]' - } - } -}; - -module.exports = { - entry: [ - // load any web API polyfills - // path.resolve(appDirectory, 'polyfills-web.js'), - // your web-specific entry file - path.resolve(appDirectory, 'index.web.js') - ], - - // configures where the build ends up - output: { - filename: 'bundle.web.js', - path: path.resolve(appDirectory, 'dist') - }, - - // ...the rest of your config - - module: { - rules: [ - babelLoaderConfiguration, - imageLoaderConfiguration - ] - }, - - resolve: { - // This will only alias the exact import "react-native" - alias: { - 'react-native$': 'react-native-web' - }, - // If you're working on a multi-platform React Native app, web-specific - // module implementations should be written in files using the extension - // `.web.js`. - extensions: [ '.web.js', '.js' ] - } -} -``` - -To run in development from the root of your application: - -``` -./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors -``` - -To build for production: - -``` -./node_modules/.bin/webpack -p --config ./web/webpack.config.js -``` - -Please refer to the Webpack documentation for more information on configuration. - -## Other notes - -### Safari flexbox performance - -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. - -### Platform-specific component props - -There are properties that do not work across all platforms. All web-specific -props are annotated with `(web)` in the documentation.