Compare commits

...
Author SHA1 Message Date
Hector Ramos dc04bf3d96 Working! 2017-11-15 15:34:32 -08:00
Hector Ramos 8e34e7bd5f latest 2017-11-14 12:51:44 -08:00
Hector Ramos 68f6799b7c Lots of progress into build-docs.js 2017-11-13 14:21:44 -08:00
Hector Ramos 2c130e6a9f wip3 2017-10-31 14:11:35 -07:00
Hector Ramos 21423bdf22 WIP 2017-10-31 14:09:41 -07:00
Hector Ramos e5332504cc wip 2017-10-31 11:51:47 -07:00
Hector Ramos 292f035ae8 progress 2017-10-31 11:19:00 -07:00
Hector Ramos a6c4ae0e75 Moving on to master docs 2017-10-30 17:04:16 -07:00
Hector Ramos e4b5e9ef85 Progress 2017-10-27 13:23:00 -07:00
Hector Ramos 732831dc27 Progress :D 2017-10-27 11:51:58 -07:00
Hector Ramos b150fdfdce mostly there 2017-10-26 23:46:53 -07:00
Hector Ramos 73f2007679 moast there 2017-10-26 18:46:40 -07:00
Hector Ramos da2a8b365c PROGRESS 2017-10-26 16:22:28 -07:00
Hector Ramos 143ecf4c62 Progress 2017-10-26 15:36:54 -07:00
Hector Ramos c8d6cb9e49 WIP{ 2017-10-26 15:20:59 -07:00
Hector Ramos 0661c6f254 WIP 2017-10-09 15:08:36 -07:00
Hector Ramos 5f4a5388ac WIP 2017-10-06 14:30:06 -07:00
Hector Ramos 445dac2743 Progress towards making single "import everything from GitHub, including every tag" script. 2017-10-05 15:36:45 -07:00
Hector Ramos 2d230bee78 Versioning WIP 2017-10-04 17:02:20 -07:00
Hector Ramos 382abb4b45 Adjust layout 2017-10-04 13:20:28 -07:00
Hector Ramos b0e4b89b58 Docs 2017-10-03 13:46:34 -07:00
Hector Ramos 0b8525847f Fix method titles in props 2017-09-29 14:41:15 -07:00
Hector Ramos 09a923599e More styling updates 2017-09-29 14:39:45 -07:00
Hector Ramos e7b7951c96 Styles for props 2017-09-29 14:39:31 -07:00
Hector Ramos a91d0d8c35 Additional css changes 2017-09-27 16:49:19 -07:00
Hector Ramos 47206fdd3c wip 2017-09-25 14:28:16 -07:00
Hector Ramos b02efd9e96 Make showcase logos square 2017-09-12 17:49:45 -07:00
Hector Ramos 31894136f4 Images and static assets 2017-09-05 09:31:56 -07:00
Hector Ramos 9b6639ad12 Fix tabs styling. 2017-09-01 14:19:26 -07:00
Hector Ramos 11f838f349 Adjust styling to match production site. 2017-09-01 13:32:38 -07:00
Hector Ramos 34787cc0eb Updated scripts. 2017-08-31 11:29:32 -07:00
Hector Ramos d40bea925f Move autodocs script to docgen/server 2017-08-31 10:41:57 -07:00
Hector Ramos 692d3f72fb Move to Docusaurus. 2017-08-31 10:38:26 -07:00
2195 changed files with 204296 additions and 5460 deletions
+3
View File
@@ -57,3 +57,6 @@ node_modules
/coverage
/third-party
/website/src
/website/build
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible Node.js debug attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}/Libraries/react-native/react-native-implementation.js"
}
]
}
+26 -24
View File
@@ -9,21 +9,21 @@
* @providesModule View
* @flow
*/
'use strict';
"use strict";
const NativeMethodsMixin = require('NativeMethodsMixin');
const Platform = require('Platform');
const PropTypes = require('prop-types');
const React = require('React');
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const ViewPropTypes = require('ViewPropTypes');
const NativeMethodsMixin = require("NativeMethodsMixin");
const Platform = require("Platform");
const PropTypes = require("prop-types");
const React = require("React");
const ReactNativeStyleAttributes = require("ReactNativeStyleAttributes");
const ReactNativeViewAttributes = require("ReactNativeViewAttributes");
const ViewPropTypes = require("ViewPropTypes");
const createReactClass = require('create-react-class');
const invariant = require('fbjs/lib/invariant');
const requireNativeComponent = require('requireNativeComponent');
const createReactClass = require("create-react-class");
const invariant = require("fbjs/lib/invariant");
const requireNativeComponent = require("requireNativeComponent");
import type {ViewProps} from 'ViewPropTypes';
import type { ViewProps } from "ViewPropTypes";
export type Props = ViewProps;
@@ -75,7 +75,7 @@ export type Props = ViewProps;
*/
// $FlowFixMe(>=0.41.0)
const View = createReactClass({
displayName: 'View',
displayName: "View",
// TODO: We should probably expose the mixins, viewConfig, and statics publicly. For example,
// one of the props is of type AccessibilityComponentType. That is defined as a const[] above,
// but it is not rendered by the docs, since `statics` below is not rendered. So its Possible
@@ -93,42 +93,44 @@ const View = createReactClass({
* make `this` look like an actual native component class.
*/
viewConfig: {
uiViewClassName: 'RCTView',
uiViewClassName: "RCTView",
validAttributes: ReactNativeViewAttributes.RCTView
},
contextTypes: {
isInAParentText: PropTypes.bool,
isInAParentText: PropTypes.bool
},
render: function() {
invariant(
!(this.context.isInAParentText && Platform.OS === 'android'),
'Nesting of <View> within <Text> is not supported on Android.');
!(this.context.isInAParentText && Platform.OS === "android"),
"Nesting of <View> within <Text> is not supported on Android."
);
// WARNING: This method will not be used in production mode as in that mode we
// replace wrapper component View with generated native wrapper RCTView. Avoid
// adding functionality this component that you'd want to be available in both
// dev and prod modes.
return <RCTView {...this.props} />;
},
}
});
const RCTView = requireNativeComponent('RCTView', View, {
const RCTView = requireNativeComponent("RCTView", View, {
nativeOnly: {
nativeBackgroundAndroid: true,
nativeForegroundAndroid: true,
nativeForegroundAndroid: true
}
});
if (__DEV__) {
const UIManager = require('UIManager');
const viewConfig = UIManager.viewConfigs && UIManager.viewConfigs.RCTView || {};
const UIManager = require("UIManager");
const viewConfig =
(UIManager.viewConfigs && UIManager.viewConfigs.RCTView) || {};
for (const prop in viewConfig.nativeProps) {
const viewAny: any = View; // Appease flow
if (!viewAny.propTypes[prop] && !ReactNativeStyleAttributes[prop]) {
throw new Error(
'View is missing propType for native prop `' + prop + '`'
"View is missing propType for native prop `" + prop + "`"
);
}
}
@@ -140,4 +142,4 @@ if (__DEV__) {
}
// No one should depend on the DEV-mode createClass View wrapper.
module.exports = ((ViewToExport : any) : typeof RCTView);
module.exports = ((ViewToExport: any): typeof RCTView);
+1
View File
@@ -0,0 +1 @@
/build/
+42
View File
@@ -0,0 +1,42 @@
# React Native Docs Generator
The React Native website is generated from a collection of markdown documents. This directory holds a collection of scripts necessary to generate these markdown docs prior to the site being built.
## import-existing-docs.js
For development use only. This script will pull down the current docs from master, and apply any transformations necessary to host the docs under the new website build script.
### Usage
First, install dependencies:
```
npm install
```
Run the following command locally:
```
GIT_USER=your_git_user GITHUB_USERNAME=facebook GITHUB_REPONAME=react-native node server/import-existing-docs.js
```
This will perform a sparse checkout of the `docs/` folder from `master`, generating a clean set of markdown docs in the local `docs/` folder. It will also write to disk an updated `sidebars.json` file based on these docs.
## build.js
Runs the usual autodocs generation scripts used by the `react-page-middleware` variant of the React Native website, but provides markdown instead of HTML. Run this script prior to building the website.
### Usage
Run the following command locally:
```
node server/build.js
```
The build script performs some cleanup, then runs the following scripts in order:
```
node server/generate.js
node server/build-autodocs-markdown.js
node server/build-autodocs-sidebar.js
```
@@ -12,14 +12,14 @@
var React = require('React');
var AlgoliaDocSearch = React.createClass({
render: function() {
class AlgoliaDocSearch extends React.Component {
render() {
return (
<div className="algolia-search-wrapper">
<input id="algolia-doc-search" tabIndex="0" type="text" placeholder="Search docs..." />
</div>
);
}
});
}
module.exports = AlgoliaDocSearch;
@@ -17,8 +17,8 @@ var BlogPostHeader = require('BlogPostHeader');
var BlogPostFooter = require('BlogPostFooter');
var ExcerptLink = require('ExcerptLink');
var BlogPost = React.createClass({
render: function() {
class BlogPost extends React.Component {
render() {
var post = this.props.post;
return (
@@ -31,6 +31,6 @@ var BlogPost = React.createClass({
</article>
);
}
});
}
module.exports = BlogPost;
@@ -13,8 +13,8 @@
var React = require('React');
var BlogPostDate = React.createClass({
render: function() {
class BlogPostDate extends React.Component {
render() {
var post = this.props.post;
var match = post.publishedAt.match(/([0-9]+)-([0-9]+)-([0-9]+)/);
@@ -32,6 +32,6 @@ var BlogPostDate = React.createClass({
<time className="date" datetime={post.publishedAt}>{postedOnDate}</time>
);
}
});
}
module.exports = BlogPostDate;
@@ -16,8 +16,8 @@ var BlogPostHeader = require('BlogPostHeader');
var Marked = require('Marked');
var ExcerptLink = require('ExcerptLink');
var BlogPostExcerpt = React.createClass({
render: function() {
class BlogPostExcerpt extends React.Component {
render() {
var post = this.props.post;
return (
<article className="entry-excerpt">
@@ -33,6 +33,6 @@ var BlogPostExcerpt = React.createClass({
</article>
);
}
});
}
module.exports = BlogPostExcerpt;
@@ -14,8 +14,8 @@
var React = require('React');
var BlogPostDate = require('BlogPostDate');
var BlogPostFooter = React.createClass({
render: function() {
class BlogPostFooter extends React.Component {
render() {
var post = this.props.post;
var authorImage = this.props.post.authorImage ? this.props.post.authorImage : '/react-native/img/author.png';
@@ -58,6 +58,6 @@ var BlogPostFooter = React.createClass({
</div>
);
}
});
}
module.exports = BlogPostFooter;
@@ -14,8 +14,8 @@
var React = require('React');
var BlogPostDate = require('BlogPostDate');
var BlogPostHeader = React.createClass({
render: function() {
class BlogPostHeader extends React.Component {
render() {
var post = this.props.post;
var hero;
@@ -54,6 +54,6 @@ var BlogPostHeader = React.createClass({
</header>
);
}
});
}
module.exports = BlogPostHeader;
@@ -13,8 +13,15 @@
var Metadata = require('Metadata');
var React = require('React');
var DocsSidebar = React.createClass({
getCategories: function() {
class DocsSidebar extends React.Component {
constructor(props, context) {
super(props, context);
this.getCategories = this.getCategories.bind(this);
this.getLink = this.getLink.bind(this);
}
getCategories() {
var metadatas = Metadata.files.filter(function(metadata) {
return metadata.layout === 'docs' || metadata.layout === 'autodocs';
});
@@ -67,13 +74,13 @@ var DocsSidebar = React.createClass({
categories.push(currentCategory);
return categories;
},
}
getLink: function(metadata) {
getLink(metadata) {
return metadata.permalink;
},
}
render: function() {
render() {
return <div className="nav-docs">
<div className="nav-docs-viewport">
{this.getCategories().map((category) =>
@@ -97,6 +104,6 @@ var DocsSidebar = React.createClass({
</div>
</div>;
}
});
}
module.exports = DocsSidebar;
@@ -12,8 +12,8 @@
var React = require('React');
var EjectBanner = React.createClass({
render: function() {
class EjectBanner extends React.Component {
render() {
return (
<div className="banner-crna-ejected">
<h3>Project with Native Code Required</h3>
@@ -25,6 +25,6 @@ var EjectBanner = React.createClass({
</div>
);
}
});
}
module.exports = EjectBanner;
@@ -13,8 +13,8 @@
var React = require('React');
var ExcerptLink = React.createClass({
render: function() {
class ExcerptLink extends React.Component {
render() {
var cta = "Read more";
if (this.props.category === "videos") {
@@ -29,6 +29,6 @@ var ExcerptLink = React.createClass({
</footer>
);
}
});
}
module.exports = ExcerptLink;
+13 -10
View File
@@ -5,22 +5,25 @@
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Footer
*/
'use strict';
var React = require('React');
var fourOhFour = React.createClass({
render: function() {
function getGitHubPath(path) {
return 'https://github.com/facebook/react-native/blob/master/' + path;
}
class Footer extends React.Component {
render() {
return (
<html>
<head>
<meta httpEquiv="refresh" content="0; /react-native/docs/getting-started.html" />
</head>
<body />
</html>
<p className="edit-page-block">
<a target="_blank" href={getGitHubPath(this.props.path)}>Improve this page</a> by sending a pull request!
</p>
);
}
});
}
module.exports = fourOhFour;
module.exports = Footer;
+3 -3
View File
@@ -13,10 +13,10 @@
var Header = require('Header');
var React = require('React');
var H2 = React.createClass({
render: function() {
class H2 extends React.Component {
render() {
return <Header {...this.props} level={2}>{this.props.children}</Header>;
}
});
}
module.exports = H2;
@@ -16,12 +16,8 @@ var PropTypes = require('prop-types');
var slugify = require('slugify');
var Header = React.createClass({
contextTypes: {
permalink: PropTypes.string
},
render: function() {
class Header extends React.Component {
render() {
var slug = slugify(this.props.toSlug || this.props.children);
var H = 'h' + this.props.level;
var base = this.context.permalink || '';
@@ -33,6 +29,10 @@ var Header = React.createClass({
</H>
);
}
});
}
Header.contextTypes = {
permalink: PropTypes.string
};
module.exports = Header;
@@ -13,18 +13,19 @@
var AlgoliaDocSearch = require('AlgoliaDocSearch');
var React = require('React');
var HeaderLinks = React.createClass({
linksInternal: [
{section: 'docs', href: 'docs/getting-started.html', text: 'Docs', target: '.nav-docs'},
{section: 'support', href: '/react-native/support.html', text: 'Help'},
{section: 'blog', href: '/react-native/blog/', text: 'Blog'},
],
linksExternal: [
{section: 'github', href: 'https://github.com/facebook/react-native', text: 'GitHub'},
{section: 'react', href: 'http://facebook.github.io/react', text: 'React'},
],
var linksInternal = [
{section: 'docs', href: 'docs/getting-started.html', text: 'Docs', target: '.nav-docs'},
{section: 'support', href: '/react-native/support.html', text: 'Help'},
{section: 'blog', href: '/react-native/blog/', text: 'Blog'},
];
makeLinks: function(links) {
var linksExternal = [
{section: 'github', href: 'https://github.com/facebook/react-native', text: 'GitHub'},
{section: 'react', href: 'http://facebook.github.io/react', text: 'React'},
];
class HeaderLinks extends React.Component {
makeLinks(links) {
return links.map(function(link) {
return (
<li key={link.section}>
@@ -37,23 +38,23 @@ var HeaderLinks = React.createClass({
</li>
);
}, this);
},
}
render: function() {
render() {
return (
<div className="nav-site-wrapper">
<ul className="nav-site nav-site-internal">
{this.makeLinks(this.linksInternal)}
{this.makeLinks(linksInternal)}
</ul>
<AlgoliaDocSearch />
<ul className="nav-site nav-site-external">
{this.makeLinks(this.linksExternal)}
{this.makeLinks(linksExternal)}
</ul>
</div>
);
}
});
}
module.exports = HeaderLinks;
@@ -19,13 +19,8 @@ function getGitHubPath(path) {
return 'https://github.com/facebook/react-native/blob/master/' + path;
}
var HeaderWithGithub = React.createClass({
contextTypes: {
version: PropTypes.string
},
render: function() {
class HeaderWithGithub extends React.Component {
render() {
return (
<table width="100%">
<tbody>
@@ -47,6 +42,10 @@ var HeaderWithGithub = React.createClass({
</table>
);
}
});
}
HeaderWithGithub.contextTypes = {
version: PropTypes.string
};
module.exports = HeaderWithGithub;
+3 -3
View File
@@ -12,8 +12,8 @@
var React = require('React');
var Hero = React.createClass({
render: function() {
class Hero extends React.Component {
render() {
return (
<div className="hero">
<div className="wrap">
@@ -26,6 +26,6 @@ var Hero = React.createClass({
</div>
);
}
});
}
module.exports = Hero;
@@ -1193,15 +1193,15 @@ marked.inlineLexer = InlineLexer.output;
marked.parse = marked;
var Marked = React.createClass({
render: function() {
class Marked extends React.Component {
render() {
return this.props.children
? React.DOM.div(
null,
marked(this.props.children, this.props)
)
: null;
},
});
}
}
module.exports = Marked;
+9 -12
View File
@@ -526,16 +526,8 @@ _.languages.java = _.languages.extend('clike', {
},
});
var Prism = React.createClass({
statics: {
_: _,
},
getDefaultProps: function() {
return {
language: 'javascript',
};
},
render: function() {
class Prism extends React.Component {
render() {
var grammar = _.languages[this.props.language];
if (!grammar) {
grammar = _.languages.javascript;
@@ -549,7 +541,12 @@ var Prism = React.createClass({
)}
</div>
);
},
});
}
}
Prism._ = _;
Prism.defaultProps = {
language: 'javascript',
};
module.exports = Prism;
@@ -13,14 +13,14 @@
var React = require('React');
const ShowcaseAppIcon = React.createClass({
render: function() {
class ShowcaseAppIcon extends React.Component {
render() {
return (
<a href={this.props.linkUri}>
<img src={this.props.iconUri} alt={this.props.name} />
</a>
);
}
});
}
module.exports = ShowcaseAppIcon;
+49
View File
@@ -0,0 +1,49 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Site
*/
'use strict';
var HeaderLinks = require('HeaderLinks');
var Metadata = require('Metadata');
var React = require('React');
class Site extends React.Component {
render() {
const path = Metadata.config.RN_DEPLOYMENT_PATH;
var basePath = '/react-native/' +
(path ? path + '/' : '');
var title = this.props.title
? this.props.title
: 'React Native | A framework for building native apps using React';
return (
<html>
<head>
<title>{title}</title>
<base href={basePath} />
<link
rel="stylesheet"
href="css/react-native.css"
/>
<link rel="stylesheet" href="css/prism.css" />
<meta property="rn:category" content={this.props.category} />
</head>
<body>
{this.props.children}
</body>
</html>
);
}
}
module.exports = Site;
@@ -41,14 +41,16 @@ var ReactNativeToExpoSDKVersionMap = {
* }
* ```
*/
var SnackPlayer = React.createClass({
contextTypes: {
version: PropTypes.number.isRequired,
},
class SnackPlayer extends React.Component {
constructor(props, context) {
super(props, context);
this.parseParams = this.parseParams.bind(this);
}
componentDidMount() {
window.ExpoSnack && window.ExpoSnack.initialize();
},
}
render() {
var code = encodeURIComponent(this.props.children);
@@ -110,9 +112,9 @@ var SnackPlayer = React.createClass({
</div>
</div>
);
},
}
parseParams: function(paramString) {
parseParams(paramString) {
var params = {};
if (paramString) {
@@ -124,7 +126,11 @@ var SnackPlayer = React.createClass({
}
return params;
},
});
}
}
SnackPlayer.contextTypes = {
version: PropTypes.number.isRequired,
};
module.exports = SnackPlayer;
@@ -31,8 +31,14 @@ var WEB_PLAYER_VERSION = '1.2.6';
* AppRegistry.registerComponent('MyApp', () => App);
* ```
*/
var WebPlayer = React.createClass({
parseParams: function(paramString) {
class WebPlayer extends React.Component {
constructor(props, context) {
super(props, context);
this.parseParams = this.parseParams.bind(this);
}
parseParams(paramString) {
var params = {};
if (paramString) {
@@ -44,9 +50,9 @@ var WebPlayer = React.createClass({
}
return params;
},
}
render: function() {
render() {
var hash = `#code=${encodeURIComponent(this.props.children)}`;
if (this.props.params) {
@@ -65,7 +71,7 @@ var WebPlayer = React.createClass({
/>
</div>
);
},
});
}
}
module.exports = WebPlayer;
@@ -12,14 +12,14 @@
var React = require('React');
var center = React.createClass({
render: function() {
class center extends React.Component {
render() {
return (
<div {...this.props} style={{textAlign: 'center'}}>
{this.props.children}
</div>
);
}
});
}
module.exports = center;
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -11,10 +11,7 @@
'use strict';
var DocsSidebar = require('DocsSidebar');
var Footer = require('Footer');
var Header = require('Header');
var HeaderWithGithub = require('HeaderWithGithub');
var Marked = require('Marked');
var Metadata = require('Metadata');
var Prism = require('Prism');
@@ -204,8 +201,23 @@ function getNamedTypes(typedefs) {
return namedTypes;
}
var ComponentDoc = React.createClass({
renderProp: function(name, prop) {
class ComponentDoc extends React.Component {
constructor(props, context) {
super(props, context);
this.extractPlatformFromProps = this.extractPlatformFromProps.bind(this);
this.renderCompose = this.renderCompose.bind(this);
this.renderStylesheetProp = this.renderStylesheetProp.bind(this);
this.renderStylesheetProps = this.renderStylesheetProps.bind(this);
this.renderMethod = this.renderMethod.bind(this);
this.renderMethods = this.renderMethods.bind(this);
this.renderProp = this.renderProp.bind(this);
this.renderProps = this.renderProps.bind(this);
this.renderTypeDef = this.renderTypeDef.bind(this);
this.renderTypeDefs = this.renderTypeDefs.bind(this);
}
renderProp(name, prop) {
return (
<div className="prop" key={name}>
<Header level={4} className="propTitle" toSlug={name}>
@@ -232,9 +244,9 @@ var ComponentDoc = React.createClass({
{prop.description && <Marked>{prop.description}</Marked>}
</div>
);
},
}
renderCompose: function(name) {
renderCompose(name) {
return (
<div className="prop" key={name}>
<Header level={4} className="propTitle" toSlug={name}>
@@ -242,9 +254,9 @@ var ComponentDoc = React.createClass({
</Header>
</div>
);
},
}
renderStylesheetProp: function(name, prop) {
renderStylesheetProp(name, prop) {
return (
<div className="prop" key={name}>
<h6 className="propTitle">
@@ -261,9 +273,9 @@ var ComponentDoc = React.createClass({
</h6>
</div>
);
},
}
renderStylesheetProps: function(stylesheetName) {
renderStylesheetProps(stylesheetName) {
var style = this.props.content.styles[stylesheetName];
this.extractPlatformFromProps(style.props);
return (
@@ -299,9 +311,9 @@ var ComponentDoc = React.createClass({
}
</div>
);
},
}
renderProps: function(props, composes) {
renderProps(props, composes) {
return (
<div className="props">
{(composes || []).map((name) =>
@@ -313,9 +325,9 @@ var ComponentDoc = React.createClass({
}
</div>
);
},
}
extractPlatformFromProps: function(props) {
extractPlatformFromProps(props) {
for (var key in props) {
var prop = props[key];
var description = prop.description || '';
@@ -326,9 +338,9 @@ var ComponentDoc = React.createClass({
prop.description = description;
prop.platforms = platforms;
}
},
}
renderMethod: function(method, namedTypes) {
renderMethod(method, namedTypes) {
return (
<Method
key={method.name}
@@ -339,11 +351,12 @@ var ComponentDoc = React.createClass({
examples={method.examples}
returns={method.returns}
namedTypes={namedTypes}
entityName={this.props.componentName}
/>
);
},
}
renderMethods: function(methods, namedTypes) {
renderMethods(methods, namedTypes) {
if (!methods || !methods.length) {
return null;
}
@@ -357,9 +370,9 @@ var ComponentDoc = React.createClass({
</div>
</span>
);
},
}
renderTypeDef: function(typedef, namedTypes) {
renderTypeDef(typedef, namedTypes) {
return (
<TypeDef
key={typedef.name}
@@ -372,9 +385,9 @@ var ComponentDoc = React.createClass({
namedTypes={namedTypes}
/>
);
},
}
renderTypeDefs: function(typedefs, namedTypes) {
renderTypeDefs(typedefs, namedTypes) {
if (!typedefs || !typedefs.length) {
return null;
}
@@ -388,9 +401,9 @@ var ComponentDoc = React.createClass({
</div>
</span>
);
},
}
render: function() {
render() {
var content = this.props.content;
this.extractPlatformFromProps(content.props);
const namedTypes = getNamedTypes(content.typedef);
@@ -406,11 +419,23 @@ var ComponentDoc = React.createClass({
</div>
);
}
});
}
var APIDoc = React.createClass({
class APIDoc extends React.Component {
constructor(props, context) {
super(props, context);
renderMethod: function(method, namedTypes) {
this.renderMethod = this.renderMethod.bind(this);
this.renderMethods = this.renderMethods.bind(this);
this.renderProperty = this.renderProperty.bind(this);
this.renderProperties = this.renderProperties.bind(this);
this.renderClasses = this.renderClasses.bind(this);
this.renderTypeDef = this.renderTypeDef.bind(this);
this.renderTypeDefs = this.renderTypeDefs.bind(this);
this.renderMainDescription = this.renderMainDescription.bind(this);
}
renderMethod(method, namedTypes) {
return (
<Method
key={method.name}
@@ -419,13 +444,13 @@ var APIDoc = React.createClass({
params={method.params}
modifiers={method.scope ? [method.scope] : method.modifiers}
examples={method.examples}
apiName={this.props.apiName}
entityName={this.props.apiName}
namedTypes={namedTypes}
/>
);
},
}
renderMethods: function(methods, namedTypes) {
renderMethods(methods, namedTypes) {
if (!methods.length) {
return null;
}
@@ -439,9 +464,9 @@ var APIDoc = React.createClass({
</div>
</span>
);
},
}
renderProperty: function(property) {
renderProperty(property) {
return (
<div className="prop" key={property.name}>
<Header level={4} className="propTitle" toSlug={property.name}>
@@ -457,9 +482,9 @@ var APIDoc = React.createClass({
</Marked>}
</div>
);
},
}
renderProperties: function(properties) {
renderProperties(properties) {
if (!properties || !properties.length) {
return null;
}
@@ -473,9 +498,9 @@ var APIDoc = React.createClass({
</div>
</span>
);
},
}
renderClasses: function(classes, namedTypes) {
renderClasses(classes, namedTypes) {
if (!classes || !classes.length) {
return null;
}
@@ -490,22 +515,22 @@ var APIDoc = React.createClass({
<Header level={2} toSlug={cls.name}>
class {cls.name}
</Header>
<ul>
<div>
{cls.docblock && <Marked>
{removeCommentsFromDocblock(cls.docblock)}
</Marked>}
{this.renderMethods(cls.methods, namedTypes)}
{this.renderProperties(cls.properties)}
</ul>
</div>
</span>
);
})}
</div>
</span>
);
},
}
renderTypeDef: function(typedef, namedTypes) {
renderTypeDef(typedef, namedTypes) {
return (
<TypeDef
key={typedef.name}
@@ -518,9 +543,9 @@ var APIDoc = React.createClass({
namedTypes={namedTypes}
/>
);
},
}
renderTypeDefs: function(typedefs, namedTypes) {
renderTypeDefs(typedefs, namedTypes) {
if (!typedefs || !typedefs.length) {
return null;
}
@@ -534,9 +559,9 @@ var APIDoc = React.createClass({
</div>
</span>
);
},
};
renderMainDescription: function(content) {
renderMainDescription(content) {
if (content.docblock) {
return (
<Marked>
@@ -552,9 +577,9 @@ var APIDoc = React.createClass({
);
}
return null;
},
}
render: function() {
render() {
var content = this.props.content;
if (!content.methods) {
throw new Error(
@@ -572,10 +597,18 @@ var APIDoc = React.createClass({
</div>
);
}
});
}
var Method = React.createClass({
renderTypehintRec: function(typehint) {
class Method extends React.Component {
constructor(props, context) {
super(props, context);
this.renderTypehint = this.renderTypehint.bind(this);
this.renderTypehintRec = this.renderTypehintRec.bind(this);
this.renderMethodExamples = this.renderMethodExamples.bind(this);
this.renderMethodParameters = this.renderMethodParameters.bind(this);
}
renderTypehintRec(typehint) {
if (typehint.type === 'simple') {
return typehint.value;
}
@@ -585,10 +618,9 @@ var Method = React.createClass({
}
return JSON.stringify(typehint);
}
},
renderTypehint: function(typehint) {
renderTypehint(typehint) {
if (typeof typehint === 'object' && typehint.name) {
return renderType(typehint);
}
@@ -599,9 +631,9 @@ var Method = React.createClass({
}
return this.renderTypehintRec(typehint);
},
}
renderMethodExamples: function(examples) {
renderMethodExamples(examples) {
if (!examples || !examples.length) {
return null;
}
@@ -621,9 +653,9 @@ var Method = React.createClass({
</div>
);
});
},
};
renderMethodParameters: function(params) {
renderMethodParameters(params) {
if (!params || !params.length) {
return null;
}
@@ -634,6 +666,7 @@ var Method = React.createClass({
if (!foundDescription) {
return null;
}
return (
<div>
<strong>Parameters:</strong>
@@ -651,7 +684,7 @@ var Method = React.createClass({
<td>
{param.optional ? '[' + param.name + ']' : param.name}
<br/><br/>
{renderTypeWithLinks(param.type, this.props.apiName, this.props.namedTypes)}
{renderTypeWithLinks(param.type, this.props.entityName, this.props.namedTypes)}
</td>
<td className="description"><Marked>{param.description}</Marked></td>
</tr>
@@ -661,9 +694,9 @@ var Method = React.createClass({
</table>
</div>
);
},
}
render: function() {
render() {
return (
<div className="prop">
<Header level={4} className="methodTitle" toSlug={this.props.name}>
@@ -690,11 +723,18 @@ var Method = React.createClass({
{this.renderMethodExamples(this.props.examples)}
</div>
);
},
});
}
}
var TypeDef = React.createClass({
renderProperties: function(properties) {
class TypeDef extends React.Component {
constructor(props, context) {
super(props, context);
this.renderProperties = this.renderProperties.bind(this);
this.renderValues = this.renderValues.bind(this);
}
renderProperties(properties) {
if (!properties || !properties.length) {
return null;
}
@@ -729,9 +769,9 @@ var TypeDef = React.createClass({
</table>
</div>
);
},
}
renderValues: function(values) {
renderValues(values) {
if (!values || !values.length) {
return null;
}
@@ -764,9 +804,9 @@ var TypeDef = React.createClass({
</table>
</div>
);
},
}
render: function() {
render() {
return (
<div className="prop">
<Header level={4} className="propTitle" toSlug={this.props.name}>
@@ -782,23 +822,24 @@ var TypeDef = React.createClass({
{this.renderValues(this.props.values)}
</div>
);
},
});
}
}
var Autodocs = React.createClass({
childContextTypes: {
permalink: PropTypes.string,
version: PropTypes.string
},
class Autodocs extends React.Component {
contsructor(props, context) {
super(props, context);
getChildContext: function() {
this.renderFullDescription = this.renderFullDescription.bind(this);
}
getChildContext() {
return {
permalink: this.props.metadata.permalink,
version: Metadata.config.RN_VERSION || 'next'
};
},
}
renderFullDescription: function(docs) {
renderFullDescription(docs) {
if (!docs.fullDescription) {
return;
}
@@ -808,39 +849,33 @@ var Autodocs = React.createClass({
<Marked>
{docs.fullDescription}
</Marked>
<Footer path={'docs/' + docs.componentName + '.md'} />
</div>
);
},
}
render: function() {
render() {
var metadata = this.props.metadata;
var docs = JSON.parse(this.props.children);
var content = docs.type === 'component' || docs.type === 'style' ?
<ComponentDoc content={docs} /> :
<APIDoc content={docs} apiName={metadata.title} />;
var content = docs.type === 'component' || docs.type === 'style'
? <ComponentDoc content={docs} componentName={metadata.title} />
: <APIDoc content={docs} apiName={metadata.title} />;
return (
<Site
section="docs"
category={metadata.category}
title={metadata.title} >
<section className="content wrap documentationContent">
<DocsSidebar metadata={metadata} />
<div className="inner-content">
<a id="content" />
<Header level={1}>{metadata.title}</Header>
{content}
<Footer path={metadata.path} />
{this.renderFullDescription(docs)}
<div className="docs-prevnext">
{metadata.previous && <a className="docs-prev" href={'docs/' + metadata.previous + '.html#content'}>&larr; Prev</a>}
{metadata.next && <a className="docs-next" href={'docs/' + metadata.next + '.html#content'}>Next &rarr;</a>}
</div>
</div>
</section>
<div className="inner-content" id="componentContent">
{content}
{this.renderFullDescription(docs)}
</div>
</Site>
);
}
});
}
Autodocs.childContextTypes = {
permalink: PropTypes.string,
version: PropTypes.string
};
module.exports = Autodocs;
@@ -15,19 +15,24 @@ var React = require('React');
var Site = require('Site');
var Hero = require('Hero');
var MetadataBlog = require('MetadataBlog');
var BlogPost = require('BlogPost');
var BlogPostExcerpt = require('BlogPostExcerpt');
var BlogPageLayout = React.createClass({
getPageURL: function(page) {
class BlogPageLayout extends React.Component {
constructor(props, context) {
super(props, context);
this.getPageURL = this.getPageURL.bind(this);
}
getPageURL(page) {
var url = '/react-native/blog/';
if (page > 0) {
url += 'page' + (page + 1) + '/';
}
return url + '#content';
},
}
render: function() {
render() {
var perPage = this.props.metadata.perPage;
var page = this.props.metadata.page;
return (
@@ -55,6 +60,6 @@ var BlogPageLayout = React.createClass({
</Site>
);
}
});
}
module.exports = BlogPageLayout;
@@ -19,8 +19,8 @@ var BlogPost = require('BlogPost');
var BlogPostHeader = require('BlogPostHeader');
var Marked = require('Marked');
var BlogPostLayout = React.createClass({
render: function() {
class BlogPostLayout extends React.Component {
render() {
return (
<Site
section="blog"
@@ -39,6 +39,6 @@ var BlogPostLayout = React.createClass({
</Site>
);
}
});
}
module.exports = BlogPostLayout;
+51
View File
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule DocsLayout
*/
'use strict';
var DocsSidebar = require('DocsSidebar');
var EjectBanner = require('EjectBanner');
var Footer = require('Footer');
var Header = require('Header');
var Marked = require('Marked');
var Metadata = require('Metadata');
var React = require('React');
var PropTypes = require('prop-types');
var Site = require('Site');
class DocsLayout extends React.Component {
getChildContext() {
return {
permalink: this.props.metadata.permalink,
version: Metadata.config.RN_VERSION || 'next'
};
}
render() {
var metadata = this.props.metadata;
var content = this.props.children;
return (
<Site
category={metadata.category}
title={metadata.title} >
<div className="inner-content" id="componentContent">
<Marked>{content}</Marked>
</div>
</Site>
);
}
}
DocsLayout.childContextTypes = {
permalink: PropTypes.string,
version: PropTypes.string
};
module.exports = DocsLayout;
@@ -15,30 +15,28 @@ var React = require('React');
var PropTypes = require('prop-types');
var Site = require('Site');
var support = React.createClass({
childContextTypes: {
permalink: PropTypes.string
},
getChildContext: function() {
class support extends React.Component {
getChildContext() {
return {permalink: this.props.metadata.permalink};
},
}
render: function() {
render() {
var metadata = this.props.metadata;
var content = this.props.children;
return (
<Site
section={metadata.section}
title={metadata.title} >
<section className="content wrap documentationContent nosidebar">
<div className="inner-content">
<Marked>{content}</Marked>
</div>
</section>
<div className="inner-content">
<Marked>{content}</Marked>
</div>
</Site>
);
}
});
}
support.childContextTypes = {
permalink: PropTypes.string
};
module.exports = support;
@@ -12,8 +12,8 @@
var React = require('React');
var RedirectLayout = React.createClass({
render: function() {
class RedirectLayout extends React.Component {
render() {
var destinationUrl = this.props.metadata.destinationUrl;
return (
@@ -32,6 +32,6 @@ var RedirectLayout = React.createClass({
</html>
);
}
});
}
module.exports = RedirectLayout;
+4977
View File
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
{
"scripts": {
"build": "node server/build.js",
"test": "jest"
},
"dependencies": {
"babel-core": "^6.6.4",
"babel-plugin-transform-flow-strip-types": "^6.21.0",
"bluebird": "^2.9.21",
"connect": "2.8.3",
"deep-assign": "^2.0.0",
"feed": "^0.3.0",
"filepath": "^1.1.0",
"flow-parser": "^0.32.0",
"fs-extra": "^4.0.2",
"fs.extra": "^1.3.2",
"glob": "6.0.4",
"glob-promise": "^3.2.0",
"jsdoc-api": "^1.1.0",
"jsdom": "^11.1.0",
"jstransform": "11.0.3",
"memory-cache": "^0.1.6",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"node-fetch": "^1.7.3",
"optimist": "0.6.0",
"prop-types": "^15.5.8",
"react": "~0.13.0",
"react-docgen": "3.0.0-beta5",
"react-page-middleware": "0.4.1",
"remove-markdown": "^0.1.0",
"request": "^2.69.0",
"semver-compare": "^1.0.0",
"shelljs": "^0.7.8"
},
"devDependencies": {
"front-matter": "^2.1.2",
"jest": "^15.1.1"
}
}
+150
View File
@@ -0,0 +1,150 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
'use strict';
const fs = require('fs');
const path = require('path');
const convert = require('../convert.js');
const http = require('http');
const extractDocs = require('../extractDocs');
const docsList = require('../docsList');
const glob = require('glob');
const DOCS_MD_DIR = path.join(__dirname, '/../../src/react-native');
const BUILD_DIR = path.join(__dirname, '/../../build/react-native');
function splitHeader(content) {
var lines = content.split(/\r?\n/);
for (var i = 1; i < lines.length - 1; ++i) {
if (lines[i] === '---') {
break;
}
}
return {
header: i < lines.length - 1 ?
lines.slice(1, i + 1).join('\n') : null,
content: lines.slice(i + 1).join('\n')
};
}
function extractMetadata(content) {
var metadata = {};
var both = splitHeader(content);
var lines = both.header.split('\n');
for (var i = 0; i < lines.length - 1; ++i) {
var keyvalue = lines[i].split(':');
var key = keyvalue[0].trim();
var value = keyvalue.slice(1).join(':').trim();
// Handle the case where you have "Community #10"
try { value = JSON.parse(value); } catch(e) { }
metadata[key] = value;
}
return {metadata: metadata, rawContent: both.content};
}
function rmFile(file) {
try {
fs.unlinkSync(file);
} catch(e) {
/* seriously, unlink throws when the file doesn't exist :( */
}
}
let extractedDocs;
beforeAll(() => {
glob(DOCS_MD_DIR + '/**/*.*', function(er, files) {
files.forEach(rmFile);
extractedDocs = extractDocs();
require('../build');
});
});
describe('extractDocs.js', () => {
it('doc has frontmatter', () => {
const firstDoc = extractedDocs[0];
expect(firstDoc.slice(0, 3) === '---').toBeTruthy();
});
it ('extracted expected number of docs', () => {
const all = docsList.components
.concat(docsList.apis)
.concat(docsList.stylesWithPermalink);
expect(extractedDocs.length == all.length);
})
})
describe('convert.js', () => {
it ('converted a component', () => {
const files = glob.sync(DOCS_MD_DIR + '/**/*.*');
expect(files.length).toBeGreaterThan(0);
});
it ('converted a component with DocsLayout', () => {
const files = glob.sync(DOCS_MD_DIR + '/**/*.*');
let foundDocsLayout = false;
files.forEach(function (file) {
const content = fs.readFileSync(file, {encoding: 'utf8'});
if (content.indexOf("var Layout = require(\"DocsLayout\");") !== -1) {
foundDocsLayout = true;
}
});
expect(foundDocsLayout).toBeTruthy();
});
it ('converted a component with AutodocsLayout', () => {
const files = glob.sync(DOCS_MD_DIR + '/**/*.*');
let foundDocsLayout = false;
files.forEach(function (file) {
const content = fs.readFileSync(file, {encoding: 'utf8'});
if (content.indexOf("var Layout = require(\"AutodocsLayout\");") !== -1) {
foundDocsLayout = true;
}
});
expect(foundDocsLayout).toBeTruthy();
});
})
describe('generate.js', () => {
it ('rendered all webpages', () => {
const files = glob.sync(DOCS_MD_DIR + '/**/*.*');
files.forEach(function (file) {
const targetFile = file.replace(/^src/, 'build');
const content = fs.readFileSync(targetFile, {encoding: 'utf8'});
expect(content.length).toBeGreaterThan(0);
});
});
})
describe('build.js', () => {
it ('rendered files', () => {
const files = glob.sync(DOCS_MD_DIR + '/**/*.*');
expect(files.length).toBeGreaterThan(0);
});
it ('rendered all files', () => {
const files = glob.sync(DOCS_MD_DIR + '/**/*.*');
files.forEach(function (file) {
const targetFile = file.replace(/^src/, 'build').replace(/\.html$/, '.md');;
const content = fs.readFileSync(targetFile, {encoding: 'utf8'});
expect(content.length).toBeGreaterThan(0);
});
});
it ('rendered markdown contains frontmatter', () => {
const files = glob.sync(BUILD_DIR + '/**/*.md');
files.forEach(function (file) {
const content = fs.readFileSync(file, {encoding: 'utf8'});
expect(content.slice(0, 3) === '---').toBeTruthy();
});
});
})
+32
View File
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
"use strict";
var fs = require("fs");
const categoriesMetadataFile = "build/sidebar-metadata.json";
const categories = JSON.parse(fs.readFileSync(categoriesMetadataFile));
const sidebarFile = "../website/sidebars.json";
let sidebarContent = { SIDEBAR_AUTODOCS_SECTION: {} };
if (fs.existsSync(sidebarFile)) {
sidebarContent = JSON.parse(fs.readFileSync(sidebarFile));
}
let sortedCategories = {};
for (var category in categories) {
const sortedCategory = categories[category].sort();
sortedCategories[category] = sortedCategory;
}
const newSidebarContent = Object.assign({}, sidebarContent, {
API: sortedCategories
});
fs.writeFileSync(sidebarFile, JSON.stringify(newSidebarContent));
console.log(`Updated ${sidebarFile}`);
+745
View File
@@ -0,0 +1,745 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
"use strict";
const fetch = require("node-fetch");
const filepath = require("filepath");
const fm = require("front-matter");
const fs = require("fs-extra");
const glob = require("glob-promise");
const jsdom = require("jsdom");
const mkdirp = require("mkdirp");
const Promise = require("bluebird");
const shell = require("shelljs");
const convert = require("./convert.js");
const slugify = require("../core/slugify");
const CWD = process.cwd();
const AUTODOCS_PREFIX = "autogen_";
const MARKDOWN_EXTENSION = "md";
const GIT_USER = "hramos"; //process.env.GIT_USER;
const GITHUB_USERNAME = "facebook"; // process.env.GITHUB_USERNAME;
const GITHUB_REPONAME = "react-native"; // process.env.GITHUB_REPONAME;
const remoteBranch = `https://${GIT_USER}@github.com/${GITHUB_USERNAME}/${GITHUB_REPONAME}.git`;
const DOCS_CHECKOUT_DIR = `${GITHUB_REPONAME}-docs`;
const RELEASES_CHECKOUT_DIR = `${GITHUB_REPONAME}-releases`;
const TAGS_CHECKOUT_DIR = `${GITHUB_REPONAME}-tags`;
const BUILD_DIR = "build";
const DOCS_DIR = "versioned_docs";
const SIDEBAR_DIR = "versioned_sidebars";
const { JSDOM } = jsdom;
let versionedDocsBlacklist = [];
// Start up a server. Don't forget to close the connection when done.
const server = require("./server.js");
server.noconvert = true;
const argv = require("minimist")(process.argv.slice(2), {
alias: {
c: "clean"
},
default: {
clean: false
}
});
function extractDocVersionFromFilename(file) {
const re = new RegExp("/([0-9]*[.]?[0-9]*)");
return file.match(re)[1];
}
function extractComponentNameFromFilename(file) {
const re = new RegExp("([A-Za-z-]*).html");
return file.match(re)[1];
}
function extractMarkdownFromHTMLDocs(file) {
if (file.indexOf("404") !== -1) {
return {};
}
// console.log(`Processing ${file}`);
return JSDOM.fromFile(filepath.create(file).toString()).then(dom => {
const body = bodyContentFromDOM(dom);
if (!body) {
return {};
}
const componentName = extractComponentNameFromFilename(file);
const version = extractDocVersionFromFilename(file);
const markdown = generateMarkdown(componentName, body, version);
const frontmatter = fm(markdown);
return { frontmatter, markdown };
});
}
// DOM FORMATTING FUNCS
function bodyContentFromDOM(dom) {
const el = dom.window.document.querySelector(".inner-content");
if (el) {
return el.innerHTML;
} else {
return null;
}
}
function componentNameFromDOM(dom) {
const el = dom.window.document.querySelector("h1");
if (el) {
let componentName = el.innerHTML;
const re = new RegExp("docs/([A-Za-z]*)(.html)");
const parsedTitle = el.innerHTML.match(re);
if (parsedTitle) {
componentName = parsedTitle[1];
}
return componentName;
} else {
return "Component";
}
}
function componentCategoryFromDOM(dom) {
const el = dom.window.document.querySelector('meta[property="rn:category"]');
if (el) {
return el.content;
} else {
return "Components";
}
}
/**
* Generates a markdown formatted file, including frontmatter.
*
* @param {*} dom
*/
function generateMarkdownFromDOM(dom) {
const body = bodyContentFromDOM(dom);
if (!body) {
return;
}
const componentName = componentNameFromDOM(dom);
const slug = slugify(componentName);
const markdown = [
"---",
"id: " + slug,
"title: " + componentName,
"---",
body
]
.filter(function(line) {
return line;
})
.join("\n");
return markdown;
}
function generateMarkdown(componentName, body, version) {
const slug = slugify(componentName);
let markdown = ["---", "id: " + slug, "title: " + componentName, "---", body];
if (version) {
markdown = [
"---",
"id: version-" + version + "-" + slug,
"title: " + componentName,
"original_id: " + slug,
"---",
body
];
}
return markdown
.filter(function(line) {
return line;
})
.join("\n");
}
function generateMetatadaFile(categories) {
const categoriesMetadataFile = `${BUILD_DIR}/sidebar-metadata.json`;
return fs.outputFile(categoriesMetadataFile, JSON.stringify(categories));
}
// END DOM
function runChecks() {
if (!shell.which("git")) {
shell.echo("Sorry, this script requires git");
shell.exit(1);
}
if (!GIT_USER) {
shell.echo("GIT_USER undefined.");
shell.exit(1);
}
if (!GITHUB_USERNAME) {
shell.echo("GITHUB_USERNAME undefined.");
shell.exit(1);
}
if (!GITHUB_REPONAME) {
shell.echo("GITHUB_REPONAME undefined.");
shell.exit(1);
}
console.log("Everything looks good, generating docs.");
}
function cleanFiles() {
return fs.remove(BUILD_DIR);
}
function generateDocsFromMaster() {
let docsMetadata = {};
const pathToGitCheckout = filepath.create(CWD, BUILD_DIR, DOCS_CHECKOUT_DIR);
const p = Promise.resolve()
.then(() => {
return fs.ensureDir(pathToGitCheckout.toString());
})
.then(() => {
shell.cd(pathToGitCheckout.toString());
return fs.exists(pathToGitCheckout.append(`.git`).toString());
})
.then(gitCheckoutExists => {
if (!gitCheckoutExists) {
shell.exec(`git init`).code !== 0;
if (shell.exec(`git remote add origin ${remoteBranch}`).code !== 0) {
throw new Error("Error: git remote failed");
}
}
return;
})
.then(() => {
if (shell.exec(`git fetch`).code !== 0) {
throw new Error("Error: git fetch failed");
}
shell.exec(`git config core.sparsecheckout true`).code !== 0;
shell.exec(`echo "docs/*" >> .git/info/sparse-checkout`).code !== 0;
if (shell.exec(`git checkout master`).code !== 0) {
throw new Error("Error: git checkout failed");
}
return;
})
.then(() => {
return glob("docs/**/*.md");
})
.then(files => {
// Parse every Markdown file and build out our metadata, which can be used later on to generate both the markdown docs in the final location, as well as our sidebar metadata files.
let seq = Promise.resolve();
files.forEach(file => {
console.log("Parsing " + file);
// e.g. docs/view.md
seq = seq
.then(() => {
return fs.readFile(file, "utf8");
})
.then(originalMarkdown => {
const frontmatter = fm(originalMarkdown);
if (frontmatter.attributes.layout === "docs") {
docsMetadata = Object.assign({}, docsMetadata, {
[frontmatter.attributes.id]: {
metadata: frontmatter.attributes,
body: frontmatter.body
}
});
if (
frontmatter.attributes.category !== "Components" &&
frontmatter.attributes.category !== "APIs"
) {
// Let's make sure we don't version anything outside of the Components/APIs categories. This is used later on when we parse old releases.
versionedDocsBlacklist.push(frontmatter.attributes.id);
}
}
return;
});
});
return seq;
})
.then(() => {
// Generate sidebar file...
const pathToSidebarFile = filepath.create(
CWD,
"..",
"website",
"sidebars.json"
);
let sidebar = {
docs: {
Guides: [],
"Guides (iOS)": [],
"Guides (Android)": [],
APIs: [],
Components: [],
Contributing: [],
"The Basics": []
}
};
Object.keys(docsMetadata).forEach(documentId => {
let category = docsMetadata[documentId].metadata.category;
if (category === "components") {
category = "Components";
}
// TODO: This is naive. Docs should be in order, and the metadata attribute 'next' lets us know what the order should be.
sidebar["docs"][category].push(documentId);
});
return fs.outputFile(
pathToSidebarFile.toString(),
JSON.stringify(sidebar)
);
})
.then(() => {
// Generate markdown files...
let seq = Promise.resolve();
Object.keys(docsMetadata).forEach(documentId => {
const metadata = docsMetadata[documentId].metadata;
const body = docsMetadata[documentId].body;
const transformedMarkdown = [
"---",
"id: " + metadata.id,
"title: " + metadata.title,
"---",
body
]
.filter(function(line) {
return line;
})
.join("\n");
seq = seq.then(() => {
const pathToMarkdownFile = filepath.create(
CWD,
"..",
"docs",
metadata.id + ".md"
);
return fs.outputFile(
pathToMarkdownFile.toString(),
transformedMarkdown
);
});
});
return seq;
});
// STATUS: This is ready, aside from the weird sidebar ordering.
// Next to do: do the same for releases, below:
return p;
}
// Must be called after checkOutDocs()
// Check out gh-pages branch
function generateDocsFromPastReleases() {
const pathToGitCheckout = filepath.create(
CWD,
BUILD_DIR,
RELEASES_CHECKOUT_DIR
);
let blacklist = [
"404",
"index",
"help",
"users",
"showcase",
"support",
"versions"
];
let docsVersions = {};
const p = Promise.resolve()
.then(() => {
return fs.ensureDir(pathToGitCheckout.toString());
})
.then(() => {
shell.cd(pathToGitCheckout.toString());
shell.echo(shell.pwd());
return fs.exists(pathToGitCheckout.append(`.git`).toString());
})
.then(gitCheckoutExists => {
if (!gitCheckoutExists) {
shell.exec(`git init`).code !== 0;
if (shell.exec(`git remote add origin ${remoteBranch}`).code !== 0) {
throw new Error("Error: git remote failed");
}
}
return;
})
.then(() => {
if (shell.exec(`git fetch`).code !== 0) {
throw new Error("Error: git fetch failed");
}
shell.exec(`git config core.sparsecheckout true`).code !== 0;
shell.exec(`echo "releases/*" >> .git/info/sparse-checkout`).code !== 0;
if (shell.exec(`git checkout gh-pages`).code !== 0) {
throw new Error("Error: git checkout failed");
}
return;
})
.then(() => {
return glob("releases/**/*.html");
})
.then(files => {
// Parse every Markdown file and build out our metadata, which can be used later on to generate both the markdown docs in the final location, as well as our sidebar metadata files.
let seq = Promise.resolve();
files.forEach(file => {
console.log("Parsing " + file);
// e.g. docs/view.md
seq = seq
.then(() => {
return extractMarkdownFromHTMLDocs(file);
})
.then(res => {
if (res.markdown === undefined) {
console.log("Skipping " + file + " for lack of markdown.");
return;
}
const version = extractDocVersionFromFilename(file);
if (!version) {
console.log("Skipping " + file + " for lack of version.");
return;
}
const frontmatter = res.frontmatter;
if (
!blacklist.includes(frontmatter.attributes.original_id) &&
!versionedDocsBlacklist.includes(
frontmatter.attributes.original_id
)
) {
if (!docsVersions.hasOwnProperty(version)) {
docsVersions[version] = {};
}
docsVersions[version] = Object.assign({}, docsVersions[version], {
[frontmatter.attributes.id]: {
metadata: frontmatter.attributes,
body: frontmatter.body,
version
}
});
}
return;
});
});
return seq;
})
.then(() => {
let seq = Promise.resolve();
Object.keys(docsVersions).forEach(version => {
seq.then(() => {
// Generate sidebar file...
const docsMetadata = docsVersions[version];
let documents = Object.keys(docsMetadata);
// TODO: We don't have old docs' categories
let sidebar = {
["version-" + version + "-docs"]: {
Docs: documents
}
};
const pathToSidebarFile = filepath.create(
CWD,
"..",
"website",
"versioned_sidebars",
"version-" + version + "-sidebars.json"
);
return fs.outputFile(
pathToSidebarFile.toString(),
JSON.stringify(sidebar)
);
});
return seq;
});
})
.then(() => {
// Generate markdown files...
let seq = Promise.resolve();
Object.keys(docsVersions).forEach(version => {
const docsMetadata = docsVersions[version];
Object.keys(docsMetadata).forEach(documentId => {
const metadata = docsMetadata[documentId].metadata;
const body = docsMetadata[documentId].body;
const transformedMarkdown = [
"---",
"id: " + metadata.id,
"original_id: " + metadata.original_id,
"title: " + metadata.title,
"---",
body
]
.filter(function(line) {
return line;
})
.join("\n");
seq = seq.then(() => {
const pathToMarkdownFile = filepath.create(
CWD,
"..",
"website",
"versioned_docs",
"version-" + version,
metadata.original_id + ".md"
);
return fs.outputFile(
pathToMarkdownFile.toString(),
transformedMarkdown
);
});
});
});
return seq;
})
.then(() => {
console.log("Finished with releases");
return;
});
return p;
}
// Attempt to run autodoc generation... on every single... release.
function generateDocsFromGitTag(tag) {
const pathToGitCheckout = filepath.create(CWD, BUILD_DIR, TAGS_CHECKOUT_DIR);
let blacklist = [
"404",
"index",
"help",
"users",
"showcase",
"support",
"versions"
];
let docsVersions = {};
const p = Promise.resolve()
.then(() => {
return fs.ensureDir(pathToGitCheckout.toString());
})
.then(() => {
shell.cd(pathToGitCheckout.toString());
shell.echo(shell.pwd());
return fs.exists(pathToGitCheckout.append(`.git`).toString());
})
.then(gitCheckoutExists => {
if (!gitCheckoutExists) {
shell.exec(`git init`).code !== 0;
if (shell.exec(`git remote add origin ${remoteBranch}`).code !== 0) {
throw new Error("Error: git remote failed");
}
}
return;
})
.then(() => {
if (shell.exec(`git fetch`).code !== 0) {
throw new Error("Error: git fetch failed");
}
shell.exec(`git config core.sparsecheckout false`).code !== 0;
if (shell.exec(`git checkout ${tag}`).code !== 0) {
throw new Error("Error: git checkout failed for " + tag);
}
return;
})
.then(() => {
return glob("releases/**/*.html");
})
.then(files => {
// Parse every Markdown file and build out our metadata, which can be used later on to generate both the markdown docs in the final location, as well as our sidebar metadata files.
let seq = Promise.resolve();
files.forEach(file => {
console.log("Parsing " + file);
// e.g. docs/view.md
seq = seq
.then(() => {
return extractMarkdownFromHTMLDocs(file);
})
.then(res => {
if (res.markdown === undefined) {
console.log("Skipping " + file + " for lack of markdown.");
return;
}
const version = extractDocVersionFromFilename(file);
if (!version) {
console.log("Skipping " + file + " for lack of version.");
return;
}
const frontmatter = res.frontmatter;
if (
!blacklist.includes(frontmatter.attributes.original_id) &&
!versionedDocsBlacklist.includes(
frontmatter.attributes.original_id
)
) {
if (!docsVersions.hasOwnProperty(version)) {
docsVersions[version] = {};
}
docsVersions[version] = Object.assign({}, docsVersions[version], {
[frontmatter.attributes.id]: {
metadata: frontmatter.attributes,
body: frontmatter.body,
version
}
});
}
return;
});
});
return seq;
})
.then(() => {
let seq = Promise.resolve();
Object.keys(docsVersions).forEach(version => {
seq.then(() => {
// Generate sidebar file...
const docsMetadata = docsVersions[version];
let documents = Object.keys(docsMetadata);
// TODO: We don't have old docs' categories
let sidebar = {
["version-" + version + "-docs"]: {
Docs: documents
}
};
const pathToSidebarFile = filepath.create(
CWD,
"..",
"website",
"versioned_sidebars",
"version-" + version + "-sidebars.json"
);
return fs.outputFile(
pathToSidebarFile.toString(),
JSON.stringify(sidebar)
);
});
return seq;
});
})
.then(() => {
// Generate markdown files...
let seq = Promise.resolve();
Object.keys(docsVersions).forEach(version => {
const docsMetadata = docsVersions[version];
Object.keys(docsMetadata).forEach(documentId => {
const metadata = docsMetadata[documentId].metadata;
const body = docsMetadata[documentId].body;
const transformedMarkdown = [
"---",
"id: " + metadata.id,
"original_id: " + metadata.original_id,
"title: " + metadata.title,
"---",
body
]
.filter(function(line) {
return line;
})
.join("\n");
seq = seq.then(() => {
const pathToMarkdownFile = filepath.create(
CWD,
"..",
"website",
"versioned_docs",
"version-" + version,
metadata.original_id + ".md"
);
return fs.outputFile(
pathToMarkdownFile.toString(),
transformedMarkdown
);
});
});
});
return seq;
})
.then(() => {
console.log("Finished with releases");
return;
});
return p;
}
if (argv.clean) {
cleanFiles();
}
runChecks();
console.log("Calling generateDocsFromMaster");
generateDocsFromMaster()
.then(() => {
console.log("Calling generateDocsFromPastReleases");
return generateDocsFromPastReleases();
})
.then(() => {
console.log("Finished");
shell.exec("say Finished");
process.exit(0);
});
/**
* Check out gh-pages branch, cd releases/
* For each version,
* For each HTML,
* Parse out jsdom
* Get body contents
* Generate frontmatter
* Save into versioned_docs
* Then finally generate sidebar files for each version
*
*/
+36
View File
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
"use strict";
const { cd, cp, echo, exec, exit, ls, mkdir, rm, which } = require("shelljs");
cd(process.cwd());
cd(`../docs`);
rm(`-rf`, `autogen_*.md`);
cd(`../docgen`);
rm(`-rf`, `build`);
rm(`-rf`, `src`);
mkdir(`-p`, `build`);
mkdir(`-p`, `src`);
if (exec(`node server/generate.js`).code !== 0) {
echo(`Error: Rendering Autodocs to HTML failed`);
exit(1);
}
if (exec(`node server/build-autodocs-markdown.js`).code !== 0) {
echo(`Error: Generating Autodocs Markdown failed`);
exit(1);
}
if (exec(`node server/build-autodocs-sidebar.js`).code !== 0) {
echo(`Error: Generating Autodocs Sidebar failed`);
exit(1);
}
@@ -9,14 +9,14 @@
'use strict';
var fs = require('fs')
var fs = require('fs');
var glob = require('glob');
var mkdirp = require('mkdirp');
var optimist = require('optimist');
var path = require('path');
var removeMd = require('remove-markdown');
var extractDocs = require('./extractDocs');
var cache = require('memory-cache');
var optimist = require('optimist');
var argv = optimist.argv;
function splitHeader(content) {
@@ -36,7 +36,7 @@ function splitHeader(content) {
function rmFile(file) {
try {
fs.unlinkSync(file);
} catch(e) {
} catch (e) {
/* seriously, unlink throws when the file doesn't exist :( */
}
}
@@ -63,7 +63,7 @@ function extractMetadata(content) {
var key = keyvalue[0].trim();
var value = keyvalue.slice(1).join(':').trim();
// Handle the case where you have "Community #10"
try { value = JSON.parse(value); } catch(e) { }
try { value = JSON.parse(value); } catch (e) { }
metadata[key] = value;
}
return {metadata: metadata, rawContent: both.content};
@@ -77,7 +77,7 @@ function buildFile(layout, metadata, rawContent) {
'var React = require("React");',
'var Layout = require("' + layout + '");',
rawContent && 'var content = ' + backtickify(rawContent) + ';',
'var Post = React.createClass({',
'var Page = React.createClass({',
rawContent && ' statics: { content: content },',
' render: function() {',
' return (',
@@ -87,7 +87,7 @@ function buildFile(layout, metadata, rawContent) {
' );',
' }',
'});',
'module.exports = Post;'
'module.exports = Page;'
].filter(e => e).join('\n');
}
@@ -97,23 +97,19 @@ function execute(options) {
}
var DOCS_MD_DIR = '../docs/';
var BLOG_MD_DIR = '../blog/';
var CONFIG_JSON_DIR = '../';
glob.sync('src/react-native/docs/*.*').forEach(rmFile);
glob.sync('src/react-native/blog/*.*').forEach(rmFile);
glob.sync('../blog/img/*.*').forEach(file => {
writeFileAndCreateFolder(
'src/react-native/blog/img/' + path.basename(file),
fs.readFileSync(file)
);
});
var metadatas = {
files: [],
};
function handleMarkdown(content, filename) {
if (!content) {
console.log(`Empty content for ${filename}`);
return;
}
if (content.slice(0, 3) !== '---') {
return;
}
@@ -145,28 +141,9 @@ function execute(options) {
// Rendering docs can take up to 8 seconds. We wait until /docs/ are
// requested before doing so, then we store the results in memory to
// speed up subsequent requests.
var extractedDocs = cache.get('extractedDocs');
if (!extractedDocs) {
extractedDocs = extractDocs();
cache.put('extractedDocs', extractedDocs);
}
extractedDocs.forEach(function(content) {
extractDocs().forEach(function(content) {
handleMarkdown(content, null);
});
var files = glob.sync(DOCS_MD_DIR + '**/*.*');
files.forEach(function(file) {
var extension = path.extname(file);
if (extension === '.md' || extension === '.markdown') {
var content = fs.readFileSync(file, {encoding: 'utf8'});
handleMarkdown(content, path.basename(file));
}
if (extension === '.json') {
var content = fs.readFileSync(file, {encoding: 'utf8'});
metadatas[path.basename(file, '.json')] = JSON.parse(content);
}
});
}
// we need to pass globals for the components to be configurable
@@ -180,81 +157,8 @@ function execute(options) {
metadatas.config[key] = process.env[key];
});
// load showcase apps into metadata
var showcaseApps = JSON.parse(fs.readFileSync(
path.basename(CONFIG_JSON_DIR + 'showcase.json'),
{encoding: 'utf8'}
));
metadatas.showcaseApps = showcaseApps;
fs.writeFileSync(
'core/metadata.js',
'/**\n' +
' * @generated\n' +
' * @providesModule Metadata\n' +
' */\n' +
'module.exports = ' + JSON.stringify(metadatas, null, 2) + ';'
);
files = glob.sync(BLOG_MD_DIR + '**/*.md');
const metadatasBlog = {
files: [],
};
files.sort().reverse().forEach(file => {
// Transform
// 2015-08-13-blog-post-name-0.5.md
// into
// 2015/08/13/blog-post-name-0-5.html
var filePath = path.basename(file)
.replace('-', '/')
.replace('-', '/')
.replace('-', '/')
// react-middleware is broken with files that contains multiple . like react-0.14.js
.replace(/\./g, '-')
.replace(/\-md$/, '.html');
// Extract 2015-08-13 from 2015/08/13/blog-post-name-0-5.html
var match = filePath.match(/([0-9]+)\/([0-9]+)\/([0-9]+)/);
var year = match[1];
var month = match[2];
var day = match[3];
var publishedAt = year + '-' + month + '-' + day;
var res = extractMetadata(fs.readFileSync(file, {encoding: 'utf8'}));
var rawContent = res.rawContent;
var excerpt = removeMd(rawContent).trim().split('\n')[0];
var metadata = Object.assign({path: filePath, content: rawContent, publishedAt: publishedAt, excerpt: excerpt}, res.metadata);
metadatasBlog.files.push(metadata);
writeFileAndCreateFolder(
'src/react-native/blog/' + filePath.replace(/\.html$/, '.js'),
buildFile('BlogPostLayout', metadata, rawContent)
);
});
var perPage = 15;
for (var page = 0; page < Math.ceil(metadatasBlog.files.length / perPage); ++page) {
writeFileAndCreateFolder(
'src/react-native/blog' + (page > 0 ? '/page' + (page + 1) : '') + '/index.js',
buildFile('BlogPageLayout', { page: page, perPage: perPage })
);
}
fs.writeFileSync(
'core/metadata-blog.js',
'/**\n' +
' * @generated\n' +
' * @providesModule MetadataBlog\n' +
' */\n' +
'module.exports = ' + JSON.stringify(metadatasBlog, null, 2) + ';'
);
fs.writeFileSync(
'server/metadata-blog.json',
JSON.stringify(metadatasBlog, null, 2)
);
console.log(`conversion finished.`)
return JSON.stringify(metadatas, null, 2);
}
if (argv.convert) {
File diff suppressed because it is too large Load Diff
@@ -12,6 +12,7 @@
const components = [
'../Libraries/Components/ActivityIndicator/ActivityIndicator.js',
'../Libraries/Components/Button.js',
'../Libraries/Components/CheckBox/CheckBox.android.js',
'../Libraries/Components/DatePicker/DatePickerIOS.ios.js',
'../Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js',
'../Libraries/Lists/FlatList.js',
@@ -51,7 +52,6 @@ const components = [
const apis = [
'../Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js',
'../Libraries/ActionSheetIOS/ActionSheetIOS.js',
'../Libraries/AdSupport/AdSupportIOS.js',
'../Libraries/Alert/Alert.js',
'../Libraries/Alert/AlertIOS.js',
'../Libraries/Animated/src/AnimatedImplementation.js',
@@ -102,8 +102,7 @@ const stylesWithPermalink = [
'../Libraries/StyleSheet/TransformPropTypes.js',
'../Libraries/Components/View/ShadowPropTypesIOS.js',
'../Libraries/Components/View/ViewPropTypes.js',
...stylesForEmbed,
];
].concat(stylesForEmbed);
const viewPropTypes = '../Libraries/Components/View/ViewPropTypes.js';
@@ -113,4 +112,4 @@ module.exports = {
stylesWithPermalink,
stylesForEmbed,
viewPropTypes,
};
};
@@ -7,23 +7,23 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
"use strict";
const babel = require('babel-core');
const deepAssign = require('deep-assign');
const docgen = require('react-docgen');
const docgenHelpers = require('./docgenHelpers');
const docsList = require('./docsList');
const fs = require('fs');
const jsDocs = require('../jsdocs/jsdocs.js');
const jsdocApi = require('jsdoc-api');
const path = require('path');
const recast = require('recast');
const slugify = require('../core/slugify');
const babel = require("babel-core");
const deepAssign = require("deep-assign");
const docgen = require("react-docgen");
const docgenHelpers = require("./docgenHelpers");
const docsList = require("./docsList"); // TODO: Use the actual docsList from the checked out tag...
const fs = require("fs");
const jsDocs = require("../jsdocs/jsdocs.js");
const jsdocApi = require("jsdoc-api");
const path = require("path");
const recast = require("recast");
const slugify = require("../core/slugify");
const ANDROID_SUFFIX = 'android';
const CROSS_SUFFIX = 'cross';
const IOS_SUFFIX = 'ios';
const ANDROID_SUFFIX = "android";
const CROSS_SUFFIX = "cross";
const IOS_SUFFIX = "ios";
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
@@ -40,25 +40,25 @@ function removeExtName(filepath) {
function getNameFromPath(filepath) {
filepath = removeExtName(filepath);
if (filepath === 'LayoutPropTypes') {
return 'Layout Props';
} else if (filepath === 'ShadowPropTypesIOS') {
return 'Shadow Props';
} else if (filepath === 'TransformPropTypes') {
return 'Transforms';
} else if (filepath === 'TabBarItemIOS') {
return 'TabBarIOS.Item';
} else if (filepath === 'AnimatedImplementation') {
return 'Animated';
if (filepath === "LayoutPropTypes") {
return "Layout Props";
} else if (filepath === "ShadowPropTypesIOS") {
return "Shadow Props";
} else if (filepath === "TransformPropTypes") {
return "Transforms";
} else if (filepath === "TabBarItemIOS") {
return "TabBarIOS.Item";
} else if (filepath === "AnimatedImplementation") {
return "Animated";
}
return filepath;
}
function getPlatformFromPath(filepath) {
filepath = removeExtName(filepath);
if (endsWith(filepath, 'Android')) {
if (endsWith(filepath, "Android")) {
return ANDROID_SUFFIX;
} else if (endsWith(filepath, 'IOS')) {
} else if (endsWith(filepath, "IOS")) {
return IOS_SUFFIX;
}
return CROSS_SUFFIX;
@@ -67,33 +67,30 @@ function getPlatformFromPath(filepath) {
// Add methods that should not appear in the components documentation.
const methodsBlacklist = [
// Native methods mixin.
'getInnerViewNode',
'setNativeProps',
"getInnerViewNode",
"setNativeProps",
// Touchable mixin.
'touchableHandlePress' ,
'touchableHandleActivePressIn',
'touchableHandleActivePressOut',
'touchableHandleLongPress',
'touchableGetPressRectOffset',
'touchableGetHitSlop',
'touchableGetHighlightDelayMS',
'touchableGetLongPressDelayMS',
'touchableGetPressOutDelayMS',
"touchableHandlePress",
"touchableHandleActivePressIn",
"touchableHandleActivePressOut",
"touchableHandleLongPress",
"touchableGetPressRectOffset",
"touchableGetHitSlop",
"touchableGetHighlightDelayMS",
"touchableGetLongPressDelayMS",
"touchableGetPressOutDelayMS",
// Scrollable mixin.
'getScrollableNode',
'getScrollResponder',
"getScrollableNode",
"getScrollResponder"
];
function filterMethods(method) {
return method.name[0] !== '_' && methodsBlacklist.indexOf(method.name) === -1;
return method.name[0] !== "_" && methodsBlacklist.indexOf(method.name) === -1;
}
// Hide a component from the sidebar by making it return false from
// this function
const HIDDEN_COMPONENTS = [
'Transforms',
'ListViewDataSource',
];
const HIDDEN_COMPONENTS = ["Transforms", "ListViewDataSource"];
function shouldDisplayInSidebar(componentName) {
return HIDDEN_COMPONENTS.indexOf(componentName) === -1;
@@ -128,13 +125,13 @@ function getPreviousComponent(idx) {
function componentsToMarkdown(type, json, filepath, idx, styles) {
const componentName = getNameFromPath(filepath);
const componentPlatform = getPlatformFromPath(filepath);
const docFilePath = '../docs/' + componentName + '.md';
const docFilePath = "../docs/" + componentName + ".md";
if (fs.existsSync(docFilePath)) {
json.fullDescription = fs.readFileSync(docFilePath).toString();
}
json.type = type;
json.filepath = filepath.replace(/^\.\.\//, '');
json.filepath = filepath.replace(/^\.\.\//, "");
json.componentName = componentName;
json.componentPlatform = componentPlatform;
if (styles) {
@@ -145,29 +142,33 @@ function componentsToMarkdown(type, json, filepath, idx, styles) {
json.methods = json.methods.filter(filterMethods);
}
if (type === 'api') {
type = 'API';
if (type === "api") {
type = "API";
}
// Put styles (e.g. Flexbox) into the API category
const category = (type === 'style' ? 'APIs' : type + 's');
const category = type === "style" ? "APIs" : type + "s";
const next = getNextComponent(idx);
const previous = getPreviousComponent(idx);
const res = [
'---',
'id: ' + slugify(componentName),
'title: ' + componentName,
'layout: autodocs',
'category: ' + category,
'permalink: docs/' + slugify(componentName) + '.html',
'platform: ' + componentPlatform,
'next: ' + next,
'previous: ' + previous,
'sidebar: ' + shouldDisplayInSidebar(componentName),
'path:' + json.filepath,
'---',
JSON.stringify(json, null, 2),
].filter(function(line) { return line; }).join('\n');
"---",
"id: " + slugify(componentName),
"title: " + componentName,
"layout: autodocs",
"category: " + category,
"permalink: docs/" + slugify(componentName) + ".html",
"platform: " + componentPlatform,
"next: " + next,
"previous: " + previous,
"sidebar: " + shouldDisplayInSidebar(componentName),
"path:" + json.filepath,
"---",
JSON.stringify(json, null, 2)
]
.filter(function(line) {
return line;
})
.join("\n");
return res;
}
@@ -176,15 +177,15 @@ let componentCount;
function getTypedef(filepath, fileContent, json) {
let typedefDocgen;
try {
typedefDocgen = docgen.parse(
fileContent,
docgenHelpers.findExportedType,
[docgenHelpers.typedefHandler]
).map((type) => type.typedef);
typedefDocgen = docgen
.parse(fileContent, docgenHelpers.findExportedType, [
docgenHelpers.typedefHandler
])
.map(type => type.typedef);
} catch (e) {
// Ignore errors due to missing exported type definitions
if (e.message.indexOf(docgen.ERROR_MISSING_DEFINITION) !== -1) {
console.error('Cannot parse file', filepath, e);
console.error("Cannot parse file", filepath, e);
}
}
if (!json) {
@@ -216,7 +217,7 @@ function getViewPropTypes() {
recast.visit(ast, {
visitAssignmentExpression: function(astPath) {
if (!definition && docgen.utils.isExportsOrModuleAssignment(astPath)) {
definition = docgen.utils.resolveToValue(astPath.get('right'));
definition = docgen.utils.resolveToValue(astPath.get("right"));
}
return false;
}
@@ -232,24 +233,22 @@ function getViewPropTypes() {
// This is broken because babylon@7 and estree introduced SpreadElement, and ast-types has not been updated to support it
// (we are broken by react-docgen broken by recast broken by ast-types)
astPath.get('properties').value.forEach(n => {
if (n.type === 'SpreadElement') {
n.type = 'SpreadProperty';
astPath.get("properties").value.forEach(n => {
if (n.type === "SpreadElement") {
n.type = "SpreadProperty";
}
});
const FauxView = builders.classDeclaration(
builders.identifier('View'),
builders.classBody(
[builders.classProperty(
builders.identifier('propTypes'),
builders.objectExpression(
astPath.get('properties').value
),
builders.identifier("View"),
builders.classBody([
builders.classProperty(
builders.identifier("propTypes"),
builders.objectExpression(astPath.get("properties").value),
null, // TypeAnnotation
true // static
)]
)
)
])
);
astPath.replace(FauxView);
}
@@ -257,10 +256,7 @@ function getViewPropTypes() {
return docgen.parse(
fs.readFileSync(docsList.viewPropTypes),
viewPropTypesResolver,
[
viewPropTypesConversionHandler,
...docgen.defaultHandlers,
]
[viewPropTypesConversionHandler].concat(docgen.defaultHandlers)
);
}
@@ -270,7 +266,7 @@ function renderComponent(filepath) {
const handlers = docgen.defaultHandlers.concat([
docgenHelpers.stylePropTypeHandler,
docgenHelpers.deprecatedPropTypeHandler,
docgenHelpers.jsDocFormatHandler,
docgenHelpers.jsDocFormatHandler
]);
const json = docgen.parse(
@@ -288,9 +284,15 @@ function renderComponent(filepath) {
json.props = viewPropTypesJSON.props;
}
return componentsToMarkdown('component', json, filepath, componentCount++, styleDocs);
return componentsToMarkdown(
"component",
json,
filepath,
componentCount++,
styleDocs
);
} catch (e) {
console.log('error in renderComponent for', filepath);
console.log("error in renderComponent for", filepath);
throw e;
}
}
@@ -307,25 +309,22 @@ function isJsDocFormat(fileContent) {
function parseAPIJsDocFormat(filepath, fileContent) {
const fileName = path.basename(filepath);
const babelRC = {
'filename': fileName,
'sourceFileName': fileName,
'plugins': [
'transform-flow-strip-types',
'babel-plugin-syntax-trailing-function-commas',
]
filename: fileName,
sourceFileName: fileName,
plugins: ["transform-flow-strip-types"]
};
// Babel transform
const code = babel.transform(fileContent, babelRC).code;
// Parse via jsdoc-api
let jsonParsed = jsdocApi.explainSync({
source: code,
configure: './jsdocs/jsdoc-conf.json'
configure: "./jsdocs/jsdoc-conf.json"
});
// Clean up jsdoc-api return
jsonParsed = jsonParsed.filter(i => {
return !i.undocumented && !/package|file/.test(i.kind);
});
jsonParsed = jsonParsed.map((identifier) => {
jsonParsed = jsonParsed.map(identifier => {
delete identifier.comment;
return identifier;
});
@@ -336,8 +335,8 @@ function parseAPIJsDocFormat(filepath, fileContent) {
const json = {};
jsonParsed.forEach((identifier, index) => {
let kind = identifier.kind;
if (kind === 'function') {
kind = 'methods';
if (kind === "function") {
kind = "methods";
}
if (!json[kind]) {
json[kind] = [];
@@ -354,10 +353,10 @@ function parseAPIInferred(filepath, fileContent) {
try {
json = jsDocs(fileContent);
if (!json) {
throw new Error('parseSource returned falsy');
throw new Error("parseSource returned falsy");
}
} catch (e) {
console.error('Cannot parse file', filepath, e);
console.error("Cannot parse file", filepath, e);
json = {};
}
return json;
@@ -366,34 +365,34 @@ function parseAPIInferred(filepath, fileContent) {
function getTypeName(type) {
let typeName;
switch (type.name) {
case 'signature':
case "signature":
typeName = type.type;
break;
case 'union':
typeName = type.value ?
type.value.map(getTypeName) :
type.elements.map(getTypeName);
case "union":
typeName = type.value
? type.value.map(getTypeName)
: type.elements.map(getTypeName);
break;
case 'enum':
if (typeof type.value === 'string') {
case "enum":
if (typeof type.value === "string") {
typeName = type.value;
} else {
typeName = 'enum';
typeName = "enum";
}
break;
case '$Enum':
case "$Enum":
if (type.elements[0].signature.properties) {
typeName = type.elements[0].signature.properties.map(p => p.key);
}
break;
case 'arrayOf':
case "arrayOf":
typeName = getTypeName(type.value);
break;
case 'instanceOf':
case "instanceOf":
typeName = type.value;
break;
case 'func':
typeName = 'function';
case "func":
typeName = "function";
break;
default:
typeName = type.alias ? type.alias : type.name;
@@ -403,24 +402,31 @@ function getTypeName(type) {
}
function getTypehintRec(typehint) {
if (typehint.type === 'simple') {
if (typehint.type === "simple") {
return typehint.value;
}
if (typehint.type === 'generic') {
return getTypehintRec(typehint.value[0]) +
'<' + getTypehintRec(typehint.value[1]) + '>';
if (typehint.type === "generic") {
return (
getTypehintRec(typehint.value[0]) +
"<" +
getTypehintRec(typehint.value[1]) +
">"
);
}
return JSON.stringify(typehint);
}
function getTypehint(typehint) {
if (typeof typehint === 'object' && typehint.name) {
if (typeof typehint === "object" && typehint.name) {
return getTypeName(typehint);
}
try {
var typehint = JSON.parse(typehint);
} catch (e) {
return typehint.toString().split('|').map(type => type.trim());
return typehint
.toString()
.split("|")
.map(type => type.trim());
}
return getTypehintRec(typehint);
}
@@ -428,7 +434,7 @@ function getTypehint(typehint) {
function getJsDocFormatType(entities) {
const modEntities = entities;
if (entities) {
if (typeof entities === 'object' && entities.length) {
if (typeof entities === "object" && entities.length) {
entities.map((entity, entityIndex) => {
if (entity.typehint) {
const typeNames = [].concat(getTypehint(entity.typehint));
@@ -439,14 +445,16 @@ function getJsDocFormatType(entities) {
const regexOptionalType = /\?$/;
if (regexOptionalType.test(entity.name)) {
modEntities[entityIndex].optional = true;
modEntities[entityIndex].name =
entity.name.replace(regexOptionalType, '');
modEntities[entityIndex].name = entity.name.replace(
regexOptionalType,
""
);
}
}
});
} else {
const typeNames = [].concat(getTypehint(entities));
return { type: { names : typeNames } };
return { type: { names: typeNames } };
}
}
return modEntities;
@@ -464,8 +472,9 @@ function renderAPI(filepath, type) {
const modMethods = methods;
methods.map((method, methodIndex) => {
modMethods[methodIndex].params = getJsDocFormatType(method.params);
modMethods[methodIndex].returns =
getJsDocFormatType(method.returntypehint);
modMethods[methodIndex].returns = getJsDocFormatType(
method.returntypehint
);
delete modMethods[methodIndex].returntypehint;
});
json.methods = modMethods;
@@ -476,7 +485,7 @@ function renderAPI(filepath, type) {
}
return componentsToMarkdown(type, json, filepath, componentCount++);
} catch (e) {
console.log('error in renderAPI for', filepath);
console.log("error in renderAPI for", filepath);
throw e;
}
}
@@ -485,20 +494,23 @@ function renderStyle(filepath) {
const json = docgen.parse(
fs.readFileSync(filepath),
docgenHelpers.findExportedObject,
[
docgen.handlers.propTypeHandler,
docgen.handlers.propDocBlockHandler,
]
[docgen.handlers.propTypeHandler, docgen.handlers.propDocBlockHandler]
);
// Remove deprecated transform props from docs
if (filepath === '../Libraries/StyleSheet/TransformPropTypes.js') {
['rotation', 'scaleX', 'scaleY', 'translateX', 'translateY'].forEach(function(key) {
if (filepath === "../Libraries/StyleSheet/TransformPropTypes.js") {
[
"rotation",
"scaleX",
"scaleY",
"translateX",
"translateY"
].forEach(function(key) {
delete json.props[key];
});
}
return componentsToMarkdown('style', json, filepath, componentCount++);
return componentsToMarkdown("style", json, filepath, componentCount++);
}
const all = docsList.components
@@ -506,16 +518,17 @@ const all = docsList.components
.concat(docsList.stylesWithPermalink);
const styleDocs = docsList.stylesForEmbed.reduce(function(docs, filepath) {
docs[path.basename(filepath).replace(path.extname(filepath), '')] =
docgen.parse(
fs.readFileSync(filepath),
docgenHelpers.findExportedObject,
[
docgen.handlers.propTypeHandler,
docgen.handlers.propTypeCompositionHandler,
docgen.handlers.propDocBlockHandler,
]
);
docs[
path.basename(filepath).replace(path.extname(filepath), "")
] = docgen.parse(
fs.readFileSync(filepath),
docgenHelpers.findExportedObject,
[
docgen.handlers.propTypeHandler,
docgen.handlers.propTypeCompositionHandler,
docgen.handlers.propDocBlockHandler
]
);
return docs;
}, {});
@@ -523,15 +536,11 @@ const styleDocs = docsList.stylesForEmbed.reduce(function(docs, filepath) {
function extractDocs() {
componentCount = 0;
var components = docsList.components.map(renderComponent);
var apis = docsList.apis.map((filepath) => {
return renderAPI(filepath, 'api');
var apis = docsList.apis.map(filepath => {
return renderAPI(filepath, "api");
});
var styles = docsList.stylesWithPermalink.map(renderStyle);
return [].concat(
components,
apis,
styles
);
return [].concat(components, apis, styles);
}
module.exports = extractDocs;
+304
View File
@@ -0,0 +1,304 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const fetch = require('node-fetch');
const filepath = require('filepath');
const fm = require('front-matter');
const fs = require('fs-extra');
const glob = require('glob-promise');
const jsdom = require('jsdom');
const mkdirp = require('mkdirp');
const Promise = require('bluebird');
const shell = require('shelljs');
const convert = require('./convert.js');
const slugify = require('../core/slugify');
const AUTODOCS_PREFIX = 'autogen_';
const MARKDOWN_EXTENSION = 'md';
const GIT_USER = 'hramos'; //process.env.GIT_USER;
const GITHUB_USERNAME = 'facebook'; // process.env.GITHUB_USERNAME;
const GITHUB_REPONAME = 'react-native'; // process.env.GITHUB_REPONAME;
const remoteBranch = `https://${GIT_USER}@github.com/${GITHUB_USERNAME}/${GITHUB_REPONAME}.git`;
const CHECKOUT_DIR = `${GITHUB_REPONAME}-docs`;
const BUILD_DIR = 'build';
const DOCS_DIR = 'versioned_docs';
const SIDEBAR_DIR = 'versioned_sidebars';
const { JSDOM } = jsdom;
// Start up a server. Don't forget to close the connection when done.
const server = require('./server.js');
server.noconvert = true;
const argv = require('minimist')(process.argv.slice(2), {
alias: {
'c': 'clean'
},
default: {
'autodocs': true
}
});
function runChecks() {
if (!shell.which('git')) {
shell.echo('Sorry, this script requires git');
shell.exit(1);
}
if (!GIT_USER) {
shell.echo('GIT_USER undefined.');
shell.exit(1);
}
if (!GITHUB_USERNAME) {
shell.echo('GITHUB_USERNAME undefined.');
shell.exit(1);
}
if (!GITHUB_REPONAME) {
shell.echo('GITHUB_REPONAME undefined.');
shell.exit(1);
}
}
function cleanFiles() {
return fs.remove(BUILD_DIR);
}
/**
* Generates documentation for a given file.
*
* @param {*} file
* @param {*} options
*/
function generateAutodocForFile(file, options) {
if (file.match(/src\/react-native\/js/)) {
// Ensure we're only processing extracted docs
console.log(`Skipping ${file}`);
return;
}
const pathToOutputDir = filepath.create(BUILD_DIR, DOCS_DIR, options.version);
console.log(`Processing ${file}`);
const url = 'http://localhost:8079/' + file
.replace(/^src/, '')
.replace(/\.js$/, '.html');
return fetch(url)
.then(response => {
if(response.ok) {
return response.text();
}
throw new Error('Network response was not ok.');
})
.then(body => {
const dom = new JSDOM(body);
const markdown = generateMarkdownFromDOM(dom);
const metadata = fm(markdown);
const pathToOutputFile = pathToOutputDir.append(`${AUTODOCS_PREFIX}${metadata.attributes.id}.${MARKDOWN_EXTENSION}`);
return fs.outputFile(pathToOutputFile.toString(), markdown);
})
.catch(error => {
console.log(error);
reject(error);
});
}
/**
* Generates Markdown documentation. Uses the convert script to extract docs from source files.
*
* STATUS FRIDAY 6:
* Checking out tags and runnign autodocs for each tag not working out.
* Lets instead check out thw tags and parse out the docs from the existing html, much easier. No need to re-generate when they already exist.
* we can use filename as key
*
* we can then copy ecisting md files from there. solves a lot ofg issues
*/
function generateAutodocs(options = { version: 'next' }) {
console.log(`Generating Markdown files from JavaScript sources for version ${options.version}.`);
convert({extractDocs: true});
let queue = Promise.resolve();
return Promise.resolve().then(function() {
return glob('src/**/*.js');
}).then(function(files) {
let p = Promise.resolve();
files.forEach(function(file) {
p = p.then(function() {
return generateAutodocForFile(file, options);
});
});
return p;
}).then(function() {
console.log(`Generated Markdown files from JavaScript sources for version ${options.version}.`);
}).catch(function(e) {
console.error(e);
process.exit(1);
});
}
// TODO: I think we have a sync/async problem where we checked out everything before trying to process docs
function checkOutDocs() {
const pathToGitCheckout = filepath.create(BUILD_DIR, CHECKOUT_DIR);
const p = Promise.resolve();
return p
.then(() => {
return fs.ensureDir(pathToGitCheckout.toString());
})
.then(() => {
shell.cd(process.cwd());
shell.cd(BUILD_DIR);
shell.cd(CHECKOUT_DIR);
return fs.exists(pathToGitCheckout.append(`.git`).toString())
}).then(gitCheckoutExists => {
if (!gitCheckoutExists) {
shell.exec(`git init`).code !== 0;
if (shell.exec(`git remote add origin ${remoteBranch}`).code !== 0) {
throw new Error('Error: git remote failed');
}
}
return;
})
.then(() => {
shell.exec(`git config core.sparsecheckout true`).code !== 0;
shell.exec(`echo "docs/*" >> .git/info/sparse-checkout`).code !== 0;
shell.exec(`echo "Libraries/*" >> .git/info/sparse-checkout`).code !== 0;
if (shell.exec(`git fetch`).code !== 0) {
throw new Error('Error: git fetch failed');
}
const tags = shell.exec(`git tag --sort=version:refname -l 'v0.??.?' 'v0.?.?'`).toString().split('\n');
tags.forEach(function(tag) {
if (tag === '') {
return;
}
console.log(`Processing ${tag}`)
if (shell.exec(`git checkout ${tag}`).code !== 0) {
throw new Error('Error: git checkout failed');
}
shell.echo(`Checked out ${tag}`);
const version = tag.substring(1);
// const versionDir = `../../website/versioned_docs/${version}`;
// shell.mkdir(versionDir);
// shell.cp(`docs/*`, `${versionDir}/.`)
// processDocs(versionDir, version);
return generateAutodocs({ version });
})
})
}
// DOM FORMATTING FUNCS
function bodyContentFromDOM(dom) {
const el = dom.window.document.querySelector('#componentContent');
if (el) {
return el.innerHTML;
} else {
return null;
}
}
function componentNameFromDOM(dom) {
const el = dom.window.document.querySelector('title');
if (el) {
return el.innerHTML;
} else {
return 'Component';
}
}
function componentCategoryFromDOM(dom) {
const el = dom.window.document.querySelector('meta[property="rn:category"]');
if (el) {
return el.content;
} else {
return 'Components';
}
}
/**
* Generates a markdown formatted file, including frontmatter.
*
* @param {*} dom
*/
function generateMarkdownFromDOM(dom) {
const body = bodyContentFromDOM(dom);
if (!body) {
return;
}
const componentName = componentNameFromDOM(dom);
const slug = slugify(componentName);
let category = 'Components';
const componentCategory = componentCategoryFromDOM(dom);
if (componentCategory) {
category = componentCategory;
}
const metadata = { id: slug, category: category };
const markdown = [
'---',
'id: ' + slug,
'title: ' + componentName,
// 'category: ' + category,
// 'permalink: docs/' + slug + '.html',
'---',
body
]
.filter(function(line) {
return line;
})
.join('\n');
return markdown;
}
function generateMetatadaFile(categories) {
const categoriesMetadataFile = `${BUILD_DIR}/sidebar-metadata.json`;
return fs.outputFile(categoriesMetadataFile, JSON.stringify(categories));
}
// END DOM
if (argv.clean) {
cleanFiles();
}
if (argv.autodocs) {
runChecks();
checkOutDocs()
.finally(function() {
server.close();
}).catch(function(e) {
console.error(e);
process.exit(1);
});
}
/**
* Check out gh-pages branch, cd releases/
* For each version,
* For each HTML,
* Parse out jsdom
* Get body contents
* Generate frontmatter
* Save into versioned_docs
* Then finally generate sidebar files for each version
*
*/
module.exports = generateAutodocs;
@@ -16,7 +16,7 @@ var mkdirp = require('mkdirp');
var server = require('./server.js');
var Feed = require('feed');
require('./convert.js')({extractDocs: true});
require('./convertOld.js')({extractDocs: true});
server.noconvert = true;
// Sadly, our setup fatals when doing multiple concurrent requests
@@ -24,48 +24,6 @@ server.noconvert = true;
// requests.
var queue = Promise.resolve();
// Generate RSS Feeds
queue = queue.then(function() {
return new Promise(function(resolve, reject) {
var targetFile = 'build/react-native/blog/feed.xml';
var basePath = 'https://facebook.github.io/react-native/';
var blogPath = basePath + 'blog/';
var metadataBlog = JSON.parse(fs.readFileSync('server/metadata-blog.json'));
var latestPost = metadataBlog.files[0];
var feed = new Feed({
title: 'React Native Blog',
description: 'The best place to stay up-to-date with the latest React Native news and events.',
id: blogPath,
link: blogPath,
image: basePath + 'img/header_logo.png',
copyright: 'Copyright © ' + new Date().getFullYear() + ' Facebook Inc.',
updated: new Date(latestPost.publishedAt),
});
metadataBlog.files.forEach(function(post) {
var url = blogPath + post.path;
feed.addItem({
title: post.title,
id: url,
link: url,
date: new Date(post.publishedAt),
author: [{
name: post.author,
link: post.authorURL
}],
description: post.excerpt,
});
});
mkdirp.sync(targetFile.replace(new RegExp('/[^/]*$'), ''));
fs.writeFileSync(targetFile, feed.render('atom-1.0'));
console.log('Generated RSS feed')
resolve();
});
});
// Generate HTML for each non-source code JS file
glob('src/**/*.*', function(er, files) {
files.forEach(function(file) {
@@ -108,4 +66,4 @@ glob('src/**/*.*', function(er, files) {
console.error(e);
process.exit(1);
});
});
});
+260
View File
@@ -0,0 +1,260 @@
#!/usr/bin/env node
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
"use strict";
/**
* This is meant to be a one-time run script that checks out every version of the docs off GitHub. This is simply any Markdown doc in the docs/ folder of a given release.
* Once we have Markdown formatted docs, we'll need to go through these and generate all the necessary sidebar files.
* We'll be working with a few directories:
*
* - /docs - This is where the latest version of the docs will reside.
* - /website/versioned_docs - Here we will have version-XXX folders, one for each React Native version. It shall include both "guides" (regular docs already stored as a Markdown file), as well as "autodocs" (Markdown docs generated from JavaScript comments).
* - /website/versioned_sidebars - We'll also have version-XXX folders here, one for each React Native version. These sidebar files will be generated based on the Markdown docs present in the corresponding versioned_docs sub-folder.
* - /docgen/build - Here we will store any intermediary build files that shall not be stored in source control. These can be regenerated from source control, and include such things as original files checked out from git tags, as well as intermediary metadata files used to generate the final sidebar files.
*
*/
const fm = require("front-matter");
const fs = require("fs");
const glob = require("glob");
const mkdirp = require("mkdirp");
const shell = require("shelljs");
const GIT_USER = process.env.GIT_USER;
const GITHUB_USERNAME = process.env.GITHUB_USERNAME;
const GITHUB_REPONAME = process.env.GITHUB_REPONAME;
const remoteBranch = `https://${GIT_USER}@github.com/${GITHUB_USERNAME}/${GITHUB_REPONAME}.git`;
const localCheckoutDir = `${GITHUB_REPONAME}-docs`;
const DOCS_DIR = `../docs`;
const buildDir = `build/`;
function runChecks() {
if (!shell.which("git")) {
shell.echo("Sorry, this script requires git");
shell.exit(1);
}
if (!GIT_USER) {
shell.echo("GIT_USER undefined.");
shell.exit(1);
}
if (!GITHUB_USERNAME) {
shell.echo("GITHUB_USERNAME undefined.");
shell.exit(1);
}
if (!GITHUB_REPONAME) {
shell.echo("GITHUB_REPONAME undefined.");
shell.exit(1);
}
}
/**
* Remove any existing build directories and start with a clean slate.
*/
function prepareFilesystem() {
shell.cd(process.cwd());
shell.rm('-rf', buildDir);
shell.mkdir('-p', buildDir + localCheckoutDir);
}
/**
* Check out each version tag, then run node server/generate.js to get HTML files built.
*
* Generate requires a server to be started up. Can we do this from one location?
*/
function checkOutDocs() {
shell.cd(localCheckoutDir);
shell.exec(`git init`).code !== 0;
if (shell.exec(`git remote add origin ${remoteBranch}`).code !== 0) {
shell.echo("Error: git remote failed");
shell.exit(1);
}
shell.exec(`git config core.sparsecheckout true`).code !== 0;
shell.exec(`echo "docs/*" >> .git/info/sparse-checkout`).code !== 0;
if (shell.exec(`git fetch --depth 1 origin master`).code !== 0) {
shell.echo("Error: git fetch failed");
shell.exit(1);
}
if (shell.exec(`git pull --depth 1 origin master`).code !== 0) {
shell.echo("Error: git pull failed");
shell.exit(1);
}
shell.echo(`Checked out ${localCheckoutDir}`);
shell.cd(`../..`);
processDocs(`build/${localCheckoutDir}/docs`);
}
function checkOutVersionedDocs() {
shell.cd(process.cwd() + buildDir + localCheckoutDir);
shell.exec(`git fetch`);
const tags = shell.exec(`git tag --sort=version:refname -l 'v0.??.?' 'v0.?.?'`).toString().split('\n');
console.log(tags);
tags.forEach(function(tag) {
if (shell.exec(`git checkout ${tag}`).code !== 0) {
shell.echo("Error: git checkout failed");
shell.exit(1);
}
shell.echo(`Checked out ${tag}`);
const version = tag.substring(1);
const versionDir = `../../website/versioned_docs/${version}`;
shell.mkdir(versionDir);
shell.cp(`docs/*`, `${versionDir}/.`)
processDocs(versionDir, version);
})
shell.cd(`../..`);
}
function generateDocsMetadata(files) {
let sidebarsMetadata = new Object();
files.forEach(function(file) {
const data = fs.readFileSync(file, "utf8");
const content = fm(data);
const metadata = content.attributes;
const rawContent = content.body;
if (metadata.layout !== "docs") {
console.log(`Skipping ${file} due to non-docs layout ${metadata.layout}`);
return;
}
if (metadata.category) {
if (!Object.keys(sidebarsMetadata).includes(metadata.category)) {
sidebarsMetadata = Object.assign({}, sidebarsMetadata, {
[metadata.category]: {}
});
}
const sidebarMetadata = {
previous: metadata.previous,
next: metadata.next,
id: metadata.id,
title: metadata.title,
content: rawContent,
filename: file
};
const updatedCategory = Object.assign(
{},
sidebarsMetadata[metadata.category],
{ [sidebarMetadata.id]: sidebarMetadata }
);
sidebarsMetadata = Object.assign({}, sidebarsMetadata, {
[metadata.category]: updatedCategory
});
} else {
console.log(`Skipping ${file} due to lack of category`);
return;
}
if (!metadata.permalink) {
console.log(`Skipping ${file} due to lack of permalink`);
return;
}
if (metadata.permalink.match(/^https?:/)) {
console.log(`Skipping ${file} as its permalink is external`);
return;
}
});
fs.writeFileSync(
`build/sidebars-metadata.json`,
JSON.stringify(sidebarsMetadata)
);
return sidebarsMetadata;
}
function generateSidebarsFromMetadata(sidebarsMetadata) {
let sidebars = new Object();
Object.keys(sidebarsMetadata).forEach(function(category) {
if (!Object.keys(sidebars).includes(category)) {
sidebars = Object.assign({}, sidebars, { [category]: [] });
}
let categoryHead;
let allFilesInCategory = Object.keys(sidebarsMetadata[category]);
Object.entries(sidebarsMetadata[category]).forEach(function([id, file]) {
if (allFilesInCategory.includes(file.previous)) {
// skip, we're looking for head
console.log(`skipping ${file.id}`);
return;
}
categoryHead = file;
});
let updatedCategory = [categoryHead.id];
let currentFile = categoryHead;
while (allFilesInCategory.includes(currentFile.next)) {
updatedCategory = updatedCategory.concat([currentFile.next]);
currentFile = sidebarsMetadata[category][currentFile.next];
}
sidebars = Object.assign({}, sidebars, { [category]: updatedCategory });
});
return sidebars;
}
function generateMarkdownFromMetadata(sidebarMetadata) {
Object.keys(sidebarMetadata).forEach(function(category) {
Object.keys(sidebarMetadata[category]).forEach(function(docId) {
const doc = sidebarMetadata[category][docId];
const targetFile = `../docs/${doc.id}.md`;
const migratedContent = doc.content.replace('src="img/', 'src="/react-native/img/');
const res = [
"---",
"id: " + doc.id,
"title: " + doc.title,
"---",
migratedContent
]
.filter(function(line) {
return line;
})
.join("\n");
fs.writeFileSync(targetFile, res);
console.log(`Wrote ${targetFile}`);
});
});
}
function processDocs(workingDir, version) {
// Generate sidebars.json
glob(`${workingDir}/*.md`, function(er, files) {
const sidebarsMetadata = generateDocsMetadata(files);
const sidebars = generateSidebarsFromMetadata(sidebarsMetadata);
const sidebarFile = `../website/` + version ? `versioned_sidebars/${version}/` : '' + 'sidebars.json'
fs.writeFileSync(
`../website/sidebars.json`,
JSON.stringify({
docs: sidebars
})
);
console.log("Generated sidebars.json file from docs");
generateMarkdownFromMetadata(sidebarsMetadata);
console.log("Generated markdown files from docs");
});
}
runChecks();
prepareFilesystem();
checkOutDocs();
// checkOutVersionedDocs();
@@ -9,7 +9,7 @@
'use strict';
const connect = require('connect');
const convert = require('./convert.js');
// const convert = require('./convert.js');
const http = require('http');
const optimist = require('optimist');
const path = require('path');
@@ -47,7 +47,7 @@ const app = connect()
// but fast enough that we don't really need to care right now.
if (!server.noconvert && req.url.match(/\.html|\/$/)) {
var extractDocs = req.url.match(/\/docs/); // Lazily extract docs.
convert({extractDocs});
// convert({extractDocs});
}
next();
})
@@ -61,6 +61,6 @@ const app = connect()
const portToUse = port || 8079;
const server = http.createServer(app);
server.listen(portToUse, function(){
console.log('Open http://localhost:' + portToUse + '/react-native/index.html');
console.log('Open http://localhost:' + portToUse + '/react-native/docs/animated.html');
});
module.exports = server;
+4032
View File
File diff suppressed because it is too large Load Diff
@@ -1,11 +1,6 @@
---
id: accessibility
title: Accessibility
layout: docs
category: Guides
permalink: docs/accessibility.html
next: timers
previous: animations
---
## Native App Accessibility (iOS and Android)
@@ -1,11 +1,6 @@
---
id: animations
title: Animations
layout: docs
category: Guides
permalink: docs/animations.html
next: accessibility
previous: images
---
Animations are very important to create a great user experience.
@@ -360,6 +355,23 @@ things like `transform` and `opacity` will work, but flexbox and position proper
When using `Animated.event`, it will only work with direct events and not bubbling events.
This means it does not work with `PanResponder` but does work with things like `ScrollView#onScroll`.
### Bear in mind
While using transform styles such as `rotateY`, `rotateX`, and others ensure the transform style `perspective` is in place.
At this time some animations may not render on Android without it. Example below.
```javascript
<Animated.View
style={{
transform: [
{ scale: this.state.scale },
{ rotateY: this.state.rotateY },
{ perspective: 1000 } // without this line this Animation will not render on Android while working fine on iOS
]
}}
/>
```
### Additional examples
The RNTester app has various examples of `Animated` in use:
@@ -472,7 +484,7 @@ manage frame updates for you.
### `setNativeProps`
As mentioned [in the Direction Manipulation section](docs/direct-manipulation.html),
As mentioned [in the Direct Manipulation section](docs/direct-manipulation.html),
`setNativeProps` allows us to modify properties of native-backed
components (components that are actually backed by native views, unlike
composite components) directly, without having to `setState` and
-5
View File
@@ -1,11 +1,6 @@
---
id: colors
title: Color Reference
layout: docs
category: Guides
permalink: docs/colors.html
next: integration-with-existing-apps
previous: direct-manipulation
---
Components in React Native are [styled using JavaScript](docs/style.html). Color properties usually match how [CSS works on the web](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value).
+59 -34
View File
@@ -1,11 +1,6 @@
---
id: debugging
title: Debugging
layout: docs
category: Guides
permalink: docs/debugging.html
next: performance
previous: timers
---
## Enabling Keyboard Shortcuts
@@ -165,43 +160,73 @@ Alternatively, select "Dev Settings" from the Developer Menu, then update the "D
### Debugging with [Stetho](http://facebook.github.io/stetho/) on Android
1. In ```android/app/build.gradle```, add these lines in the `dependencies` section:
Follow this guide to enable Stetho for Debug mode:
1. In `android/app/build.gradle`, add these lines in the `dependencies` section:
```gradle
compile 'com.facebook.stetho:stetho:1.3.1'
compile 'com.facebook.stetho:stetho-okhttp3:1.3.1'
debugCompile 'com.facebook.stetho:stetho:1.5.0'
debugCompile 'com.facebook.stetho:stetho-okhttp3:1.5.0'
```
2. In ```android/app/src/main/java/com/{yourAppName}/MainApplication.java```, add the following imports:
> The above will configure Stetho v1.5.0. You can check at http://facebook.github.io/stetho/ if a newer version is available.
```java
import com.facebook.react.modules.network.ReactCookieJarContainer;
import com.facebook.stetho.Stetho;
import okhttp3.OkHttpClient;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import java.util.concurrent.TimeUnit;
```
2. Create the following Java classes to wrap the Stetho call, one for release and one for debug:
```java
// android/app/src/release/java/com/{yourAppName}/StethoWrapper.java
public class StethoWrapper {
3. In ```android/app/src/main/java/com/{yourAppName}/MainApplication.java``` add the function:
```java
public void onCreate() {
super.onCreate();
Stetho.initializeWithDefaults(this);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(0, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer())
.addNetworkInterceptor(new StethoInterceptor())
.build();
OkHttpClientProvider.replaceOkHttpClient(client);
}
```
public static void initialize(Context context) {
// NO_OP
}
4. Run ```react-native run-android ```
public static void addInterceptor() {
// NO_OP
}
}
```
5. In a new Chrome tab, open: ```chrome://inspect```, then click on 'Inspect device' (the one followed by "Powered by Stetho").
```java
// android/app/src/debug/java/com/{yourAppName}/StethoWrapper.java
public class StethoWrapper {
public static void initialize(Context context) {
Stetho.initializeWithDefaults(context);
}
public static void addInterceptor() {
OkHttpClient client = OkHttpClientProvider.getOkHttpClient()
.newBuilder()
.addNetworkInterceptor(new StethoInterceptor())
.build();
OkHttpClientProvider.replaceOkHttpClient(client);
}
}
```
3. Open `android/app/src/main/java/com/{yourAppName}/MainApplication.java` and replace the original `onCreate` function:
```java
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
StethoWrapper.initialize(this);
StethoWrapper.addInterceptor();
}
SoLoader.init(this, /* native exopackage */ false);
}
```
4. Open the project in Android Studio and resolve any dependency issues. The IDE should guide you through this steps after hovering your pointer over the red lines.
5. Run `react-native run-android`.
6. In a new Chrome tab, open: `chrome://inspect`, then click on the 'Inspect device' item next to "Powered by Stetho".
## Debugging native code
+5 -8
View File
@@ -1,11 +1,6 @@
---
id: images
title: Images
layout: docs
category: Guides
permalink: docs/images.html
next: animations
previous: navigation
---
## Static Image Resources
@@ -186,13 +181,15 @@ On the user side, this lets you annotate the object with useful attributes such
## Background Image via Nesting
A common feature request from developers familiar with the web is `background-image`. To handle this use case, simply create a normal `<Image>` component and add whatever children to it you would like to layer on top of it.
A common feature request from developers familiar with the web is `background-image`. To handle this use case, you can use the `<ImageBackground>` component, which has the same props as `<Image>`, and add whatever children to it you would like to layer on top of it.
You might not want to use `<ImageBackground>` in some cases, since the implementation is very simple. Refer to `<ImageBackground>`'s [source code](https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageBackground.js) for more insight, and create your own custom component when needed.
```javascript
return (
<Image source={...}>
<ImageBackground source={...}>
<Text>Inside</Text>
</Image>
</ImageBackground>
);
```
@@ -1,11 +1,6 @@
---
id: navigation
title: Navigating Between Screens
layout: docs
category: Guides
permalink: docs/navigation.html
next: images
previous: platform-specific-code
---
Mobile apps are rarely made up of a single screen. Managing the presentation of, and transition between, multiple screens is typically handled by what is known as a navigator.
@@ -99,6 +94,7 @@ export default class NavigatorIOSApp extends React.Component {
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: {index: 1},
}}
style={{flex: 1}}
/>
@@ -108,7 +104,9 @@ export default class NavigatorIOSApp extends React.Component {
class MyScene extends React.Component {
static propTypes = {
title: PropTypes.string.isRequired,
route: PropTypes.shape({
title: PropTypes.string.isRequired
}),
navigator: PropTypes.object.isRequired,
}
@@ -116,10 +114,13 @@ class MyScene extends React.Component {
super(props, context);
this._onForward = this._onForward.bind(this);
}
_onForward() {
let nextIndex = ++this.props.index;
this.props.navigator.push({
component: MyScene,
title: 'Scene ' + nextIndex,
passProps: {index: nextIndex}
});
}
@@ -1,11 +1,6 @@
---
id: performance
title: Performance
layout: docs
category: Guides
permalink: docs/performance.html
next: gesture-responder-system
previous: debugging
---
A compelling reason for using React Native instead of WebView-based tools is to achieve 60 frames per second and a native look and feel to your apps.
@@ -91,6 +86,10 @@ Use the new [`FlatList`](docs/flatlist.html) or [`SectionList`](docs/sectionlist
Besides simplifying the API, the new list components also have significant performance enhancements,
the main one being nearly constant memory usage for any number of rows.
If your [`FlatList`](docs/flatlist.html) is rendering slow, be sure that you've implemented
[`getItemLayout`](https://facebook.github.io/react-native/docs/flatlist.html#getitemlayout) to
optimize rendering speed by skipping measurement of the rendered items.
### JS FPS plunges when re-rendering a view that hardly changes
If you are using a ListView, you must provide a `rowHasChanged` function that can reduce a lot of work by quickly determining whether or not a row needs to be re-rendered. If you are using immutable data structures, this would be as simple as a reference equality check.
@@ -101,7 +100,7 @@ Similarly, you can implement `shouldComponentUpdate` and indicate the exact cond
"Slow Navigator transitions" is the most common manifestation of this, but there are other times this can happen. Using InteractionManager can be a good approach, but if the user experience cost is too high to delay work during an animation, then you might want to consider LayoutAnimation.
The Animated api currently calculates each keyframe on-demand on the JavaScript thread, while LayoutAnimation leverages Core Animation and is unaffected by JS thread and main thread frame drops.
The Animated API currently calculates each keyframe on-demand on the JavaScript thread unless you [set `useNativeDriver: true`](https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html#how-do-i-use-this-in-my-app), while LayoutAnimation leverages Core Animation and is unaffected by JS thread and main thread frame drops.
One case where I have used this is for animating in a modal (sliding down from top and fading in a translucent overlay) while initializing and perhaps receiving responses for several network requests, rendering the contents of the modal, and updating the view where the modal was opened from. See the Animations guide for more information about how to use LayoutAnimation.
-5
View File
@@ -1,11 +1,6 @@
---
id: props
title: Props
layout: docs
category: The Basics
permalink: docs/props.html
next: state
previous: tutorial
---
Most components can be customized when they are created, with different parameters. These creation parameters are called `props`.
-5
View File
@@ -1,11 +1,6 @@
---
id: state
title: State
layout: docs
category: The Basics
permalink: docs/state.html
next: style
previous: props
---
There are two types of data that control a component: `props` and `state`. `props` are set by the parent and they are fixed throughout the lifetime of a component. For data that is going to change, we have to use `state`.
-5
View File
@@ -1,11 +1,6 @@
---
id: style
title: Style
layout: docs
category: The Basics
permalink: docs/style.html
next: height-and-width
previous: state
---
With React Native, you don't use a special language or syntax for defining styles. You just style your application using JavaScript. All of the core components accept a prop named `style`. The style names and [values](docs/colors.html) usually match how CSS works on the web, except names are written using camel casing, e.g `backgroundColor` rather than `background-color`.
+11 -9
View File
@@ -1,20 +1,22 @@
---
id: testing
title: Running Tests and Contributing
layout: docs
category: Guides
permalink: docs/testing.html
next: understanding-cli
previous: upgrading
title: Testing your Changes
---
This document is about running tests on React Native itself. If you're interested in testing a React Native app, check out the [React Native Tutorial](http://facebook.github.io/jest/docs/tutorial-react-native.html) on the Jest website.
This document is about testing your changes to React Native as a [contributor](docs/contributing.html). If you're interested in testing a React Native app, check out the [React Native Tutorial](http://facebook.github.io/jest/docs/tutorial-react-native.html) on the Jest website.
The React Native repo has several tests you can run to verify you haven't caused a regression with your PR. These tests are run with the [Travis](https://travis-ci.org/facebook/react-native/builds) and [CircleCI](https://circleci.com/gh/facebook/react-native) continuous integration systems, which will automatically annotate pull requests with the test results.
The React Native repo has several tests you can run to verify you haven't caused a regression with your PR. These tests are run with the [Travis](https://travis-ci.org/facebook/react-native/builds) and [Circle](https://circleci.com/gh/facebook/react-native) continuous integration systems, which will automatically annotate pull requests with the test results.
Whenever you are fixing a bug or adding new functionality to React Native, you should add a test that covers it. Depending on the change you're making, there are different types of tests that may be appropriate.
## JavaScript Tests
- [JavaScript](docs/testing.html#javascript)
- [Android](docs/testing.html#android)
- [iOS](docs/testing.html#ios)
- [Apple TV](docs/testing.html#apple-tv)
- [End-to-end tests](docs/testing.html#end-to-end-tests)
- [Website](docs/testing.html#website)
## JavaScript
### Jest
-5
View File
@@ -1,11 +1,6 @@
---
id: timers
title: Timers
layout: docs
category: Guides
permalink: docs/timers.html
next: debugging
previous: accessibility
---
Timers are an important part of an application and React Native implements the [browser timers](https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Timers).
+45
View File
@@ -0,0 +1,45 @@
---
id: tutorial
title: Learn the Basics
---
React Native is like React, but it uses native components instead of web components as building blocks. So to understand the basic structure of a React Native app, you need to understand some of the basic React concepts, like JSX, components, `state`, and `props`. If you already know React, you still need to learn some React-Native-specific stuff, like the native components. This
tutorial is aimed at all audiences, whether you have React experience or not.
Let's do this thing.
## Hello World
In accordance with the ancient traditions of our people, we must first build an app that does nothing except say "Hello world". Here it is:
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { Text } from 'react-native';
export default class HelloWorldApp extends Component {
render() {
return (
<Text>Hello world!</Text>
);
}
}
```
If you are feeling curious, you can play around with sample code directly in the web simulators. You can also paste it into your `App.js` file to create a real app on your local machine.
## What's going on here?
Some of the things in here might not look like JavaScript to you. Don't panic. _This is the future_.
First of all, ES2015 (also known as ES6) is a set of improvements to JavaScript that is now part of the official standard, but not yet supported by all browsers, so often it isn't used yet in web development. React Native ships with ES2015 support, so you can use this stuff without worrying about compatibility. `import`, `from`, `class`, `extends`, and the `() =>` syntax in the example above are all ES2015 features. If you aren't familiar with ES2015, you can probably pick it up just by reading through sample code like this tutorial has. If you want, [this page](https://babeljs.io/learn-es2015/) has a good overview of ES2015 features.
The other unusual thing in this code example is `<Text>Hello world!</Text>`. This is JSX - a syntax for embedding XML within JavaScript. Many frameworks use a special templating language which lets you embed code inside markup language. In React, this is reversed. JSX lets you write your markup language inside code. It looks like HTML on the web, except instead of web things like `<div>` or `<span>`, you use React components. In this case, `<Text>`
is a built-in component that just displays some text.
## Components
So this code is defining `HelloWorldApp`, a new `Component`. When you're building a React Native app, you'll be making new components a lot. Anything you see on the screen is some sort of component. A component can be pretty simple - the only thing that's required is a `render` function which returns some JSX to render.
## This app doesn't do very much
Good point. To make components do more interesting things, you need to [learn about Props](docs/props.html).
@@ -1,11 +1,6 @@
---
id: upgrading
title: Upgrading to new React Native versions
layout: docs
category: Guides
permalink: docs/upgrading.html
next: testing
previous: running-on-device
---
Upgrading to new versions of React Native will give you access to more APIs, views, developer tools and other goodies. Upgrading requires a small amount of effort, but we try to make it easy for you. The instructions are a bit different depending on whether you used `create-react-native-app` or `react-native init` to create your project.
@@ -1,12 +1,6 @@
---
id: android-building-from-source
title: Building React Native from source
layout: docs
category: Guides (Android)
permalink: docs/android-building-from-source.html
banner: ejected
next: activityindicator
previous: android-ui-performance
---
You will need to build React Native from source if you want to work on a new feature/bug fix, try out the latest features which are not released yet, or maintain your own fork with patches that cannot be merged to the core.
@@ -55,7 +49,7 @@ ndk.dir=/Users/your_unix_name/android-ndk/android-ndk-r10e
3. Windows (64-bit) - http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip
4. Windows (32-bit) - http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip
You can find further instructions on the [official page](http://developer.android.com/ndk/downloads/index.html).
You can find further instructions on the [official page](https://developer.android.com/ndk/index.html).
## Building the source
+26
View File
@@ -0,0 +1,26 @@
---
id: app-extensions
title: App Extensions
---
App extensions let you provide custom functionality and content outside of your main app. There are different types of app extensions on iOS, and they are all covered in the [App Extension Programming Guide](https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/index.html#//apple_ref/doc/uid/TP40014214-CH20-SW1). In this guide, we'll briefly cover how you may take advantage of app extensions on iOS.
## Memory use in extensions
As these extensions are loaded outside of the regular app sandbox, it's highly likely that several of these app extensions will be loaded simultaneously. As you might expect, these extensions have small memory usage limits. Keep these in mind when developing your app extensions. It's always highly recommended to test your application on an actual device, and more so when developing app extensions: too frequently, developers find that their extension works just fine in the iOS Simulator, only to get user reports that their extension is not loading on actual devices.
We highly recommend that you watch Conrad Kramer's talk on [Memory Use in Extensions](https://cocoaheads.tv/memory-use-in-extensions-by-conrad-kramer/) to learn more about this topic.
### Today widget
The memory limit of a Today widget is 16 MB. As it happens, Today widget implementations using React Native may work unreliably because the memory usage tends to be too high. You can tell if your Today widget is exceeding the memory limit if it yields the message 'Unable to Load':
![](img/TodayWidgetUnableToLoad.jpg)
Always make sure to test your app extensions in a real device, but be aware that this may not be sufficient, especially when dealing with Today widgets. Debug-configured builds are more likely to exceed the memory limits, while release-configured builds don't fail right away. We highly recommend that you use [Xcode's Instruments](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html) to analyze your real world memory usage, as it's very likely that your release-configured build is very close to the 16 MB limit. In situations like these, it is easy to go over the 16 MB limit by performing common operations, such as fetching data from an API.
To experiment with the limits of React Native Today widget implementations, try extending the example project in [react-native-today-widget](https://github.com/matejkriz/react-native-today-widget/).
### Other app extensions
Other types of app extensions have greater memory limits than the Today widget. For instance, Custom Keyboard extensions are limited to 48 MB, and Share extensions are limited to 120 MB. Implementing such app extensions with React Native is more viable. One proof of concept example is [react-native-ios-share-extension](https://github.com/andrewsardone/react-native-ios-share-extension).
+54
View File
@@ -0,0 +1,54 @@
---
id: accessibilityinfo
title: AccessibilityInfo
category: APIs
permalink: docs/accessibilityinfo.html
---
<div><div><p>Sometimes it's useful to know whether or not the device has a screen reader that is currently active. The
<code>AccessibilityInfo</code> API is designed for this purpose. You can use it to query the current state of the
screen reader as well as to register to be notified when the state of the screen reader changes.</p><p>Here's a small example illustrating how to use <code>AccessibilityInfo</code>:</p><div class="prism language-javascript"><span class="token keyword">class</span> <span class="token class-name">ScreenReaderStatusExample</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
state <span class="token operator">=</span> <span class="token punctuation">{</span>
screenReaderEnabled<span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
AccessibilityInfo<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>
<span class="token string">'change'</span><span class="token punctuation">,</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>_handleScreenReaderToggled
<span class="token punctuation">)</span><span class="token punctuation">;</span>
AccessibilityInfo<span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">done</span><span class="token punctuation">(</span><span class="token punctuation">(</span>isEnabled<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
screenReaderEnabled<span class="token punctuation">:</span> isEnabled
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
AccessibilityInfo<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span>
<span class="token string">'change'</span><span class="token punctuation">,</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>_handleScreenReaderToggled
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
_handleScreenReaderToggled <span class="token operator">=</span> <span class="token punctuation">(</span>isEnabled<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
screenReaderEnabled<span class="token punctuation">:</span> isEnabled<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token operator">&lt;</span>View<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>Text<span class="token operator">&gt;</span>
The screen reader is <span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>screenReaderEnabled <span class="token operator">?</span> <span class="token string">'enabled'</span> <span class="token punctuation">:</span> <span class="token string">'disabled'</span><span class="token punctuation">}</span><span class="token punctuation">.</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>Text<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>View<span class="token operator">&gt;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/accessibilityinfo.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="fetch"></a><span class="methodType">static </span>fetch<span class="methodType">()</span> <a class="hash-link" href="docs/accessibilityinfo.html#fetch">#</a></h4><div><p>Query whether a screen reader is currently enabled. Returns a promise which
resolves to a boolean. The result is <code>true</code> when a screen reader is enabled
and <code>false</code> otherwise.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="addeventlistener"></a><span class="methodType">static </span>addEventListener<span class="methodType">(eventName, handler)</span> <a class="hash-link" href="docs/accessibilityinfo.html#addeventlistener">#</a></h4><div><p>Add an event handler. Supported events:</p><ul><li><code>change</code>: Fires when the state of the screen reader changes. The argument
to the event handler is a boolean. The boolean is <code>true</code> when a screen
reader is enabled and <code>false</code> otherwise.</li><li><code>announcementFinished</code>: iOS-only event. Fires when the screen reader has
finished making an announcement. The argument to the event handler is a dictionary
with these keys:<ul><li><code>announcement</code>: The string announced by the screen reader.</li><li><code>success</code>: A boolean indicating whether the announcement was successfully made.</li></ul></li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setaccessibilityfocus"></a><span class="methodType">static </span>setAccessibilityFocus<span class="methodType">(reactTag)</span> <a class="hash-link" href="docs/accessibilityinfo.html#setaccessibilityfocus">#</a></h4><div><p>iOS-Only. Set accessibility focus to a react component.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="announceforaccessibility"></a><span class="methodType">static </span>announceForAccessibility<span class="methodType">(announcement)</span> <a class="hash-link" href="docs/accessibilityinfo.html#announceforaccessibility">#</a></h4><div><p>iOS-Only. Post a string to be announced by the screen reader.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removeeventlistener"></a><span class="methodType">static </span>removeEventListener<span class="methodType">(eventName, handler)</span> <a class="hash-link" href="docs/accessibilityinfo.html#removeeventlistener">#</a></h4><div><p>Remove an event handler.</p></div></div></div></span></div>
+12
View File
@@ -0,0 +1,12 @@
---
id: actionsheetios
title: ActionSheetIOS
category: APIs
permalink: docs/actionsheetios.html
---
<div><div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/actionsheetios.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="showactionsheetwithoptions"></a><span class="methodType">static </span>showActionSheetWithOptions<span class="methodType">(options, callback)</span> <a class="hash-link" href="docs/actionsheetios.html#showactionsheetwithoptions">#</a></h4><div><p>Display an iOS action sheet. The <code>options</code> object must contain one or more
of:</p><ul><li><code>options</code> (array of strings) - a list of button titles (required)</li><li><code>cancelButtonIndex</code> (int) - index of cancel button in <code>options</code></li><li><code>destructiveButtonIndex</code> (int) - index of destructive button in <code>options</code></li><li><code>title</code> (string) - a title to show above the action sheet</li><li><code>message</code> (string) - a message to show below the title</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="showshareactionsheetwithoptions"></a><span class="methodType">static </span>showShareActionSheetWithOptions<span class="methodType">(options, failureCallback, successCallback)</span> <a class="hash-link" href="docs/actionsheetios.html#showshareactionsheetwithoptions">#</a></h4><div><p>Display the iOS share sheet. The <code>options</code> object should contain
one or both of <code>message</code> and <code>url</code> and can additionally have
a <code>subject</code> or <code>excludedActivityTypes</code>:</p><ul><li><code>url</code> (string) - a URL to share</li><li><code>message</code> (string) - a message to share</li><li><code>subject</code> (string) - a subject for the message</li><li><code>excludedActivityTypes</code> (array) - the activities to exclude from the ActionSheet</li></ul><p>NOTE: if <code>url</code> points to a local file, or is a base64-encoded
uri, the file it points to will be loaded and shared directly.
In this way, you can share images, videos, PDF files, etc.</p></div></div></div></span></div>
+8
View File
@@ -0,0 +1,8 @@
---
id: activityindicator
title: ActivityIndicator
category: Components
permalink: docs/activityindicator.html
---
<div><div><p>Displays a circular loading indicator.</p></div><h3><a class="anchor" name="props"></a>Props <a class="hash-link" href="docs/activityindicator.html#props">#</a></h3><div class="props"><div class="prop"><h4 class="propTitle"><a class="anchor" name="viewproptypes"></a><a href="docs/viewproptypes.html#props">ViewPropTypes props...</a> <a class="hash-link" href="docs/activityindicator.html#viewproptypes">#</a></h4></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="animating"></a>animating?: <span class="propType">bool</span> <a class="hash-link" href="docs/activityindicator.html#animating">#</a></h4><div><p>Whether to show the indicator (true, the default) or hide it (false).</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="color"></a>color?: <span class="propType"><a href="docs/colors.html">color</a></span> <a class="hash-link" href="docs/activityindicator.html#color">#</a></h4><div><p>The foreground color of the spinner (default is gray).</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="size"></a>size?: <span class="propType"><span><span>enum('small', 'large'), </span>number</span></span> <a class="hash-link" href="docs/activityindicator.html#size">#</a></h4><div><p>Size of the indicator (default is 'small').
Passing a number to the size prop is only supported on Android.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="hideswhenstopped"></a><span class="platform">ios</span>hidesWhenStopped?: <span class="propType">bool</span> <a class="hash-link" href="docs/activityindicator.html#hideswhenstopped">#</a></h4><div><p>Whether the indicator should hide when not animating (true by default).</p></div></div></div></div>
+27
View File
@@ -0,0 +1,27 @@
---
id: alert
title: Alert
category: APIs
permalink: docs/alert.html
---
<div><div><p>Launches an alert dialog with the specified title and message.</p><p>Optionally provide a list of buttons. Tapping any button will fire the
respective onPress callback and dismiss the alert. By default, the only
button will be an 'OK' button.</p><p>This is an API that works both on iOS and Android and can show static
alerts. To show an alert that prompts the user to enter some information,
see <code>AlertIOS</code>; entering text in an alert is common on iOS only.</p><h2><a class="anchor" name="ios"></a>iOS <a class="hash-link" href="docs/alert.html#ios">#</a></h2><p>On iOS you can specify any number of buttons. Each button can optionally
specify a style, which is one of 'default', 'cancel' or 'destructive'.</p><h2><a class="anchor" name="android"></a>Android <a class="hash-link" href="docs/alert.html#android">#</a></h2><p>On Android at most three buttons can be specified. Android has a concept
of a neutral, negative and a positive button:</p><ul><li>If you specify one button, it will be the 'positive' one (such as 'OK')</li><li>Two buttons mean 'negative', 'positive' (such as 'Cancel', 'OK')</li><li>Three buttons mean 'neutral', 'negative', 'positive' (such as 'Later', 'Cancel', 'OK')</li></ul><p>By default alerts on Android can be dismissed by tapping outside of the alert
box. This event can be handled by providing an optional <code>options</code> parameter,
with an <code>onDismiss</code> callback property <code>{ onDismiss: () =&gt; {} }</code>.</p><p>Alternatively, the dismissing behavior can be disabled altogether by providing
an optional <code>options</code> parameter with the <code>cancelable</code> property set to <code>false</code>
i.e. <code>{ cancelable: false }</code></p><p>Example usage:</p><div class="prism language-javascript"><span class="token comment" spellcheck="true">// Works on both iOS and Android
</span>Alert<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span>
<span class="token string">'Alert Title'</span><span class="token punctuation">,</span>
<span class="token string">'My Alert Msg'</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span>
<span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">'Ask me later'</span><span class="token punctuation">,</span> onPress<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Ask me later pressed'</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">'Cancel'</span><span class="token punctuation">,</span> onPress<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Cancel Pressed'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> <span class="token string">'cancel'</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">'OK'</span><span class="token punctuation">,</span> onPress<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'OK Pressed'</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span> cancelable<span class="token punctuation">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span>
<span class="token punctuation">)</span></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/alert.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="alert"></a><span class="methodType">static </span>alert<span class="methodType">(title, message?, buttons?, options?, type?)</span> <a class="hash-link" href="docs/alert.html#alert">#</a></h4></div></div></span></div>
+52
View File
@@ -0,0 +1,52 @@
---
id: alertios
title: AlertIOS
category: APIs
permalink: docs/alertios.html
---
<div><div><p><code>AlertIOS</code> provides functionality to create an iOS alert dialog with a
message or create a prompt for user input.</p><p>Creating an iOS alert:</p><div class="prism language-javascript">AlertIOS<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span>
<span class="token string">'Sync Complete'</span><span class="token punctuation">,</span>
<span class="token string">'All your data are belong to us.'</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>Creating an iOS prompt:</p><div class="prism language-javascript">AlertIOS<span class="token punctuation">.</span><span class="token function">prompt</span><span class="token punctuation">(</span>
<span class="token string">'Enter a value'</span><span class="token punctuation">,</span>
<span class="token keyword">null</span><span class="token punctuation">,</span>
text <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"You entered "</span><span class="token operator">+</span>text<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>We recommend using the <a href="docs/alert.html" target="_blank"><code>Alert.alert</code></a> method for
cross-platform support if you don't need to create iOS-only prompts.</p></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/alertios.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="alert"></a><span class="methodType">static </span>alert<span class="methodType">(title: string, message?: string, callbackOrButtons?: ?(() =&gt; void), ButtonsArray, type?: AlertType)</span> <a class="hash-link" href="docs/alertios.html#alert">#</a></h4><div><p>Create and display a popup alert.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>title<br><br><div><span>string</span></div></td><td class="description"><div><p>The dialog's title.</p></div></td></tr><tr><td>[message]<br><br><div><span>string</span></div></td><td class="description"><div><p>An optional message that appears below
the dialog's title.</p></div></td></tr><tr><td>[callbackOrButtons]<br><br><div><span>?(() =&gt; void) | </span><span><a href="docs/alertios.html#buttonsarray">ButtonsArray</a></span></div></td><td class="description"><div><p>This optional argument should
be either a single-argument function or an array of buttons. If passed
a function, it will be called when the user taps 'OK'.</p><p> If passed an array of button configurations, each button should include
a <code>text</code> key, as well as optional <code>onPress</code> and <code>style</code> keys. <code>style</code>
should be one of 'default', 'cancel' or 'destructive'.</p></div></td></tr><tr><td>[type]<br><br><div><span><a href="docs/alertios.html#alerttype">AlertType</a></span></div></td><td class="description"><div><p>Deprecated, do not use.</p></div></td></tr></tbody></table></div><div><br>Example with custom buttons:<div class="prism language-javascript">AlertIOS<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span>
<span class="token string">'Update available'</span><span class="token punctuation">,</span>
<span class="token string">'Keep your app up to date to enjoy the latest features'</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span>
<span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">'Cancel'</span><span class="token punctuation">,</span> onPress<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Cancel Pressed'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> <span class="token string">'cancel'</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">'Install'</span><span class="token punctuation">,</span> onPress<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Install Pressed'</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></div></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="prompt"></a><span class="methodType">static </span>prompt<span class="methodType">(title: string, message?: string, callbackOrButtons?: ?((text: string) =&gt; void), ButtonsArray, type?: AlertType, defaultValue?: string, keyboardType?: string)</span> <a class="hash-link" href="docs/alertios.html#prompt">#</a></h4><div><p>Create and display a prompt to enter some text.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>title<br><br><div><span>string</span></div></td><td class="description"><div><p>The dialog's title.</p></div></td></tr><tr><td>[message]<br><br><div><span>string</span></div></td><td class="description"><div><p>An optional message that appears above the text
input.</p></div></td></tr><tr><td>[callbackOrButtons]<br><br><div><span>?((text: string) =&gt; void) | </span><span><a href="docs/alertios.html#buttonsarray">ButtonsArray</a></span></div></td><td class="description"><div><p>This optional argument should
be either a single-argument function or an array of buttons. If passed
a function, it will be called with the prompt's value when the user
taps 'OK'.</p><p> If passed an array of button configurations, each button should include
a <code>text</code> key, as well as optional <code>onPress</code> and <code>style</code> keys (see
example). <code>style</code> should be one of 'default', 'cancel' or 'destructive'.</p></div></td></tr><tr><td>[type]<br><br><div><span><a href="docs/alertios.html#alerttype">AlertType</a></span></div></td><td class="description"><div><p>This configures the text input. One of 'plain-text',
'secure-text' or 'login-password'.</p></div></td></tr><tr><td>[defaultValue]<br><br><div><span>string</span></div></td><td class="description"><div><p>The default text in text input.</p></div></td></tr><tr><td>[keyboardType]<br><br><div><span>string</span></div></td><td class="description"><div><p>The keyboard type of first text field(if exists).
One of 'default', 'email-address', 'numeric', 'phone-pad',
'ascii-capable', 'numbers-and-punctuation', 'url', 'number-pad',
'name-phone-pad', 'decimal-pad', 'twitter' or 'web-search'.</p></div></td></tr></tbody></table></div><div><br>Example with custom buttons:<div class="prism language-javascript">AlertIOS<span class="token punctuation">.</span><span class="token function">prompt</span><span class="token punctuation">(</span>
<span class="token string">'Enter password'</span><span class="token punctuation">,</span>
<span class="token string">'Enter your password to claim your $1.5B in lottery winnings'</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span>
<span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">'Cancel'</span><span class="token punctuation">,</span> onPress<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Cancel Pressed'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> <span class="token string">'cancel'</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span>text<span class="token punctuation">:</span> <span class="token string">'OK'</span><span class="token punctuation">,</span> onPress<span class="token punctuation">:</span> password <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'OK Pressed, password: '</span> <span class="token operator">+</span> password<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token string">'secure-text'</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></div></div><div><br>Example with the default button and a custom callback:<div class="prism language-javascript">AlertIOS<span class="token punctuation">.</span><span class="token function">prompt</span><span class="token punctuation">(</span>
<span class="token string">'Update username'</span><span class="token punctuation">,</span>
<span class="token keyword">null</span><span class="token punctuation">,</span>
text <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Your username is "</span><span class="token operator">+</span>text<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token keyword">null</span><span class="token punctuation">,</span>
<span class="token string">'default'</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></div></div></div></div></span><span><h3><a class="anchor" name="type-definitions"></a>Type Definitions <a class="hash-link" href="docs/alertios.html#type-definitions">#</a></h3><div class="props"><div class="prop"><h4 class="propTitle"><a class="anchor" name="alerttype"></a>AlertType <a class="hash-link" href="docs/alertios.html#alerttype">#</a></h4><div><p>An Alert button type</p></div><strong>Type:</strong><br>$Enum<div><br><strong>Constants:</strong><table class="params"><thead><tr><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>default</td><td class="description"><div><p>Default alert with no inputs</p></div></td></tr><tr><td>plain-text</td><td class="description"><div><p>Plain text input alert</p></div></td></tr><tr><td>secure-text</td><td class="description"><div><p>Secure text input alert</p></div></td></tr><tr><td>login-password</td><td class="description"><div><p>Login and password alert</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="alertbuttonstyle"></a>AlertButtonStyle <a class="hash-link" href="docs/alertios.html#alertbuttonstyle">#</a></h4><div><p>An Alert button style</p></div><strong>Type:</strong><br>$Enum<div><br><strong>Constants:</strong><table class="params"><thead><tr><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>default</td><td class="description"><div><p>Default button style</p></div></td></tr><tr><td>cancel</td><td class="description"><div><p>Cancel button style</p></div></td></tr><tr><td>destructive</td><td class="description"><div><p>Destructive button style</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="buttonsarray"></a>ButtonsArray <a class="hash-link" href="docs/alertios.html#buttonsarray">#</a></h4><div><p>Array or buttons</p></div><strong>Type:</strong><br>Array<div><br><strong>Properties:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>[text]<br><br><div><span>string</span></div></td><td class="description"><div><p>Button label</p></div></td></tr><tr><td>[onPress]<br><br><div><span>function</span></div></td><td class="description"><div><p>Callback function when button pressed</p></div></td></tr><tr><td>[style]<br><br><div><span><a href="docs/alertios.html#alertbuttonstyle">AlertButtonStyle</a></span></div></td><td class="description"><div><p>Button style</p></div></td></tr></tbody></table></div><div><br><strong>Constants:</strong><table class="params"><thead><tr><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>text</td><td class="description"><div><p>Button label</p></div></td></tr><tr><td>onPress</td><td class="description"><div><p>Callback function when button pressed</p></div></td></tr><tr><td>style</td><td class="description"><div><p>Button style</p></div></td></tr></tbody></table></div></div></div></span></div>
+154
View File
@@ -0,0 +1,154 @@
---
id: animated
title: Animated
category: APIs
permalink: docs/animated.html
---
<div><div><p>The <code>Animated</code> library is designed to make animations fluid, powerful, and
easy to build and maintain. <code>Animated</code> focuses on declarative relationships
between inputs and outputs, with configurable transforms in between, and
simple <code>start</code>/<code>stop</code> methods to control time-based animation execution.</p><p>The simplest workflow for creating an animation is to to create an
<code>Animated.Value</code>, hook it up to one or more style attributes of an animated
component, and then drive updates via animations using <code>Animated.timing()</code>:</p><div class="prism language-javascript">Animated<span class="token punctuation">.</span><span class="token function">timing</span><span class="token punctuation">(</span> <span class="token comment" spellcheck="true"> // Animate value over time
</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>fadeAnim<span class="token punctuation">,</span> <span class="token comment" spellcheck="true"> // The value to drive
</span> <span class="token punctuation">{</span>
toValue<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true"> // Animate to final value of 1
</span> <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true"> // Start the animation</span></div><p>Refer to the <a href="docs/animations.html#animated-api" target="_blank">Animations</a> guide to see
additional examples of <code>Animated</code> in action.</p><h2><a class="anchor" name="overview"></a>Overview <a class="hash-link" href="docs/animated.html#overview">#</a></h2><p>There are two value types you can use with <code>Animated</code>:</p><ul><li><a href="docs/animated.html#value" target="_blank"><code>Animated.Value()</code></a> for single values</li><li><a href="docs/animated.html#valuexy" target="_blank"><code>Animated.ValueXY()</code></a> for vectors</li></ul><p><code>Animated.Value</code> can bind to style properties or other props, and can be
interpolated as well. A single <code>Animated.Value</code> can drive any number of
properties.</p><h3><a class="anchor" name="configuring-animations"></a>Configuring animations <a class="hash-link" href="docs/animated.html#configuring-animations">#</a></h3><p><code>Animated</code> provides three types of animation types. Each animation type
provides a particular animation curve that controls how your values animate
from their initial value to the final value:</p><ul><li><a href="docs/animated.html#decay" target="_blank"><code>Animated.decay()</code></a> starts with an initial
velocity and gradually slows to a stop.</li><li><a href="docs/animated.html#spring" target="_blank"><code>Animated.spring()</code></a> provides a simple
spring physics model.</li><li><a href="docs/animated.html#timing" target="_blank"><code>Animated.timing()</code></a> animates a value over time
using <a href="docs/easing.html" target="_blank">easing functions</a>.</li></ul><p>In most cases, you will be using <code>timing()</code>. By default, it uses a symmetric
easeInOut curve that conveys the gradual acceleration of an object to full
speed and concludes by gradually decelerating to a stop.</p><h3><a class="anchor" name="working-with-animations"></a>Working with animations <a class="hash-link" href="docs/animated.html#working-with-animations">#</a></h3><p>Animations are started by calling <code>start()</code> on your animation. <code>start()</code>
takes a completion callback that will be called when the animation is done.
If the animation finished running normally, the completion callback will be
invoked with <code>{finished: true}</code>. If the animation is done because <code>stop()</code>
was called on it before it could finish (e.g. because it was interrupted by a
gesture or another animation), then it will receive <code>{finished: false}</code>.</p><h3><a class="anchor" name="using-the-native-driver"></a>Using the native driver <a class="hash-link" href="docs/animated.html#using-the-native-driver">#</a></h3><p>By using the native driver, we send everything about the animation to native
before starting the animation, allowing native code to perform the animation
on the UI thread without having to go through the bridge on every frame.
Once the animation has started, the JS thread can be blocked without
affecting the animation.</p><p>You can use the native driver by specifying <code>useNativeDriver: true</code> in your
animation configuration. See the
<a href="docs/animations.html#using-the-native-driver" target="_blank">Animations</a> guide to learn
more.</p><h3><a class="anchor" name="animatable-components"></a>Animatable components <a class="hash-link" href="docs/animated.html#animatable-components">#</a></h3><p>Only animatable components can be animated. These special components do the
magic of binding the animated values to the properties, and do targeted
native updates to avoid the cost of the react render and reconciliation
process on every frame. They also handle cleanup on unmount so they are safe
by default.</p><ul><li><a href="docs/animated.html#createanimatedcomponent" target="_blank"><code>createAnimatedComponent()</code></a>
can be used to make a component animatable.</li></ul><p><code>Animated</code> exports the following animatable components using the above
wrapper:</p><ul><li><code>Animated.Image</code></li><li><code>Animated.ScrollView</code></li><li><code>Animated.Text</code></li><li><code>Animated.View</code></li></ul><h3><a class="anchor" name="composing-animations"></a>Composing animations <a class="hash-link" href="docs/animated.html#composing-animations">#</a></h3><p>Animations can also be combined in complex ways using composition functions:</p><ul><li><a href="docs/animated.html#delay" target="_blank"><code>Animated.delay()</code></a> starts an animation after
a given delay.</li><li><a href="docs/animated.html#parallel" target="_blank"><code>Animated.parallel()</code></a> starts a number of
animations at the same time.</li><li><a href="docs/animated.html#sequence" target="_blank"><code>Animated.sequence()</code></a> starts the animations
in order, waiting for each to complete before starting the next.</li><li><a href="docs/animated.html#stagger" target="_blank"><code>Animated.stagger()</code></a> starts animations in
order and in parallel, but with successive delays.</li></ul><p>Animations can also be chained together simply by setting the <code>toValue</code> of
one animation to be another <code>Animated.Value</code>. See
<a href="docs/animations.html#tracking-dynamic-values" target="_blank">Tracking dynamic values</a> in
the Animations guide.</p><p>By default, if one animation is stopped or interrupted, then all other
animations in the group are also stopped.</p><h3><a class="anchor" name="combining-animated-values"></a>Combining animated values <a class="hash-link" href="docs/animated.html#combining-animated-values">#</a></h3><p>You can combine two animated values via addition, multiplication, division,
or modulo to make a new animated value:</p><ul><li><a href="docs/animated.html#add" target="_blank"><code>Animated.add()</code></a></li><li><a href="docs/animated.html#divide" target="_blank"><code>Animated.divide()</code></a></li><li><a href="docs/animated.html#modulo" target="_blank"><code>Animated.modulo()</code></a></li><li><a href="docs/animated.html#multiply" target="_blank"><code>Animated.multiply()</code></a></li></ul><h3><a class="anchor" name="interpolation"></a>Interpolation <a class="hash-link" href="docs/animated.html#interpolation">#</a></h3><p>The <code>interpolate()</code> function allows input ranges to map to different output
ranges. By default, it will extrapolate the curve beyond the ranges given,
but you can also have it clamp the output value. It uses lineal interpolation
by default but also supports easing functions.</p><ul><li><a href="docs/animated.html#interpolate" target="_blank"><code>interpolate()</code></a></li></ul><p>Read more about interpolation in the
<a href="docs/animations.html#interpolation" target="_blank">Animation</a> guide.</p><h3><a class="anchor" name="handling-gestures-and-other-events"></a>Handling gestures and other events <a class="hash-link" href="docs/animated.html#handling-gestures-and-other-events">#</a></h3><p>Gestures, like panning or scrolling, and other events can map directly to
animated values using <code>Animated.event()</code>. This is done with a structured map
syntax so that values can be extracted from complex event objects. The first
level is an array to allow mapping across multiple args, and that array
contains nested objects.</p><ul><li><a href="docs/animated.html#event" target="_blank"><code>Animated.event()</code></a></li></ul><p>For example, when working with horizontal scrolling gestures, you would do
the following in order to map <code>event.nativeEvent.contentOffset.x</code> to
<code>scrollX</code> (an <code>Animated.Value</code>):</p><div class="prism language-javascript"> onScroll<span class="token operator">=</span><span class="token punctuation">{</span>Animated<span class="token punctuation">.</span><span class="token function">event</span><span class="token punctuation">(</span>
<span class="token comment" spellcheck="true"> // scrollX = e.nativeEvent.contentOffset.x
</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> nativeEvent<span class="token punctuation">:</span> <span class="token punctuation">{</span>
contentOffset<span class="token punctuation">:</span> <span class="token punctuation">{</span>
x<span class="token punctuation">:</span> scrollX
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">]</span>
<span class="token punctuation">)</span><span class="token punctuation">}</span></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/animated.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="decay"></a><span class="methodType">static </span>decay<span class="methodType">(value, config)</span> <a class="hash-link" href="docs/animated.html#decay">#</a></h4><div><p>Animates a value from an initial velocity to zero based on a decay
coefficient.</p><p>Config is an object that may have the following options:</p><ul><li><code>velocity</code>: Initial velocity. Required.</li><li><code>deceleration</code>: Rate of decay. Default 0.997.</li><li><code>useNativeDriver</code>: Uses the native driver when true. Default false.</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="timing"></a><span class="methodType">static </span>timing<span class="methodType">(value, config)</span> <a class="hash-link" href="docs/animated.html#timing">#</a></h4><div><p>Animates a value along a timed easing curve. The
<a href="docs/easing.html" target="_blank"><code>Easing</code></a> module has tons of predefined curves, or you
can use your own function.</p><p>Config is an object that may have the following options:</p><ul><li><code>duration</code>: Length of animation (milliseconds). Default 500.</li><li><code>easing</code>: Easing function to define curve.
Default is <code>Easing.inOut(Easing.ease)</code>.</li><li><code>delay</code>: Start the animation after delay (milliseconds). Default 0.</li><li><code>useNativeDriver</code>: Uses the native driver when true. Default false.</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="spring"></a><span class="methodType">static </span>spring<span class="methodType">(value, config)</span> <a class="hash-link" href="docs/animated.html#spring">#</a></h4><div><p>Spring animation based on Rebound and
<a href="https://facebook.github.io/origami/" target="_blank">Origami</a>. Tracks velocity state to
create fluid motions as the <code>toValue</code> updates, and can be chained together.</p><p>Config is an object that may have the following options. Note that you can
only define bounciness/speed or tension/friction but not both:</p><ul><li><code>friction</code>: Controls "bounciness"/overshoot. Default 7.</li><li><code>tension</code>: Controls speed. Default 40.</li><li><code>speed</code>: Controls speed of the animation. Default 12.</li><li><code>bounciness</code>: Controls bounciness. Default 8.</li><li><code>useNativeDriver</code>: Uses the native driver when true. Default false.</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="add"></a><span class="methodType">static </span>add<span class="methodType">(a, b)</span> <a class="hash-link" href="docs/animated.html#add">#</a></h4><div><p>Creates a new Animated value composed from two Animated values added
together.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="divide"></a><span class="methodType">static </span>divide<span class="methodType">(a, b)</span> <a class="hash-link" href="docs/animated.html#divide">#</a></h4><div><p>Creates a new Animated value composed by dividing the first Animated value
by the second Animated value.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="multiply"></a><span class="methodType">static </span>multiply<span class="methodType">(a, b)</span> <a class="hash-link" href="docs/animated.html#multiply">#</a></h4><div><p>Creates a new Animated value composed from two Animated values multiplied
together.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="modulo"></a><span class="methodType">static </span>modulo<span class="methodType">(a, modulus)</span> <a class="hash-link" href="docs/animated.html#modulo">#</a></h4><div><p>Creates a new Animated value that is the (non-negative) modulo of the
provided Animated value</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="diffclamp"></a><span class="methodType">static </span>diffClamp<span class="methodType">(a, min, max)</span> <a class="hash-link" href="docs/animated.html#diffclamp">#</a></h4><div><p>Create a new Animated value that is limited between 2 values. It uses the
difference between the last value so even if the value is far from the bounds
it will start changing when the value starts getting closer again.
(<code>value = clamp(value + diff, min, max)</code>).</p><p>This is useful with scroll events, for example, to show the navbar when
scrolling up and to hide it when scrolling down.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="delay"></a><span class="methodType">static </span>delay<span class="methodType">(time)</span> <a class="hash-link" href="docs/animated.html#delay">#</a></h4><div><p>Starts an animation after the given delay.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="sequence"></a><span class="methodType">static </span>sequence<span class="methodType">(animations)</span> <a class="hash-link" href="docs/animated.html#sequence">#</a></h4><div><p>Starts an array of animations in order, waiting for each to complete
before starting the next. If the current running animation is stopped, no
following animations will be started.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="parallel"></a><span class="methodType">static </span>parallel<span class="methodType">(animations, config?)</span> <a class="hash-link" href="docs/animated.html#parallel">#</a></h4><div><p>Starts an array of animations all at the same time. By default, if one
of the animations is stopped, they will all be stopped. You can override
this with the <code>stopTogether</code> flag.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="stagger"></a><span class="methodType">static </span>stagger<span class="methodType">(time, animations)</span> <a class="hash-link" href="docs/animated.html#stagger">#</a></h4><div><p>Array of animations may run in parallel (overlap), but are started in
sequence with successive delays. Nice for doing trailing effects.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="loop"></a><span class="methodType">static </span>loop<span class="methodType">(animation)</span> <a class="hash-link" href="docs/animated.html#loop">#</a></h4><div><p>Loops a given animation continuously, so that each time it reaches the
end, it resets and begins again from the start. Can specify number of
times to loop using the key 'iterations' in the config. Will loop without
blocking the UI thread if the child animation is set to 'useNativeDriver'.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="event"></a><span class="methodType">static </span>event<span class="methodType">(argMapping, config?)</span> <a class="hash-link" href="docs/animated.html#event">#</a></h4><div><p>Takes an array of mappings and extracts values from each arg accordingly,
then calls <code>setValue</code> on the mapped outputs. e.g.</p><div class="prism language-javascript"> onScroll<span class="token operator">=</span><span class="token punctuation">{</span>Animated<span class="token punctuation">.</span><span class="token function">event</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token punctuation">{</span>nativeEvent<span class="token punctuation">:</span> <span class="token punctuation">{</span>contentOffset<span class="token punctuation">:</span> <span class="token punctuation">{</span>x<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_scrollX<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span>listener<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true"> // Optional async listener
</span> <span class="token punctuation">)</span><span class="token punctuation">}</span>
<span class="token operator">...</span>
onPanResponderMove<span class="token punctuation">:</span> Animated<span class="token punctuation">.</span><span class="token function">event</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
<span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true"> // raw event arg ignored
</span> <span class="token punctuation">{</span>dx<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_panX<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true"> // gestureState arg
</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span></div><p>Config is an object that may have the following options:</p><ul><li><code>listener</code>: Optional async listener.</li><li><code>useNativeDriver</code>: Uses the native driver when true. Default false.</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="createanimatedcomponent"></a><span class="methodType">static </span>createAnimatedComponent<span class="methodType">(Component)</span> <a class="hash-link" href="docs/animated.html#createanimatedcomponent">#</a></h4><div><p>Make any React component Animatable. Used to create <code>Animated.View</code>, etc.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="attachnativeevent"></a><span class="methodType">static </span>attachNativeEvent<span class="methodType">(viewRef, eventName, argMapping)</span> <a class="hash-link" href="docs/animated.html#attachnativeevent">#</a></h4><div><p>Imperative API to attach an animated value to an event on a view. Prefer using
<code>Animated.event</code> with <code>useNativeDrive: true</code> if possible.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="forkevent"></a><span class="methodType">static </span>forkEvent<span class="methodType">(event, listener)</span> <a class="hash-link" href="docs/animated.html#forkevent">#</a></h4><div><p>Advanced imperative API for snooping on animated events that are passed in through props. Use
values directly where possible.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="unforkevent"></a><span class="methodType">static </span>unforkEvent<span class="methodType">(event, listener)</span> <a class="hash-link" href="docs/animated.html#unforkevent">#</a></h4></div></div></span><span><h3><a class="anchor" name="properties"></a>Properties <a class="hash-link" href="docs/animated.html#properties">#</a></h3><div class="props"><div class="prop"><h4 class="propTitle"><a class="anchor" name="value"></a>Value<span class="propType">: AnimatedValue</span> <a class="hash-link" href="docs/animated.html#value">#</a></h4><div><p>Standard value class for driving animations. Typically initialized with
<code>new Animated.Value(0);</code></p><p>See also <a href="docs/animated.html#animatedvalue" target="_blank"><code>AnimatedValue</code></a>.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="valuexy"></a>ValueXY<span class="propType">: AnimatedValueXY</span> <a class="hash-link" href="docs/animated.html#valuexy">#</a></h4><div><p>2D value class for driving 2D animations, such as pan gestures.</p><p>See also <a href="docs/animated.html#animatedvaluexy" target="_blank"><code>AnimatedValueXY</code></a>.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="interpolation"></a>Interpolation<span class="propType">: AnimatedInterpolation</span> <a class="hash-link" href="docs/animated.html#interpolation">#</a></h4><div><p>exported to use the Interpolation type in flow</p><p>See also <a href="docs/animated.html#animatedinterpolation" target="_blank"><code>AnimatedInterpolation</code></a>.</p></div></div></div></span><span><div><span><h2><a class="anchor" name="animatedvalue"></a>class AnimatedValue <a class="hash-link" href="docs/animated.html#animatedvalue">#</a></h2><div><div><p>Standard value for driving animations. One <code>Animated.Value</code> can drive
multiple properties in a synchronized fashion, but can only be driven by one
mechanism at a time. Using a new mechanism (e.g. starting a new animation,
or calling <code>setValue</code>) will stop any previous ones.</p></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/animated.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="constructor"></a>constructor<span class="methodType">(value)</span> <a class="hash-link" href="docs/animated.html#constructor">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setvalue"></a>setValue<span class="methodType">(value)</span> <a class="hash-link" href="docs/animated.html#setvalue">#</a></h4><div><p>Directly set the value. This will stop any animations running on the value
and update all the bound properties.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setoffset"></a>setOffset<span class="methodType">(offset)</span> <a class="hash-link" href="docs/animated.html#setoffset">#</a></h4><div><p>Sets an offset that is applied on top of whatever value is set, whether via
<code>setValue</code>, an animation, or <code>Animated.event</code>. Useful for compensating
things like the start of a pan gesture.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="flattenoffset"></a>flattenOffset<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#flattenoffset">#</a></h4><div><p>Merges the offset value into the base value and resets the offset to zero.
The final output of the value is unchanged.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="extractoffset"></a>extractOffset<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#extractoffset">#</a></h4><div><p>Sets the offset value to the base value, and resets the base value to zero.
The final output of the value is unchanged.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="addlistener"></a>addListener<span class="methodType">(callback)</span> <a class="hash-link" href="docs/animated.html#addlistener">#</a></h4><div><p>Adds an asynchronous listener to the value so you can observe updates from
animations. This is useful because there is no way to
synchronously read the value because it might be driven natively.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removelistener"></a>removeListener<span class="methodType">(id)</span> <a class="hash-link" href="docs/animated.html#removelistener">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removealllisteners"></a>removeAllListeners<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#removealllisteners">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="stopanimation"></a>stopAnimation<span class="methodType">(callback?)</span> <a class="hash-link" href="docs/animated.html#stopanimation">#</a></h4><div><p>Stops any running animation or tracking. <code>callback</code> is invoked with the
final value after stopping the animation, which is useful for updating
state to match the animation position with layout.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="resetanimation"></a>resetAnimation<span class="methodType">(callback?)</span> <a class="hash-link" href="docs/animated.html#resetanimation">#</a></h4><div><p>Stops any animation and resets the value to its original</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="interpolate"></a>interpolate<span class="methodType">(config)</span> <a class="hash-link" href="docs/animated.html#interpolate">#</a></h4><div><p>Interpolates the value before updating the property, e.g. mapping 0-1 to
0-10.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="animate"></a>animate<span class="methodType">(animation, callback)</span> <a class="hash-link" href="docs/animated.html#animate">#</a></h4><div><p>Typically only used internally, but could be used by a custom Animation
class.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="stoptracking"></a>stopTracking<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#stoptracking">#</a></h4><div><p>Typically only used internally.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="track"></a>track<span class="methodType">(tracking)</span> <a class="hash-link" href="docs/animated.html#track">#</a></h4><div><p>Typically only used internally.</p></div></div></div></span></div></span><span><h2><a class="anchor" name="animatedvaluexy"></a>class AnimatedValueXY <a class="hash-link" href="docs/animated.html#animatedvaluexy">#</a></h2><div><div><p>2D Value for driving 2D animations, such as pan gestures. Almost identical
API to normal <code>Animated.Value</code>, but multiplexed. Contains two regular
<code>Animated.Value</code>s under the hood.</p><h4><a class="anchor" name="example"></a>Example <a class="hash-link" href="docs/animated.html#example">#</a></h4><div class="prism language-javascript"> <span class="token keyword">class</span> <span class="token class-name">DraggableView</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
<span class="token function">constructor</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span>
pan<span class="token punctuation">:</span> <span class="token keyword">new</span> <span class="token class-name">Animated<span class="token punctuation">.</span>ValueXY</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token comment" spellcheck="true"> // inits to zero
</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>panResponder <span class="token operator">=</span> PanResponder<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
onStartShouldSetPanResponder<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
onPanResponderMove<span class="token punctuation">:</span> Animated<span class="token punctuation">.</span><span class="token function">event</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
dx<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>pan<span class="token punctuation">.</span>x<span class="token punctuation">,</span><span class="token comment" spellcheck="true"> // x,y are Animated.Value
</span> dy<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>pan<span class="token punctuation">.</span>y<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
onPanResponderRelease<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
Animated<span class="token punctuation">.</span><span class="token function">spring</span><span class="token punctuation">(</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>pan<span class="token punctuation">,</span> <span class="token comment" spellcheck="true"> // Auto-multiplexed
</span> <span class="token punctuation">{</span>toValue<span class="token punctuation">:</span> <span class="token punctuation">{</span>x<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> y<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true"> // Back to zero
</span> <span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token operator">&lt;</span>Animated<span class="token punctuation">.</span>View
<span class="token punctuation">{</span><span class="token operator">...</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>panResponder<span class="token punctuation">.</span>panHandlers<span class="token punctuation">}</span>
style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>pan<span class="token punctuation">.</span><span class="token function">getLayout</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
<span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>Animated<span class="token punctuation">.</span>View<span class="token operator">&gt;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/animated.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="constructor"></a>constructor<span class="methodType">(valueIn?)</span> <a class="hash-link" href="docs/animated.html#constructor">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setvalue"></a>setValue<span class="methodType">(value)</span> <a class="hash-link" href="docs/animated.html#setvalue">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setoffset"></a>setOffset<span class="methodType">(offset)</span> <a class="hash-link" href="docs/animated.html#setoffset">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="flattenoffset"></a>flattenOffset<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#flattenoffset">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="extractoffset"></a>extractOffset<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#extractoffset">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="resetanimation"></a>resetAnimation<span class="methodType">(callback?)</span> <a class="hash-link" href="docs/animated.html#resetanimation">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="stopanimation"></a>stopAnimation<span class="methodType">(callback?)</span> <a class="hash-link" href="docs/animated.html#stopanimation">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="addlistener"></a>addListener<span class="methodType">(callback)</span> <a class="hash-link" href="docs/animated.html#addlistener">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removelistener"></a>removeListener<span class="methodType">(id)</span> <a class="hash-link" href="docs/animated.html#removelistener">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removealllisteners"></a>removeAllListeners<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#removealllisteners">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getlayout"></a>getLayout<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#getlayout">#</a></h4><div><p>Converts <code>{x, y}</code> into <code>{left, top}</code> for use in style, e.g.</p><div class="prism language-javascript"> style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>anim<span class="token punctuation">.</span><span class="token function">getLayout</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span></div></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="gettranslatetransform"></a>getTranslateTransform<span class="methodType">()</span> <a class="hash-link" href="docs/animated.html#gettranslatetransform">#</a></h4><div><p>Converts <code>{x, y}</code> into a useable translation transform, e.g.</p><div class="prism language-javascript"> style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>
transform<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>anim<span class="token punctuation">.</span><span class="token function">getTranslateTransform</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">}</span></div></div></div></div></span></div></span><span><h2><a class="anchor" name="animatedinterpolation"></a>class AnimatedInterpolation <a class="hash-link" href="docs/animated.html#animatedinterpolation">#</a></h2><div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/animated.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="constructor"></a>constructor<span class="methodType">(parent, config)</span> <a class="hash-link" href="docs/animated.html#constructor">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="interpolate"></a>interpolate<span class="methodType">(config)</span> <a class="hash-link" href="docs/animated.html#interpolate">#</a></h4></div></div></span></div></span></div></span></div>
+32
View File
@@ -0,0 +1,32 @@
---
id: appregistry
title: AppRegistry
category: APIs
permalink: docs/appregistry.html
---
<div><div><span><div class="banner-crna-ejected">
<h3>Project with Native Code Required</h3>
<p>
This API only works in projects made with <code>react-native init</code>
or in those made with Create React Native App which have since ejected. For
more information about ejecting, please see
the <a href="https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md" target="_blank">guide</a> on
the Create React Native App repository.
</p>
</div>
</span><p><code>AppRegistry</code> is the JS entry point to running all React Native apps. App
root components should register themselves with
<code>AppRegistry.registerComponent</code>, then the native system can load the bundle
for the app and then actually run the app when it's ready by invoking
<code>AppRegistry.runApplication</code>.</p><p>To "stop" an application when a view should be destroyed, call
<code>AppRegistry.unmountApplicationComponentAtRootTag</code> with the tag that was
passed into <code>runApplication</code>. These should always be used as a pair.</p><p><code>AppRegistry</code> should be <code>require</code>d early in the <code>require</code> sequence to make
sure the JS execution environment is setup before other modules are
<code>require</code>d.</p></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/appregistry.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setwrappercomponentprovider"></a><span class="methodType">static </span>setWrapperComponentProvider<span class="methodType">(provider)</span> <a class="hash-link" href="docs/appregistry.html#setwrappercomponentprovider">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="registerconfig"></a><span class="methodType">static </span>registerConfig<span class="methodType">(config)</span> <a class="hash-link" href="docs/appregistry.html#registerconfig">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="registercomponent"></a><span class="methodType">static </span>registerComponent<span class="methodType">(appKey, componentProvider, section?)</span> <a class="hash-link" href="docs/appregistry.html#registercomponent">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="registerrunnable"></a><span class="methodType">static </span>registerRunnable<span class="methodType">(appKey, run)</span> <a class="hash-link" href="docs/appregistry.html#registerrunnable">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="registersection"></a><span class="methodType">static </span>registerSection<span class="methodType">(appKey, component)</span> <a class="hash-link" href="docs/appregistry.html#registersection">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getappkeys"></a><span class="methodType">static </span>getAppKeys<span class="methodType">()</span> <a class="hash-link" href="docs/appregistry.html#getappkeys">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getsectionkeys"></a><span class="methodType">static </span>getSectionKeys<span class="methodType">()</span> <a class="hash-link" href="docs/appregistry.html#getsectionkeys">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getsections"></a><span class="methodType">static </span>getSections<span class="methodType">()</span> <a class="hash-link" href="docs/appregistry.html#getsections">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getrunnable"></a><span class="methodType">static </span>getRunnable<span class="methodType">(appKey)</span> <a class="hash-link" href="docs/appregistry.html#getrunnable">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getregistry"></a><span class="methodType">static </span>getRegistry<span class="methodType">()</span> <a class="hash-link" href="docs/appregistry.html#getregistry">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setcomponentproviderinstrumentationhook"></a><span class="methodType">static </span>setComponentProviderInstrumentationHook<span class="methodType">(hook)</span> <a class="hash-link" href="docs/appregistry.html#setcomponentproviderinstrumentationhook">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="runapplication"></a><span class="methodType">static </span>runApplication<span class="methodType">(appKey, appParameters)</span> <a class="hash-link" href="docs/appregistry.html#runapplication">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="unmountapplicationcomponentatroottag"></a><span class="methodType">static </span>unmountApplicationComponentAtRootTag<span class="methodType">(rootTag)</span> <a class="hash-link" href="docs/appregistry.html#unmountapplicationcomponentatroottag">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="registerheadlesstask"></a><span class="methodType">static </span>registerHeadlessTask<span class="methodType">(taskKey, task)</span> <a class="hash-link" href="docs/appregistry.html#registerheadlesstask">#</a></h4><div><p>Register a headless task. A headless task is a bit of code that runs without a UI.
@param taskKey the key associated with this task
@param task a promise returning function that takes some data passed from the native side as
the only argument; when the promise is resolved or rejected the native side is
notified of this event and it may decide to destroy the JS context.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="startheadlesstask"></a><span class="methodType">static </span>startHeadlessTask<span class="methodType">(taskId, taskKey, data)</span> <a class="hash-link" href="docs/appregistry.html#startheadlesstask">#</a></h4><div><p>Only called from native code. Starts a headless task.</p><p>@param taskId the native id for this task instance to keep track of its execution
@param taskKey the key for the task to start
@param data the data to pass to the task</p></div></div></div></span></div>
+52
View File
@@ -0,0 +1,52 @@
---
id: appstate
title: AppState
category: APIs
permalink: docs/appstate.html
---
<div><div><p><code>AppState</code> can tell you if the app is in the foreground or background,
and notify you when the state changes.</p><p>AppState is frequently used to determine the intent and proper behavior when
handling push notifications.</p><h3><a class="anchor" name="app-states"></a>App States <a class="hash-link" href="docs/appstate.html#app-states">#</a></h3><ul><li><code>active</code> - The app is running in the foreground</li><li><code>background</code> - The app is running in the background. The user is either
in another app or on the home screen</li><li><code>inactive</code> - This is a state that occurs when transitioning between
foreground &amp; background, and during periods of inactivity such as
entering the Multitasking view or in the event of an incoming call</li></ul><p>For more information, see
<a href="https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html" target="_blank">Apple's documentation</a></p><h3><a class="anchor" name="basic-usage"></a>Basic Usage <a class="hash-link" href="docs/appstate.html#basic-usage">#</a></h3><p>To see the current state, you can check <code>AppState.currentState</code>, which
will be kept up-to-date. However, <code>currentState</code> will be null at launch
while <code>AppState</code> retrieves it over the bridge.</p><div class="prism language-javascript"><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span>Component<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>AppState<span class="token punctuation">,</span> Text<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-native'</span>
<span class="token keyword">class</span> <span class="token class-name">AppStateExample</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
state <span class="token operator">=</span> <span class="token punctuation">{</span>
appState<span class="token punctuation">:</span> AppState<span class="token punctuation">.</span>currentState
<span class="token punctuation">}</span>
<span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
AppState<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'change'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_handleAppStateChange<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
AppState<span class="token punctuation">.</span><span class="token function">removeEventListener</span><span class="token punctuation">(</span><span class="token string">'change'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>_handleAppStateChange<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
_handleAppStateChange <span class="token operator">=</span> <span class="token punctuation">(</span>nextAppState<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>appState<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span><span class="token regex">/inactive|background/</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> nextAppState <span class="token operator">===</span> <span class="token string">'active'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'App has come to the foreground!'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span>appState<span class="token punctuation">:</span> nextAppState<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token operator">&lt;</span>Text<span class="token operator">&gt;</span>Current state is<span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>appState<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>Text<span class="token operator">&gt;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></div><p>This example will only ever appear to say "Current state is: active" because
the app is only visible to the user when in the <code>active</code> state, and the null
state will happen only momentarily.</p></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/appstate.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name=""></a>=<span class="methodType">(;, ()</span> <a class="hash-link" href="docs/appstate.html#">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="addeventlistener"></a>addEventListener<span class="methodType">(type, handler)</span> <a class="hash-link" href="docs/appstate.html#addeventlistener">#</a></h4><div><p>Add a handler to AppState changes by listening to the <code>change</code> event type
and providing the handler</p><p>TODO: now that AppState is a subclass of NativeEventEmitter, we could deprecate
<code>addEventListener</code> and <code>removeEventListener</code> and just use <code>addListener</code> and
<code>listener.remove()</code> directly. That will be a breaking change though, as both
the method and event names are different (addListener events are currently
required to be globally unique).</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removeeventlistener"></a>removeEventListener<span class="methodType">(type, handler)</span> <a class="hash-link" href="docs/appstate.html#removeeventlistener">#</a></h4><div><p>Remove a handler by passing the <code>change</code> event type and the handler</p></div></div></div></span></div>
+124
View File
@@ -0,0 +1,124 @@
---
id: asyncstorage
title: AsyncStorage
category: APIs
permalink: docs/asyncstorage.html
---
<div><div><p><code>AsyncStorage</code> is a simple, unencrypted, asynchronous, persistent, key-value storage
system that is global to the app. It should be used instead of LocalStorage.</p><p>It is recommended that you use an abstraction on top of <code>AsyncStorage</code>
instead of <code>AsyncStorage</code> directly for anything more than light usage since
it operates globally.</p><p>On iOS, <code>AsyncStorage</code> is backed by native code that stores small values in a
serialized dictionary and larger values in separate files. On Android,
<code>AsyncStorage</code> will use either <a href="http://rocksdb.org/" target="_blank">RocksDB</a> or SQLite
based on what is available.</p><p>The <code>AsyncStorage</code> JavaScript code is a simple facade that provides a clear
JavaScript API, real <code>Error</code> objects, and simple non-multi functions. Each
method in the API returns a <code>Promise</code> object.</p><p>Persisting data:</p><div class="prism language-javascript"><span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">await</span> AsyncStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">'@MySuperStore:key'</span><span class="token punctuation">,</span> <span class="token string">'I like to save it.'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // Error saving data
</span><span class="token punctuation">}</span></div><p>Fetching data:</p><div class="prism language-javascript"><span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> value <span class="token operator">=</span> <span class="token keyword">await</span> AsyncStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">'@MySuperStore:key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">!==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // We have data!!
</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // Error retrieving data
</span><span class="token punctuation">}</span></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/asyncstorage.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getitem"></a><span class="methodType">static </span>getItem<span class="methodType">(key: string, callback?: ?(error: ?Error, result: ?string) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#getitem">#</a></h4><div><p>Fetches an item for a <code>key</code> and invokes a callback upon completion.
Returns a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>key<br><br><div><span>string</span></div></td><td class="description"><div><p>Key of the item to fetch.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(error: ?Error, result: ?string) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with a result if found or
any error.</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setitem"></a><span class="methodType">static </span>setItem<span class="methodType">(key: string, value: string, callback?: ?(error: ?Error) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#setitem">#</a></h4><div><p>Sets the value for a <code>key</code> and invokes a callback upon completion.
Returns a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>key<br><br><div><span>string</span></div></td><td class="description"><div><p>Key of the item to set.</p></div></td></tr><tr><td>value<br><br><div><span>string</span></div></td><td class="description"><div><p>Value to set for the <code>key</code>.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(error: ?Error) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with any error.</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removeitem"></a><span class="methodType">static </span>removeItem<span class="methodType">(key: string, callback?: ?(error: ?Error) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#removeitem">#</a></h4><div><p>Removes an item for a <code>key</code> and invokes a callback upon completion.
Returns a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>key<br><br><div><span>string</span></div></td><td class="description"><div><p>Key of the item to remove.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(error: ?Error) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with any error.</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="mergeitem"></a><span class="methodType">static </span>mergeItem<span class="methodType">(key: string, value: string, callback?: ?(error: ?Error) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#mergeitem">#</a></h4><div><p>Merges an existing <code>key</code> value with an input value, assuming both values
are stringified JSON. Returns a <code>Promise</code> object.</p><p><strong>NOTE:</strong> This is not supported by all native implementations.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>key<br><br><div><span>string</span></div></td><td class="description"><div><p>Key of the item to modify.</p></div></td></tr><tr><td>value<br><br><div><span>string</span></div></td><td class="description"><div><p>New value to merge for the <code>key</code>.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(error: ?Error) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with any error.</p></div></td></tr></tbody></table></div><div><br>Example:<div class="prism language-javascript">
<span class="token keyword">let</span> UID123_object <span class="token operator">=</span> <span class="token punctuation">{</span>
name<span class="token punctuation">:</span> <span class="token string">'Chris'</span><span class="token punctuation">,</span>
age<span class="token punctuation">:</span> <span class="token number">30</span><span class="token punctuation">,</span>
traits<span class="token punctuation">:</span> <span class="token punctuation">{</span>hair<span class="token punctuation">:</span> <span class="token string">'brown'</span><span class="token punctuation">,</span> eyes<span class="token punctuation">:</span> <span class="token string">'brown'</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">
// You only need to define what will be added or updated
</span><span class="token keyword">let</span> UID123_delta <span class="token operator">=</span> <span class="token punctuation">{</span>
age<span class="token punctuation">:</span> <span class="token number">31</span><span class="token punctuation">,</span>
traits<span class="token punctuation">:</span> <span class="token punctuation">{</span>eyes<span class="token punctuation">:</span> <span class="token string">'blue'</span><span class="token punctuation">,</span> shoe_size<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">'UID123'</span><span class="token punctuation">,</span> JSON<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>UID123_object<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">mergeItem</span><span class="token punctuation">(</span><span class="token string">'UID123'</span><span class="token punctuation">,</span> JSON<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>UID123_delta<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">'UID123'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>err<span class="token punctuation">,</span> result<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">
// Console log result:
</span><span class="token comment" spellcheck="true">// =&gt; {'name':'Chris','age':31,'traits':
</span><span class="token comment" spellcheck="true">// {'shoe_size':10,'hair':'brown','eyes':'blue'}}</span></div></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="clear"></a><span class="methodType">static </span>clear<span class="methodType">(callback?: ?(error: ?Error) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#clear">#</a></h4><div><p>Erases <em>all</em> <code>AsyncStorage</code> for all clients, libraries, etc. You probably
don't want to call this; use <code>removeItem</code> or <code>multiRemove</code> to clear only
your app's keys. Returns a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>[callback]<br><br><div><span>?(error: ?Error) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with any error.</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getallkeys"></a><span class="methodType">static </span>getAllKeys<span class="methodType">(callback?: ?(error: ?Error, keys: ?Array&lt;string&gt;) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#getallkeys">#</a></h4><div><p>Gets <em>all</em> keys known to your app; for all callers, libraries, etc.
Returns a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>[callback]<br><br><div><span>?(error: ?Error, keys: ?Array&lt;string&gt;) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called the keys found and any error.</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="flushgetrequests"></a><span class="methodType">static </span>flushGetRequests<span class="methodType">()</span> <a class="hash-link" href="docs/asyncstorage.html#flushgetrequests">#</a></h4><div><p>Flushes any pending requests using a single batch call to get the data.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="multiget"></a><span class="methodType">static </span>multiGet<span class="methodType">(keys: Array&lt;string&gt;, callback?: ?(errors: ?Array&lt;Error&gt;, result: ?Array&lt;Array&lt;string&gt;&gt;) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#multiget">#</a></h4><div><p>This allows you to batch the fetching of items given an array of <code>key</code>
inputs. Your callback will be invoked with an array of corresponding
key-value pairs found:</p><div class="prism language-javascript"><span class="token function">multiGet</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'k1'</span><span class="token punctuation">,</span> <span class="token string">'k2'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> cb<span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">&gt;</span> <span class="token function">cb</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">'k1'</span><span class="token punctuation">,</span> <span class="token string">'val1'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'k2'</span><span class="token punctuation">,</span> <span class="token string">'val2'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span></div><p>The method returns a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>keys<br><br><div><span>Array&lt;string&gt;</span></div></td><td class="description"><div><p>Array of key for the items to get.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(errors: ?Array&lt;Error&gt;, result: ?Array&lt;Array&lt;string&gt;&gt;) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with a key-value array of
the results, plus an array of any key-specific errors found.</p></div></td></tr></tbody></table></div><div><br>Example:<div class="prism language-javascript">AsyncStorage<span class="token punctuation">.</span><span class="token function">getAllKeys</span><span class="token punctuation">(</span><span class="token punctuation">(</span>err<span class="token punctuation">,</span> keys<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">multiGet</span><span class="token punctuation">(</span>keys<span class="token punctuation">,</span> <span class="token punctuation">(</span>err<span class="token punctuation">,</span> stores<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
stores<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span> i<span class="token punctuation">,</span> store<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // get at each store's key/value so you can work with it
</span> <span class="token keyword">let</span> key <span class="token operator">=</span> store<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> value <span class="token operator">=</span> store<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></div></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="multiset"></a><span class="methodType">static </span>multiSet<span class="methodType">(keyValuePairs: Array&lt;Array&lt;string&gt;&gt;, callback?: ?(errors: ?Array&lt;Error&gt;) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#multiset">#</a></h4><div><p>Use this as a batch operation for storing multiple key-value pairs. When
the operation completes you'll get a single callback with any errors:</p><div class="prism language-javascript"><span class="token function">multiSet</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">'k1'</span><span class="token punctuation">,</span> <span class="token string">'val1'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'k2'</span><span class="token punctuation">,</span> <span class="token string">'val2'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> cb<span class="token punctuation">)</span><span class="token punctuation">;</span></div><p>The method returns a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>keyValuePairs<br><br><div><span>Array&lt;Array&lt;string&gt;&gt;</span></div></td><td class="description"><div><p>Array of key-value array for the items to set.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(errors: ?Array&lt;Error&gt;) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with an array of any
key-specific errors found.</p></div></td></tr></tbody></table></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="multiremove"></a><span class="methodType">static </span>multiRemove<span class="methodType">(keys: Array&lt;string&gt;, callback?: ?(errors: ?Array&lt;Error&gt;) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#multiremove">#</a></h4><div><p>Call this to batch the deletion of all keys in the <code>keys</code> array. Returns
a <code>Promise</code> object.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>keys<br><br><div><span>Array&lt;string&gt;</span></div></td><td class="description"><div><p>Array of key for the items to delete.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(errors: ?Array&lt;Error&gt;) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called an array of any key-specific
errors found.</p></div></td></tr></tbody></table></div><div><br>Example:<div class="prism language-javascript">
<span class="token keyword">let</span> keys <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'k1'</span><span class="token punctuation">,</span> <span class="token string">'k2'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">multiRemove</span><span class="token punctuation">(</span>keys<span class="token punctuation">,</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // keys k1 &amp; k2 removed, if they existed
</span> <span class="token comment" spellcheck="true"> // do most stuff after removal (if you want)
</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></div></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="multimerge"></a><span class="methodType">static </span>multiMerge<span class="methodType">(keyValuePairs: Array&lt;Array&lt;string&gt;&gt;, callback?: ?(errors: ?Array&lt;Error&gt;) =&gt; void)</span> <a class="hash-link" href="docs/asyncstorage.html#multimerge">#</a></h4><div><p>Batch operation to merge in existing and new values for a given set of
keys. This assumes that the values are stringified JSON. Returns a
<code>Promise</code> object.</p><p><strong>NOTE</strong>: This is not supported by all native implementations.</p></div><div><strong>Parameters:</strong><table class="params"><thead><tr><th>Name and Type</th><th>Description</th></tr></thead><tbody><tr><td>keyValuePairs<br><br><div><span>Array&lt;Array&lt;string&gt;&gt;</span></div></td><td class="description"><div><p>Array of key-value array for the items to merge.</p></div></td></tr><tr><td>[callback]<br><br><div><span>?(errors: ?Array&lt;Error&gt;) =&gt; void</span></div></td><td class="description"><div><p>Function that will be called with an array of any
key-specific errors found.</p></div></td></tr></tbody></table></div><div><br>Example:<div class="prism language-javascript"><span class="token comment" spellcheck="true">
// first user, initial values
</span><span class="token keyword">let</span> UID234_object <span class="token operator">=</span> <span class="token punctuation">{</span>
name<span class="token punctuation">:</span> <span class="token string">'Chris'</span><span class="token punctuation">,</span>
age<span class="token punctuation">:</span> <span class="token number">30</span><span class="token punctuation">,</span>
traits<span class="token punctuation">:</span> <span class="token punctuation">{</span>hair<span class="token punctuation">:</span> <span class="token string">'brown'</span><span class="token punctuation">,</span> eyes<span class="token punctuation">:</span> <span class="token string">'brown'</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">
// first user, delta values
</span><span class="token keyword">let</span> UID234_delta <span class="token operator">=</span> <span class="token punctuation">{</span>
age<span class="token punctuation">:</span> <span class="token number">31</span><span class="token punctuation">,</span>
traits<span class="token punctuation">:</span> <span class="token punctuation">{</span>eyes<span class="token punctuation">:</span> <span class="token string">'blue'</span><span class="token punctuation">,</span> shoe_size<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">
// second user, initial values
</span><span class="token keyword">let</span> UID345_object <span class="token operator">=</span> <span class="token punctuation">{</span>
name<span class="token punctuation">:</span> <span class="token string">'Marge'</span><span class="token punctuation">,</span>
age<span class="token punctuation">:</span> <span class="token number">25</span><span class="token punctuation">,</span>
traits<span class="token punctuation">:</span> <span class="token punctuation">{</span>hair<span class="token punctuation">:</span> <span class="token string">'blonde'</span><span class="token punctuation">,</span> eyes<span class="token punctuation">:</span> <span class="token string">'blue'</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">
// second user, delta values
</span><span class="token keyword">let</span> UID345_delta <span class="token operator">=</span> <span class="token punctuation">{</span>
age<span class="token punctuation">:</span> <span class="token number">26</span><span class="token punctuation">,</span>
traits<span class="token punctuation">:</span> <span class="token punctuation">{</span>eyes<span class="token punctuation">:</span> <span class="token string">'green'</span><span class="token punctuation">,</span> shoe_size<span class="token punctuation">:</span> <span class="token number">6</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> multi_set_pairs <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">'UID234'</span><span class="token punctuation">,</span> JSON<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>UID234_object<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'UID345'</span><span class="token punctuation">,</span> JSON<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>UID345_object<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token keyword">let</span> multi_merge_pairs <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">'UID234'</span><span class="token punctuation">,</span> JSON<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>UID234_delta<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'UID345'</span><span class="token punctuation">,</span> JSON<span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>UID345_delta<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">multiSet</span><span class="token punctuation">(</span>multi_set_pairs<span class="token punctuation">,</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">multiMerge</span><span class="token punctuation">(</span>multi_merge_pairs<span class="token punctuation">,</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
AsyncStorage<span class="token punctuation">.</span><span class="token function">multiGet</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'UID234'</span><span class="token punctuation">,</span><span class="token string">'UID345'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>err<span class="token punctuation">,</span> stores<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
stores<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span> <span class="token punctuation">(</span>result<span class="token punctuation">,</span> i<span class="token punctuation">,</span> store<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> key <span class="token operator">=</span> store<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> val <span class="token operator">=</span> store<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment" spellcheck="true">
// Console log results:
</span><span class="token comment" spellcheck="true">// =&gt; UID234 {"name":"Chris","age":31,"traits":{"shoe_size":10,"hair":"brown","eyes":"blue"}}
</span><span class="token comment" spellcheck="true">// =&gt; UID345 {"name":"Marge","age":26,"traits":{"shoe_size":6,"hair":"blonde","eyes":"green"}}</span></div></div></div></div></span></div>
+7
View File
@@ -0,0 +1,7 @@
---
id: backandroid
title: BackAndroid
category: APIs
permalink: docs/backandroid.html
---
<div><div><p>Deprecated. Use BackHandler instead.</p></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/backandroid.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="exitapp"></a><span class="methodType">static </span>exitApp<span class="methodType">()</span> <a class="hash-link" href="docs/backandroid.html#exitapp">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="addeventlistener"></a><span class="methodType">static </span>addEventListener<span class="methodType">(eventName, handler)</span> <a class="hash-link" href="docs/backandroid.html#addeventlistener">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removeeventlistener"></a><span class="methodType">static </span>removeEventListener<span class="methodType">(eventName, handler)</span> <a class="hash-link" href="docs/backandroid.html#removeeventlistener">#</a></h4></div></div></span></div>
+20
View File
@@ -0,0 +1,20 @@
---
id: backhandler
title: BackHandler
category: APIs
permalink: docs/backhandler.html
---
<div><div><p>Detect hardware button presses for back navigation.</p><p>Android: Detect hardware back button presses, and programmatically invoke the default back button
functionality to exit the app if there are no listeners or if none of the listeners return true.</p><p>tvOS: Detect presses of the menu button on the TV remote. (Still to be implemented:
programmatically disable menu button handling
functionality to exit the app if there are no listeners or if none of the listeners return true.)</p><p>iOS: Not applicable.</p><p>The event subscriptions are called in reverse order (i.e. last registered subscription first),
and if one subscription returns true then subscriptions registered earlier will not be called.</p><p>Example:</p><div class="prism language-javascript">BackHandler<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'hardwareBackPress'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // this.onMainScreen and this.goBack are just examples, you need to use your own implementation here
</span><span class="token comment" spellcheck="true"> // Typically you would use the navigator here to go to the last state.
</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">onMainScreen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">goBack</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/backhandler.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="exitapp"></a><span class="methodType">static </span>exitApp<span class="methodType">()</span> <a class="hash-link" href="docs/backhandler.html#exitapp">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="addeventlistener"></a><span class="methodType">static </span>addEventListener<span class="methodType">(eventName, handler)</span> <a class="hash-link" href="docs/backhandler.html#addeventlistener">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removeeventlistener"></a><span class="methodType">static </span>removeEventListener<span class="methodType">(eventName, handler)</span> <a class="hash-link" href="docs/backhandler.html#removeeventlistener">#</a></h4></div></div></span></div>
+19
View File
@@ -0,0 +1,19 @@
---
id: button
title: Button
category: Components
permalink: docs/button.html
---
<div><div><p>A basic button component that should render nicely on any platform. Supports
a minimal level of customization.</p><span><center><img src="/react-native/img/buttonExample.png"></center>
</span><p>If this button doesn't look right for your app, you can build your own
button using <a href="docs/touchableopacity.html" target="_blank">TouchableOpacity</a>
or <a href="docs/touchablenativefeedback.html" target="_blank">TouchableNativeFeedback</a>.
For inspiration, look at the <a href="https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js" target="_blank">source code for this button component</a>.
Or, take a look at the <a href="https://js.coach/react-native?search=button" target="_blank">wide variety of button components built by the community</a>.</p><p>Example usage:</p><div class="prism language-javascript"><span class="token operator">&lt;</span>Button
onPress<span class="token operator">=</span><span class="token punctuation">{</span>onPressLearnMore<span class="token punctuation">}</span>
title<span class="token operator">=</span><span class="token string">"Learn More"</span>
color<span class="token operator">=</span><span class="token string">"#841584"</span>
accessibilityLabel<span class="token operator">=</span><span class="token string">"Learn more about this purple button"</span>
<span class="token operator">/</span><span class="token operator">&gt;</span></div></div><h3><a class="anchor" name="props"></a>Props <a class="hash-link" href="docs/button.html#props">#</a></h3><div class="props"><div class="prop"><h4 class="propTitle"><a class="anchor" name="accessibilitylabel"></a>accessibilityLabel?: <span class="propType"><span>?string</span></span> <a class="hash-link" href="docs/button.html#accessibilitylabel">#</a></h4><div><p>Text to display for blindness accessibility features</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="color"></a>color?: <span class="propType"><span>?string</span></span> <a class="hash-link" href="docs/button.html#color">#</a></h4><div><p>Color of the text (iOS), or background color of the button (Android)</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="disabled"></a>disabled?: <span class="propType"><span>?boolean</span></span> <a class="hash-link" href="docs/button.html#disabled">#</a></h4><div><p>If true, disable all interactions for this component.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="onpress"></a>onPress: <span class="propType">() =&gt; any</span> <a class="hash-link" href="docs/button.html#onpress">#</a></h4><div><p>Handler to be called when the user taps the button</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="testid"></a>testID?: <span class="propType"><span>?string</span></span> <a class="hash-link" href="docs/button.html#testid">#</a></h4><div><p>Used to locate this view in end-to-end tests.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="title"></a>title: <span class="propType">string</span> <a class="hash-link" href="docs/button.html#title">#</a></h4><div><p>Text to display inside the button</p></div></div></div></div>
+15
View File
@@ -0,0 +1,15 @@
---
id: cameraroll
title: CameraRoll
category: APIs
permalink: docs/cameraroll.html
---
<div><div><p><code>CameraRoll</code> provides access to the local camera roll / gallery.
Before using this you must link the <code>RCTCameraRoll</code> library.
You can refer to <a href="docs/linking-libraries-ios.html" target="_blank">Linking</a> for help.</p><h3><a class="anchor" name="permissions"></a>Permissions <a class="hash-link" href="docs/cameraroll.html#permissions">#</a></h3><p>The user's permission is required in order to access the Camera Roll on devices running iOS 10 or later.
Add the <code>NSPhotoLibraryUsageDescription</code> key in your <code>Info.plist</code> with a string that describes how your
app will use this data. This key will appear as <code>Privacy - Photo Library Usage Description</code> in Xcode.</p></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/cameraroll.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name=""></a>=<span class="methodType">(;, AssetTypeOptions, static, (, :)</span> <a class="hash-link" href="docs/cameraroll.html#">#</a></h4></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="savetocameraroll"></a><span class="methodType">static </span>saveToCameraRoll<span class="methodType">(tag, type?)</span> <a class="hash-link" href="docs/cameraroll.html#savetocameraroll">#</a></h4><div><p>Saves the photo or video to the camera roll / gallery.</p><p>On Android, the tag must be a local image or video URI, such as <code>"file:///sdcard/img.png"</code>.</p><p>On iOS, the tag can be any image URI (including local, remote asset-library and base64 data URIs)
or a local video file URI (remote or data URIs are not supported for saving video at this time).</p><p>If the tag has a file extension of .mov or .mp4, it will be inferred as a video. Otherwise
it will be treated as a photo. To override the automatic choice, you can pass an optional
<code>type</code> parameter that must be one of 'photo' or 'video'.</p><p>Returns a Promise which will resolve with the new URI.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getphotos"></a><span class="methodType">static </span>getPhotos<span class="methodType">(params)</span> <a class="hash-link" href="docs/cameraroll.html#getphotos">#</a></h4><div><p>Returns a Promise with photo identifier objects from the local camera
roll of the device matching shape defined by <code>getPhotosReturnChecker</code>.</p><p>Expects a params object of the following shape:</p><ul><li><code>first</code> : {number} : The number of photos wanted in reverse order of the photo application (i.e. most recent first for SavedPhotos).</li><li><code>after</code> : {string} : A cursor that matches <code>page_info { end_cursor }</code> returned from a previous call to <code>getPhotos</code>.</li><li><code>groupTypes</code> : {string} : Specifies which group types to filter the results to. Valid values are:<ul><li><code>Album</code></li><li><code>All</code></li><li><code>Event</code></li><li><code>Faces</code></li><li><code>Library</code></li><li><code>PhotoStream</code></li><li><code>SavedPhotos</code> // default</li></ul></li><li><code>groupName</code> : {string} : Specifies filter on group names, like 'Recent Photos' or custom album titles.</li><li><code>assetType</code> : {string} : Specifies filter on asset type. Valid values are:<ul><li><code>All</code></li><li><code>Videos</code></li><li><code>Photos</code> // default</li></ul></li><li><code>mimeTypes</code> : {string} : Filter by mimetype (e.g. image/jpeg).</li></ul><p>Returns a Promise which when resolved will be of the following shape:</p><ul><li><code>edges</code> : {Array&lt;node&gt;} An array of node objects<ul><li><code>node</code>: {object} An object with the following shape:<ul><li><code>type</code>: {string}</li><li><code>group_name</code>: {string}</li><li><code>image</code>: {object} : An object with the following shape:<ul><li><code>uri</code>: {string}</li><li><code>height</code>: {number}</li><li><code>width</code>: {number}</li><li><code>isStored</code>: {boolean}</li></ul></li><li><code>timestamp</code>: {number}</li><li><code>location</code>: {object} : An object with the following shape:<ul><li><code>latitude</code>: {number}</li><li><code>longitude</code>: {number}</li><li><code>altitude</code>: {number}</li><li><code>heading</code>: {number}</li><li><code>speed</code>: {number}</li></ul></li></ul></li></ul></li><li><code>page_info</code> : {object} : An object with the following shape:<ul><li><code>has_next_page</code>: {boolean}</li><li><code>start_cursor</code>: {boolean}</li><li><code>end_cursor</code>: {boolean}</li></ul></li></ul></div></div></div></span></div>
+11
View File
@@ -0,0 +1,11 @@
---
id: clipboard
title: Clipboard
category: APIs
permalink: docs/clipboard.html
---
<div><div><p><code>Clipboard</code> gives you an interface for setting and getting content from Clipboard on both iOS and Android</p></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/clipboard.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="getstring"></a><span class="methodType">static </span>getString<span class="methodType">()</span> <a class="hash-link" href="docs/clipboard.html#getstring">#</a></h4><div><p>Get content of string type, this method returns a <code>Promise</code>, so you can use following code to get clipboard content</p><div class="prism language-javascript"><span class="token keyword">async</span> <span class="token function">_getContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> content <span class="token operator">=</span> <span class="token keyword">await</span> Clipboard<span class="token punctuation">.</span><span class="token function">getString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></div></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="setstring"></a><span class="methodType">static </span>setString<span class="methodType">(content)</span> <a class="hash-link" href="docs/clipboard.html#setstring">#</a></h4><div><p>Set content of string type. You can use following code to set clipboard content</p><div class="prism language-javascript"><span class="token function">_setContent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
Clipboard<span class="token punctuation">.</span><span class="token function">setString</span><span class="token punctuation">(</span><span class="token string">'hello world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></div><p>@param the content to be stored in the clipboard.</p></div></div></div></span></div>
+22
View File
@@ -0,0 +1,22 @@
---
id: datepickerandroid
title: DatePickerAndroid
category: APIs
permalink: docs/datepickerandroid.html
---
<div><div><p>Opens the standard Android date picker dialog.</p><h3><a class="anchor" name="example"></a>Example <a class="hash-link" href="docs/datepickerandroid.html#example">#</a></h3><div class="prism language-javascript"><span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span>action<span class="token punctuation">,</span> year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> day<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">await</span> DatePickerAndroid<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // Use `new Date()` for current date.
</span> <span class="token comment" spellcheck="true"> // May 25 2020. Month 0 is January.
</span> date<span class="token punctuation">:</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2020</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">25</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>action <span class="token operator">!==</span> DatePickerAndroid<span class="token punctuation">.</span>dismissedAction<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment" spellcheck="true"> // Selected year, month (0-11), day
</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>code<span class="token punctuation">,</span> message<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token string">'Cannot open date picker'</span><span class="token punctuation">,</span> message<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/datepickerandroid.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="open"></a><span class="methodType">static </span>open<span class="methodType">(options)</span> <a class="hash-link" href="docs/datepickerandroid.html#open">#</a></h4><div><p>Opens the standard Android date picker dialog.</p><p>The available keys for the <code>options</code> object are:</p><ul><li><code>date</code> (<code>Date</code> object or timestamp in milliseconds) - date to show by default</li><li><code>minDate</code> (<code>Date</code> or timestamp in milliseconds) - minimum date that can be selected</li><li><code>maxDate</code> (<code>Date</code> object or timestamp in milliseconds) - maximum date that can be selected</li><li><code>mode</code> (<code>enum('calendar', 'spinner', 'default')</code>) - To set the date-picker mode to calendar/spinner/default<ul><li>'calendar': Show a date picker in calendar mode.</li><li>'spinner': Show a date picker in spinner mode.</li><li>'default': Show a default native date picker(spinner/calendar) based on android versions.</li></ul></li></ul><p>Returns a Promise which will be invoked an object containing <code>action</code>, <code>year</code>, <code>month</code> (0-11),
<code>day</code> if the user picked a date. If the user dismissed the dialog, the Promise will
still be resolved with action being <code>DatePickerAndroid.dismissedAction</code> and all the other keys
being undefined. <strong>Always</strong> check whether the <code>action</code> before reading the values.</p><p>Note the native date picker dialog has some UI glitches on Android 4 and lower
when using the <code>minDate</code> and <code>maxDate</code> options.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="datesetaction"></a><span class="methodType">static </span>dateSetAction<span class="methodType">()</span> <a class="hash-link" href="docs/datepickerandroid.html#datesetaction">#</a></h4><div><p>A date has been selected.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="dismissedaction"></a><span class="methodType">static </span>dismissedAction<span class="methodType">()</span> <a class="hash-link" href="docs/datepickerandroid.html#dismissedaction">#</a></h4><div><p>The dialog has been dismissed.</p></div></div></div></span></div>
+15
View File
@@ -0,0 +1,15 @@
---
id: datepickerios
title: DatePickerIOS
category: Components
permalink: docs/datepickerios.html
---
<div><div><p>Use <code>DatePickerIOS</code> to render a date/time picker (selector) on iOS. This is
a controlled component, so you must hook in to the <code>onDateChange</code> callback
and update the <code>date</code> prop in order for the component to update, otherwise
the user's change will be reverted immediately to reflect <code>props.date</code> as the
source of truth.</p></div><h3><a class="anchor" name="props"></a>Props <a class="hash-link" href="docs/datepickerios.html#props">#</a></h3><div class="props"><div class="prop"><h4 class="propTitle"><a class="anchor" name="viewproptypes"></a><a href="docs/viewproptypes.html#props">ViewPropTypes props...</a> <a class="hash-link" href="docs/datepickerios.html#viewproptypes">#</a></h4></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="date"></a>date: <span class="propType">Date</span> <a class="hash-link" href="docs/datepickerios.html#date">#</a></h4><div><p>The currently selected date.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="maximumdate"></a>maximumDate?: <span class="propType">Date</span> <a class="hash-link" href="docs/datepickerios.html#maximumdate">#</a></h4><div><p>Maximum date.</p><p>Restricts the range of possible date/time values.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="minimumdate"></a>minimumDate?: <span class="propType">Date</span> <a class="hash-link" href="docs/datepickerios.html#minimumdate">#</a></h4><div><p>Minimum date.</p><p>Restricts the range of possible date/time values.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="minuteinterval"></a>minuteInterval?: <span class="propType">enum(1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30)</span> <a class="hash-link" href="docs/datepickerios.html#minuteinterval">#</a></h4><div><p>The interval at which minutes can be selected.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="mode"></a>mode?: <span class="propType">enum('date', 'time', 'datetime')</span> <a class="hash-link" href="docs/datepickerios.html#mode">#</a></h4><div><p>The date picker mode.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="ondatechange"></a>onDateChange: <span class="propType">function</span> <a class="hash-link" href="docs/datepickerios.html#ondatechange">#</a></h4><div><p>Date change handler.</p><p>This is called when the user changes the date or time in the UI.
The first and only argument is a Date object representing the new
date and time.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="timezoneoffsetinminutes"></a>timeZoneOffsetInMinutes?: <span class="propType">number</span> <a class="hash-link" href="docs/datepickerios.html#timezoneoffsetinminutes">#</a></h4><div><p>Timezone offset in minutes.</p><p>By default, the date picker will use the device's timezone. With this
parameter, it is possible to force a certain timezone offset. For
instance, to show times in Pacific Standard Time, pass -7 * 60.</p></div></div></div></div>
+17
View File
@@ -0,0 +1,17 @@
---
id: dimensions
title: Dimensions
category: APIs
permalink: docs/dimensions.html
---
<div><div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/dimensions.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="set"></a><span class="methodType">static </span>set<span class="methodType">(dims)</span> <a class="hash-link" href="docs/dimensions.html#set">#</a></h4><div><p>This should only be called from native code by sending the
didUpdateDimensions event.</p><p>@param {object} dims Simple string-keyed object of dimensions to set</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="get"></a><span class="methodType">static </span>get<span class="methodType">(dim)</span> <a class="hash-link" href="docs/dimensions.html#get">#</a></h4><div><p>Initial dimensions are set before <code>runApplication</code> is called so they should
be available before any other require's are run, but may be updated later.</p><p>Note: Although dimensions are available immediately, they may change (e.g
due to device rotation) so any rendering logic or styles that depend on
these constants should try to call this function on every render, rather
than caching the value (for example, using inline styles rather than
setting a value in a <code>StyleSheet</code>).</p><p>Example: <code>var {height, width} = Dimensions.get('window');</code></p><p>@param {string} dim Name of dimension as defined when calling <code>set</code>.
@returns {Object?} Value for the dimension.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="addeventlistener"></a><span class="methodType">static </span>addEventListener<span class="methodType">(type, handler)</span> <a class="hash-link" href="docs/dimensions.html#addeventlistener">#</a></h4><div><p>Add an event handler. Supported events:</p><ul><li><code>change</code>: Fires when a property within the <code>Dimensions</code> object changes. The argument
to the event handler is an object with <code>window</code> and <code>screen</code> properties whose values
are the same as the return values of <code>Dimensions.get('window')</code> and
<code>Dimensions.get('screen')</code>, respectively.</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="removeeventlistener"></a><span class="methodType">static </span>removeEventListener<span class="methodType">(type, handler)</span> <a class="hash-link" href="docs/dimensions.html#removeeventlistener">#</a></h4><div><p>Remove an event handler.</p></div></div></div></span></div>
@@ -0,0 +1,46 @@
---
id: drawerlayoutandroid
title: DrawerLayoutAndroid
category: Components
permalink: docs/drawerlayoutandroid.html
---
<div><div><p>React component that wraps the platform <code>DrawerLayout</code> (Android only). The
Drawer (typically used for navigation) is rendered with <code>renderNavigationView</code>
and direct children are the main view (where your content goes). The navigation
view is initially not visible on the screen, but can be pulled in from the
side of the window specified by the <code>drawerPosition</code> prop and its width can
be set by the <code>drawerWidth</code> prop.</p><p>Example:</p><div class="prism language-javascript">render<span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> navigationView <span class="token operator">=</span> <span class="token punctuation">(</span>
<span class="token operator">&lt;</span>View style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>flex<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> backgroundColor<span class="token punctuation">:</span> <span class="token string">'#fff'</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>Text style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>margin<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> fontSize<span class="token punctuation">:</span> <span class="token number">15</span><span class="token punctuation">,</span> textAlign<span class="token punctuation">:</span> <span class="token string">'left'</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>I'm <span class="token keyword">in</span> the Drawer<span class="token operator">!</span><span class="token operator">&lt;</span><span class="token operator">/</span>Text<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>View<span class="token operator">&gt;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token operator">&lt;</span>DrawerLayoutAndroid
drawerWidth<span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">300</span><span class="token punctuation">}</span>
drawerPosition<span class="token operator">=</span><span class="token punctuation">{</span>DrawerLayoutAndroid<span class="token punctuation">.</span>positions<span class="token punctuation">.</span>Left<span class="token punctuation">}</span>
renderNavigationView<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> navigationView<span class="token punctuation">}</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>View style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>flex<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> alignItems<span class="token punctuation">:</span> <span class="token string">'center'</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>Text style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>margin<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> fontSize<span class="token punctuation">:</span> <span class="token number">15</span><span class="token punctuation">,</span> textAlign<span class="token punctuation">:</span> <span class="token string">'right'</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>Hello<span class="token operator">&lt;</span><span class="token operator">/</span>Text<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span>Text style<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>margin<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> fontSize<span class="token punctuation">:</span> <span class="token number">15</span><span class="token punctuation">,</span> textAlign<span class="token punctuation">:</span> <span class="token string">'right'</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>World<span class="token operator">!</span><span class="token operator">&lt;</span><span class="token operator">/</span>Text<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>View<span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>DrawerLayoutAndroid<span class="token operator">&gt;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span></div></div><h3><a class="anchor" name="props"></a>Props <a class="hash-link" href="docs/drawerlayoutandroid.html#props">#</a></h3><div class="props"><div class="prop"><h4 class="propTitle"><a class="anchor" name="viewproptypes"></a><a href="docs/viewproptypes.html#props">ViewPropTypes props...</a> <a class="hash-link" href="docs/drawerlayoutandroid.html#viewproptypes">#</a></h4></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="drawerbackgroundcolor"></a>drawerBackgroundColor?: <span class="propType"><a href="docs/colors.html">color</a></span> <a class="hash-link" href="docs/drawerlayoutandroid.html#drawerbackgroundcolor">#</a></h4><div><p>Specifies the background color of the drawer. The default value is white.
If you want to set the opacity of the drawer, use rgba. Example:</p><div class="prism language-javascript"><span class="token keyword">return</span> <span class="token punctuation">(</span>
<span class="token operator">&lt;</span>DrawerLayoutAndroid drawerBackgroundColor<span class="token operator">=</span><span class="token string">"rgba(0,0,0,0.5)"</span><span class="token operator">&gt;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>DrawerLayoutAndroid<span class="token operator">&gt;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></div></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="drawerlockmode"></a>drawerLockMode?: <span class="propType">enum('unlocked', 'locked-closed', 'locked-open')</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#drawerlockmode">#</a></h4><div><p>Specifies the lock mode of the drawer. The drawer can be locked in 3 states:
- unlocked (default), meaning that the drawer will respond (open/close) to touch gestures.
- locked-closed, meaning that the drawer will stay closed and not respond to gestures.
- locked-open, meaning that the drawer will stay opened and not respond to gestures.
The drawer may still be opened and closed programmatically (<code>openDrawer</code>/<code>closeDrawer</code>).</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="drawerposition"></a>drawerPosition?: <span class="propType">enum(DrawerConsts.DrawerPosition.Left, DrawerConsts.DrawerPosition.Right)</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#drawerposition">#</a></h4><div><p>Specifies the side of the screen from which the drawer will slide in.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="drawerwidth"></a>drawerWidth?: <span class="propType">number</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#drawerwidth">#</a></h4><div><p>Specifies the width of the drawer, more precisely the width of the view that be pulled in
from the edge of the window.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="keyboarddismissmode"></a>keyboardDismissMode?: <span class="propType">enum('none', 'on-drag')</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#keyboarddismissmode">#</a></h4><div><p>Determines whether the keyboard gets dismissed in response to a drag.
- 'none' (the default), drags do not dismiss the keyboard.
- 'on-drag', the keyboard is dismissed when a drag begins.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="ondrawerclose"></a>onDrawerClose?: <span class="propType">function</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#ondrawerclose">#</a></h4><div><p>Function called whenever the navigation view has been closed.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="ondraweropen"></a>onDrawerOpen?: <span class="propType">function</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#ondraweropen">#</a></h4><div><p>Function called whenever the navigation view has been opened.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="ondrawerslide"></a>onDrawerSlide?: <span class="propType">function</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#ondrawerslide">#</a></h4><div><p>Function called whenever there is an interaction with the navigation view.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="ondrawerstatechanged"></a>onDrawerStateChanged?: <span class="propType">function</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#ondrawerstatechanged">#</a></h4><div><p>Function called when the drawer state has changed. The drawer can be in 3 states:
- idle, meaning there is no interaction with the navigation view happening at the time
- dragging, meaning there is currently an interaction with the navigation view
- settling, meaning that there was an interaction with the navigation view, and the
navigation view is now finishing its closing or opening animation</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="rendernavigationview"></a>renderNavigationView: <span class="propType">function</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#rendernavigationview">#</a></h4><div><p>The navigation view that will be rendered to the side of the screen and can be pulled in.</p></div></div><div class="prop"><h4 class="propTitle"><a class="anchor" name="statusbarbackgroundcolor"></a>statusBarBackgroundColor?: <span class="propType"><a href="docs/colors.html">color</a></span> <a class="hash-link" href="docs/drawerlayoutandroid.html#statusbarbackgroundcolor">#</a></h4><div><p>Make the drawer take the entire screen and draw the background of the
status bar to allow it to open over the status bar. It will only have an
effect on API 21+.</p></div></div></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/drawerlayoutandroid.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="opendrawer"></a>openDrawer<span class="methodType">()</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#opendrawer">#</a></h4><div><p>Opens the drawer.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="closedrawer"></a>closeDrawer<span class="methodType">()</span> <a class="hash-link" href="docs/drawerlayoutandroid.html#closedrawer">#</a></h4><div><p>Closes the drawer.</p></div></div></div></span></div>
+26
View File
@@ -0,0 +1,26 @@
---
id: easing
title: Easing
category: APIs
permalink: docs/easing.html
---
<div><div><p>The <code>Easing</code> module implements common easing functions. This module is used
by <a href="docs/animate.html#timing" target="_blank">Animate.timing()</a> to convey physically
believable motion in animations.</p><p>You can find a visualization of some common easing functions at
<a href="http://easings.net/">http://easings.net/</a></p><h3><a class="anchor" name="predefined-animations"></a>Predefined animations <a class="hash-link" href="docs/easing.html#predefined-animations">#</a></h3><p>The <code>Easing</code> module provides several predefined animations through the
following methods:</p><ul><li><a href="docs/easing.html#back" target="_blank"><code>back</code></a> provides a simple animation where the
object goes slightly back before moving forward</li><li><a href="docs/easing.html#bounce" target="_blank"><code>bounce</code></a> provides a bouncing animation</li><li><a href="docs/easing.html#ease" target="_blank"><code>ease</code></a> provides a simple inertial animation</li><li><a href="docs/easing.html#elastic" target="_blank"><code>elastic</code></a> provides a simple spring interaction</li></ul><h3><a class="anchor" name="standard-functions"></a>Standard functions <a class="hash-link" href="docs/easing.html#standard-functions">#</a></h3><p>Three standard easing functions are provided:</p><ul><li><a href="docs/easing.html#linear" target="_blank"><code>linear</code></a></li><li><a href="docs/easing.html#quad" target="_blank"><code>quad</code></a></li><li><a href="docs/easing.html#cubic" target="_blank"><code>cubic</code></a></li></ul><p>The <a href="docs/easing.html#poly" target="_blank"><code>poly</code></a> function can be used to implement
quartic, quintic, and other higher power functions.</p><h3><a class="anchor" name="additional-functions"></a>Additional functions <a class="hash-link" href="docs/easing.html#additional-functions">#</a></h3><p>Additional mathematical functions are provided by the following methods:</p><ul><li><a href="docs/easing.html#bezier" target="_blank"><code>bezier</code></a> provides a cubic bezier curve</li><li><a href="docs/easing.html#circle" target="_blank"><code>circle</code></a> provides a circular function</li><li><a href="docs/easing.html#sin" target="_blank"><code>sin</code></a> provides a sinusoidal function</li><li><a href="docs/easing.html#exp" target="_blank"><code>exp</code></a> provides an exponential function</li></ul><p>The following helpers are used to modify other easing functions.</p><ul><li><a href="docs/easing.html#in" target="_blank"><code>in</code></a> runs an easing function forwards</li><li><a href="docs/easing.html#inout" target="_blank"><code>inOut</code></a> makes any easing function symmetrical</li><li><a href="docs/easing.html#out" target="_blank"><code>out</code></a> runs an easing function backwards</li></ul></div><span><h3><a class="anchor" name="methods"></a>Methods <a class="hash-link" href="docs/easing.html#methods">#</a></h3><div class="props"><div class="prop"><h4 class="methodTitle"><a class="anchor" name="step0"></a><span class="methodType">static </span>step0<span class="methodType">(n)</span> <a class="hash-link" href="docs/easing.html#step0">#</a></h4><div><p>A stepping function, returns 1 for any positive value of <code>n</code>.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="step1"></a><span class="methodType">static </span>step1<span class="methodType">(n)</span> <a class="hash-link" href="docs/easing.html#step1">#</a></h4><div><p>A stepping function, returns 1 if <code>n</code> is greater than or equal to 1.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="linear"></a><span class="methodType">static </span>linear<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#linear">#</a></h4><div><p>A linear function, <code>f(t) = t</code>. Position correlates to elapsed time one to
one.</p><p><a href="http://cubic-bezier.com/#0,0,1,1">http://cubic-bezier.com/#0,0,1,1</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="ease"></a><span class="methodType">static </span>ease<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#ease">#</a></h4><div><p>A simple inertial interaction, similar to an object slowly accelerating to
speed.</p><p><a href="http://cubic-bezier.com/#.42,0,1,1">http://cubic-bezier.com/#.42,0,1,1</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="quad"></a><span class="methodType">static </span>quad<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#quad">#</a></h4><div><p>A quadratic function, <code>f(t) = t * t</code>. Position equals the square of elapsed
time.</p><p><a href="http://easings.net/#easeInQuad">http://easings.net/#easeInQuad</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="cubic"></a><span class="methodType">static </span>cubic<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#cubic">#</a></h4><div><p>A cubic function, <code>f(t) = t * t * t</code>. Position equals the cube of elapsed
time.</p><p><a href="http://easings.net/#easeInCubic">http://easings.net/#easeInCubic</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="poly"></a><span class="methodType">static </span>poly<span class="methodType">(n)</span> <a class="hash-link" href="docs/easing.html#poly">#</a></h4><div><p>A power function. Position is equal to the Nth power of elapsed time.</p><p>n = 4: <a href="http://easings.net/#easeInQuart">http://easings.net/#easeInQuart</a>
n = 5: <a href="http://easings.net/#easeInQuint">http://easings.net/#easeInQuint</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="sin"></a><span class="methodType">static </span>sin<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#sin">#</a></h4><div><p>A sinusoidal function.</p><p><a href="http://easings.net/#easeInSine">http://easings.net/#easeInSine</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="circle"></a><span class="methodType">static </span>circle<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#circle">#</a></h4><div><p>A circular function.</p><p><a href="http://easings.net/#easeInCirc">http://easings.net/#easeInCirc</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="exp"></a><span class="methodType">static </span>exp<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#exp">#</a></h4><div><p>An exponential function.</p><p><a href="http://easings.net/#easeInExpo">http://easings.net/#easeInExpo</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="elastic"></a><span class="methodType">static </span>elastic<span class="methodType">(bounciness)</span> <a class="hash-link" href="docs/easing.html#elastic">#</a></h4><div><p>A simple elastic interaction, similar to a spring oscillating back and
forth.</p><p>Default bounciness is 1, which overshoots a little bit once. 0 bounciness
doesn't overshoot at all, and bounciness of N &gt; 1 will overshoot about N
times.</p><p><a href="http://easings.net/#easeInElastic">http://easings.net/#easeInElastic</a></p><p>Wolfram Plots:</p><ul><li><a href="http://tiny.cc/elastic_b_1">http://tiny.cc/elastic_b_1</a> (bounciness = 1, default)</li><li><a href="http://tiny.cc/elastic_b_3">http://tiny.cc/elastic_b_3</a> (bounciness = 3)</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="back"></a><span class="methodType">static </span>back<span class="methodType">(s)</span> <a class="hash-link" href="docs/easing.html#back">#</a></h4><div><p>Use with <code>Animated.parallel()</code> to create a simple effect where the object
animates back slightly as the animation starts.</p><p>Wolfram Plot:</p><ul><li><a href="http://tiny.cc/back_default">http://tiny.cc/back_default</a> (s = 1.70158, default)</li></ul></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="bounce"></a><span class="methodType">static </span>bounce<span class="methodType">(t)</span> <a class="hash-link" href="docs/easing.html#bounce">#</a></h4><div><p>Provides a simple bouncing effect.</p><p><a href="http://easings.net/#easeInBounce">http://easings.net/#easeInBounce</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="bezier"></a><span class="methodType">static </span>bezier<span class="methodType">(x1, y1, x2, y2)</span> <a class="hash-link" href="docs/easing.html#bezier">#</a></h4><div><p>Provides a cubic bezier curve, equivalent to CSS Transitions'
<code>transition-timing-function</code>.</p><p>A useful tool to visualize cubic bezier curves can be found at
<a href="http://cubic-bezier.com/">http://cubic-bezier.com/</a></p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="in"></a><span class="methodType">static </span>in<span class="methodType">(easing)</span> <a class="hash-link" href="docs/easing.html#in">#</a></h4><div><p>Runs an easing function forwards.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="out"></a><span class="methodType">static </span>out<span class="methodType">(easing)</span> <a class="hash-link" href="docs/easing.html#out">#</a></h4><div><p>Runs an easing function backwards.</p></div></div><div class="prop"><h4 class="methodTitle"><a class="anchor" name="inout"></a><span class="methodType">static </span>inOut<span class="methodType">(easing)</span> <a class="hash-link" href="docs/easing.html#inout">#</a></h4><div><p>Makes any easing function symmetrical. The easing function will run
forwards for half of the duration, then backwards for the rest of the
duration.</p></div></div></div></span></div>

Some files were not shown because too many files have changed in this diff Show More