mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-03-31 10:11:38 +08:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4081d17f25 | ||
|
|
4fa6f77d25 | ||
|
|
17d723559d | ||
|
|
8d80885f5d | ||
|
|
3ca4becc41 | ||
|
|
cc077e9019 | ||
|
|
1225b00cdb | ||
|
|
ed70617e91 | ||
|
|
134114de83 | ||
|
|
08ee7c83bb | ||
|
|
5fad78dcad | ||
|
|
e04343e48e | ||
|
|
5e3a946f8b | ||
|
|
4e3d8dbb02 | ||
|
|
fee909d26a | ||
|
|
9e58a7b5f1 | ||
|
|
20e1febe21 | ||
|
|
ef209ca281 | ||
|
|
a35949fa71 | ||
|
|
f5ac856c2d | ||
|
|
4b557b1e0b | ||
|
|
d4e9d9d256 | ||
|
|
0ff3e91592 | ||
|
|
092d5d12f7 | ||
|
|
507e0d41f5 | ||
|
|
9e863d5402 | ||
|
|
1364b1dfdf | ||
|
|
7f81e313ed | ||
|
|
a1892ec8b8 | ||
|
|
e6232d5980 | ||
|
|
e93a2eb478 | ||
|
|
44ecf1fe87 | ||
|
|
faec2b4a83 | ||
|
|
3677f0dd57 | ||
|
|
36d161a959 | ||
|
|
1ca18ab056 | ||
|
|
b43717e797 | ||
|
|
801d5f8c68 | ||
|
|
30f2ec9bf5 | ||
|
|
6f3e29f630 | ||
|
|
2607cb25ab | ||
|
|
8f56454ed7 | ||
|
|
d03e06632e | ||
|
|
66732394cb | ||
|
|
077d2f3e63 | ||
|
|
f6ad9c3afb | ||
|
|
f91ecaa81d | ||
|
|
ad3dee0204 | ||
|
|
1a0a40d9be | ||
|
|
0bf6e893c6 |
18
.github/CONTRIBUTING.md
vendored
18
.github/CONTRIBUTING.md
vendored
@@ -66,7 +66,7 @@ yarn docs:build
|
||||
To run the performance benchmarks in a browser (opening `./benchmarks/index.html`):
|
||||
|
||||
```
|
||||
yarn benchmarks
|
||||
yarn benchmark
|
||||
```
|
||||
|
||||
## Compile and build
|
||||
@@ -104,13 +104,17 @@ Please open an issue with a proposal for a new feature or refactoring before
|
||||
starting on the work. We don't want you to waste your efforts on a pull request
|
||||
that we won't want to accept.
|
||||
|
||||
## Submitting Changes
|
||||
## Pull requests
|
||||
|
||||
* Open a new issue in the [Issue tracker](https://github.com/necolas/react-native-web/issues).
|
||||
* Fork the repo.
|
||||
* Create a new feature branch based off the `master` branch.
|
||||
* Make sure all tests pass and there are no linting errors.
|
||||
* Submit a pull request, referencing any issues it addresses.
|
||||
**Before submitting a pull request,** please make sure the following is done:
|
||||
|
||||
1. Fork the repository and create your branch from `master`.
|
||||
2. If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. Ensure the tests pass (`yarn test`).
|
||||
5. Lint and format your code (`yarn fmt && yarn lint`).
|
||||
|
||||
You can now submit a pull request, referencing any issues it addresses.
|
||||
|
||||
Please try to keep your pull request focused in scope and avoid including
|
||||
unrelated commits.
|
||||
|
||||
34
.github/ISSUE_TEMPLATE.md
vendored
34
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,30 +1,20 @@
|
||||
<!--
|
||||
React Native for Web is an implementation of React Native. If you have feature
|
||||
requests, you should post them to https://productpains.com/product/react-native/.
|
||||
|
||||
GitHub issues should only be used for bugs or Web-specific features you believe
|
||||
React Native requires.
|
||||
|
||||
Make sure to add ALL the information needed to understand the bug so that
|
||||
someone can help. If the info is missing we'll add the 'needs more information'
|
||||
label and close the issue until there is enough information.
|
||||
-->
|
||||
**Do you want to request a *feature* or report a *bug*?**
|
||||
|
||||
**What is the current behavior?**
|
||||
|
||||
Link to minimal test case: (template: [codepen](https://codepen.io/necolas/pen/PZzwBR?editors=0010))
|
||||
|
||||
**What is the expected behaviour?**
|
||||
|
||||
**Steps to reproduce**
|
||||
**If the current behavior is a bug, please provide the steps to reproduce and
|
||||
if a minimal demo of the problem via Glitch or similar (template:
|
||||
https://glitch.com/edit/#!/react-native-web-playground).**
|
||||
|
||||
1.
|
||||
2.
|
||||
|
||||
**Environment (include versions)**
|
||||
**What is the expected behavior?**
|
||||
|
||||
OS:
|
||||
Device:
|
||||
Browser:
|
||||
React Native for Web (version):
|
||||
React (version):
|
||||
**Environment (include versions). Did this work in previous versions?**
|
||||
|
||||
* OS:
|
||||
* Device:
|
||||
* Browser:
|
||||
* React Native for Web (version):
|
||||
* React (version):
|
||||
|
||||
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,18 +1 @@
|
||||
<!--
|
||||
Thanks for submitting a pull request! Make sure the PR does only one thing.
|
||||
Please provide enough information so that others can review your pull
|
||||
request. Make sure you have read the Contributing Guidelines -
|
||||
https://github.com/necolas/react-native-web/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
**This patch solves the following problem**
|
||||
|
||||
**Test plan**
|
||||
|
||||
**This pull request**
|
||||
|
||||
- [ ] includes documentation
|
||||
- [ ] includes tests
|
||||
- [ ] includes benchmark reports
|
||||
- [ ] includes an interactive example
|
||||
- [ ] includes screenshots/videos
|
||||
**Before submitting a pull request,** please make sure you have followed the steps the CONTRIBUTING guide.
|
||||
|
||||
28
README.md
28
README.md
@@ -19,19 +19,20 @@ Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
|
||||
touch handling to the Web.
|
||||
|
||||
Browse the [UI Explorer](https://necolas.github.io/react-native-web/storybook/)
|
||||
to see React Native examples running on Web. Or try it out online with [React
|
||||
Native for Web: Playground](https://www.webpackbin.com/bins/-KgucwxRbn7HRU-V-3Bc).
|
||||
to see React Native examples running on Web. Or remix the [React Native for
|
||||
Web: Playground](https://glitch.com/edit/#!/react-native-web-playground) on
|
||||
Glitch.
|
||||
|
||||
## Quick start
|
||||
|
||||
To install in your app:
|
||||
|
||||
```
|
||||
npm install --save react@15.6 react-dom@15.6 react-native-web
|
||||
```
|
||||
|
||||
NOTE: React Native for Web supports React/ReactDOM 15.4, 15.5, or 15.6.
|
||||
|
||||
Install in your existing app using `yarn` or `npm`:
|
||||
|
||||
```
|
||||
yarn add react@15.6 react-dom@15.6 react-native-web
|
||||
```
|
||||
|
||||
Then read the [Getting Started](docs/guides/getting-started.md) guide.
|
||||
|
||||
## Documentation
|
||||
@@ -49,6 +50,12 @@ Guides:
|
||||
* [Advanced use](docs/guides/advanced.md)
|
||||
* [Known issues](docs/guides/known-issues.md)
|
||||
|
||||
## Starter kits
|
||||
|
||||
* [create-react-app](https://github.com/facebookincubator/create-react-app) ([on Glitch](https://glitch.com/edit/#!/react-native-web-playground))
|
||||
* [react-native-web-starter](https://github.com/grabcode/react-native-web-starter)
|
||||
* [react-native-web-webpack](https://github.com/ndbroadbent/react-native-web-webpack)
|
||||
|
||||
## Example code
|
||||
|
||||
```js
|
||||
@@ -91,12 +98,9 @@ AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-ro
|
||||
## Related projects
|
||||
|
||||
* [react-primitives](https://github.com/lelandrichardson/react-primitives/)
|
||||
* [react-native-web-player](https://github.com/dabbott/react-native-web-player)
|
||||
* [react-native-web-starter](https://github.com/grabcode/react-native-web-starter)
|
||||
* [react-native-web-webpack](https://github.com/ndbroadbent/react-native-web-webpack)
|
||||
* [react-sketchapp](https://github.com/airbnb/react-sketchapp)
|
||||
* [react-web](https://github.com/taobaofed/react-web)
|
||||
* [reactxp](https://github.com/microsoft/reactxp)
|
||||
* [react-native-web-player](https://github.com/dabbott/react-native-web-player)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ npm run build:performance
|
||||
open ./performance/index.html
|
||||
```
|
||||
|
||||
Append `?fastest` to the URL to include the fastest "other libraries", and
|
||||
`?all` to include all the "other libraries".
|
||||
|
||||
## Notes
|
||||
|
||||
The components used in the render benchmarks are simple enough to be
|
||||
@@ -24,24 +27,25 @@ Typical render timings*: mean ± two standard deviations.
|
||||
|
||||
| Implementation | Deep tree (ms) | Wide tree (ms) | Tweets (ms) |
|
||||
| :--- | ---: | ---: | ---: |
|
||||
| `css-modules` | `94.96` `±31.01` | `200.43` `±38.90` | |
|
||||
| `react-native-web/stylesheet@0.0.107` | `98.58` `±10.83` | `218.59` `±36.52` | |
|
||||
| `react-native-web@0.0.107` | `117.45` `±18.76` | `288.27` `±33.50` | `15.10` `±5.45ms` |
|
||||
| `css-modules` | `84.19` `±14.69` | `183.37` `±22.98` | |
|
||||
| `react-native-web/stylesheet@0.0.113` | `88.83` `±14.31` | `185.54` `±24.62` | |
|
||||
| `react-native-web@0.0.113` | `110.45` `±19.63` | `251.53` `±32.52` | `15.52` `±7.93ms` |
|
||||
|
||||
Other libraries
|
||||
|
||||
| Implementation | Deep tree (ms) | Wide tree (ms) |
|
||||
| :--- | ---: | ---: |
|
||||
| `styletron@2.5.1` | `90.38` `±15.15` | `197.40` `±29.02` |
|
||||
| `aphrodite@1.2.0` | `88.65` `±19.62` | `187.35` `±24.60` |
|
||||
| `glamor@3.0.0-1` | `145.64` `±21.93` | `283.60` `±23.26` |
|
||||
| `react-jss@5.4.1` | `143.17` `±19.14` | `361.80` `±33.39` |
|
||||
| `reactxp@0.34.3` | `227.18` `±28.75` | `496.08` `±59.96` |
|
||||
| `styled-components@2.1.0` | `262.85` `±46.12` | `578.43` `±35.86` |
|
||||
| `styled-components/primitives@2.1.0` | `261.43` `±44.14` | `569.65` `±22.19` |
|
||||
| `aphrodite@1.2.3` | `84.68` `±18.80` | `180.62` `±41.98` |
|
||||
| `styletron@2.5.1` | `83.93` `±13.10` | `185.96` `±45.65` |
|
||||
| `react-jss@7.0.1` | `174.75` `±30.87` | `411.77` `±83.83` |
|
||||
| `glamor@3.0.0-3` | `255.21` `±45.68` | `545.74` `±107.79` |
|
||||
| `reactxp@0.34.3` | `237.46` `±36.72` | `514.48` `±84.87` |
|
||||
| `styled-components@2.1.1` | `266.91` `±50.04` | `598.29` `±95.13` |
|
||||
| `styled-components/primitives@2.1.1` | `266.62` `±50.39` | `567.13` `±68.12` |
|
||||
| `radium@0.19.1` | `518.48` `±69.74` | `1058.85` `±120.85` |
|
||||
|
||||
These results indicate that render performance is not a significant
|
||||
differentiating factor between `aphrodite`, `styletron`, and
|
||||
`react-native-web/stylesheet`.
|
||||
These results indicate that styled render performance is not a significant
|
||||
differentiating factor between `aphrodite`, `css-modules`, `react-native-web`,
|
||||
and `styletron`.
|
||||
|
||||
*MacBook Pro (13-inch, Early 2015); 3.1 GHz Intel Core i7; 16 GB 1867 MHz DDR3. Google Chrome 58 (2x CPU slowdown).
|
||||
|
||||
@@ -5,7 +5,9 @@ const node = document.querySelector('.root');
|
||||
|
||||
const createRenderBenchmark = ({ description, getElement, name, runs }) => () => {
|
||||
const setup = () => {};
|
||||
const teardown = () => ReactDOM.unmountComponentAtNode(node);
|
||||
const teardown = () => {
|
||||
ReactDOM.unmountComponentAtNode(node);
|
||||
};
|
||||
|
||||
return benchmark({
|
||||
name,
|
||||
@@ -13,7 +15,9 @@ const createRenderBenchmark = ({ description, getElement, name, runs }) => () =>
|
||||
runs,
|
||||
setup,
|
||||
teardown,
|
||||
task: () => ReactDOM.render(getElement(), node)
|
||||
task: () => {
|
||||
ReactDOM.render(getElement(), node);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import aphrodite from './src/aphrodite';
|
||||
import cssModules from './src/css-modules';
|
||||
import glamor from './src/glamor';
|
||||
import jss from './src/jss';
|
||||
import radium from './src/radium';
|
||||
import reactNative from './src/react-native';
|
||||
import reactNativeStyleSheet from './src/react-native-stylesheet';
|
||||
import styledComponents from './src/styled-components';
|
||||
@@ -14,6 +15,7 @@ import renderTweet from './tests/renderTweet';
|
||||
import renderWideTree from './tests/renderWideTree';
|
||||
|
||||
const testAll = window.location.search === '?all';
|
||||
const testFastest = window.location.search === '?fastest';
|
||||
|
||||
const coreTests = [
|
||||
() => renderTweet('react-native-web', reactNative),
|
||||
@@ -26,18 +28,23 @@ const coreTests = [
|
||||
() => renderWideTree('react-native-web', reactNative)
|
||||
];
|
||||
|
||||
/**
|
||||
* Optionally run tests using other libraries
|
||||
*/
|
||||
const extraTests = [
|
||||
const fastestTests = [
|
||||
() => renderDeepTree('styletron', styletron),
|
||||
() => renderWideTree('styletron', styletron),
|
||||
() => renderDeepTree('aphrodite', aphrodite),
|
||||
() => renderWideTree('aphrodite', aphrodite),
|
||||
() => renderWideTree('aphrodite', aphrodite)
|
||||
];
|
||||
|
||||
/**
|
||||
* Optionally run tests using other libraries
|
||||
*/
|
||||
const restTests = [
|
||||
() => renderDeepTree('glamor', glamor),
|
||||
() => renderWideTree('glamor', glamor),
|
||||
() => renderDeepTree('react-jss', jss),
|
||||
() => renderWideTree('react-jss', jss),
|
||||
() => renderDeepTree('radium', radium),
|
||||
() => renderWideTree('radium', radium),
|
||||
() => renderDeepTree('reactxp', xp),
|
||||
() => renderWideTree('reactxp', xp),
|
||||
() => renderDeepTree('styled-components', styledComponents),
|
||||
@@ -46,7 +53,14 @@ const extraTests = [
|
||||
() => renderWideTree('styled-components/primitives', styledComponentsPrimitives)
|
||||
];
|
||||
|
||||
const tests = testAll ? coreTests.concat(extraTests) : coreTests;
|
||||
const tests = [...coreTests];
|
||||
if (testFastest) {
|
||||
tests.push(...fastestTests);
|
||||
}
|
||||
if (testAll) {
|
||||
tests.push(...fastestTests);
|
||||
tests.push(...restTests);
|
||||
}
|
||||
|
||||
// run benchmarks
|
||||
tests.reduce((promise, test) => promise.then(test()), Promise.resolve());
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "performance",
|
||||
"name": "benchmarks",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"aphrodite": "^1.2.1",
|
||||
"aphrodite": "^1.2.3",
|
||||
"classnames": "^2.2.5",
|
||||
"glamor": "2.20.25",
|
||||
"glamor": "^2.20.37",
|
||||
"marky": "^1.2.0",
|
||||
"react-jss": "^6.1.1",
|
||||
"react-primitives": "^0.4.2",
|
||||
"reactxp": "^0.34.3",
|
||||
"styled-components": "^2.1.0",
|
||||
"radium": "^0.19.1",
|
||||
"react-jss": "^7.0.1",
|
||||
"react-primitives": "^0.4.3",
|
||||
"reactxp": "0.34.3",
|
||||
"styled-components": "^2.1.1",
|
||||
"styletron-client": "^2.5.7",
|
||||
"styletron-utils": "^2.5.4"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import theme from '../theme';
|
||||
import React, { PropTypes, PureComponent } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { StyleSheet, Text } from 'react-native';
|
||||
|
||||
class AppText extends PureComponent {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { PureComponent, PropTypes } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
|
||||
class AspectRatio extends PureComponent {
|
||||
@@ -21,7 +22,9 @@ class AspectRatio extends PureComponent {
|
||||
return (
|
||||
<View style={[styles.root, style]}>
|
||||
<View style={[styles.shim, { paddingBottom: `${percentage}%` }]} />
|
||||
<View style={StyleSheet.absoluteFill}>{children}</View>
|
||||
<View style={StyleSheet.absoluteFill}>
|
||||
{children}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,4 +45,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -14,4 +14,4 @@ const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other
|
||||
})}
|
||||
/>;
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -44,4 +44,4 @@ const styles = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -46,4 +46,4 @@ const styles = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = injectSheet(styles)(Box);
|
||||
export default injectSheet(styles)(Box);
|
||||
|
||||
48
benchmarks/src/components/Box/radium.js
Normal file
48
benchmarks/src/components/Box/radium.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import Radium from 'radium';
|
||||
import React from 'react';
|
||||
import View from '../View/radium';
|
||||
|
||||
const Box = ({ color, fixed = false, layout = 'column', outer = false, ...other }) =>
|
||||
<View
|
||||
{...other}
|
||||
style={[
|
||||
styles[`color${color}`],
|
||||
fixed && styles.fixed,
|
||||
layout === 'row' && styles.row,
|
||||
outer && styles.outer
|
||||
]}
|
||||
/>;
|
||||
|
||||
const styles = {
|
||||
outer: {
|
||||
padding: 4
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row'
|
||||
},
|
||||
color0: {
|
||||
backgroundColor: '#222'
|
||||
},
|
||||
color1: {
|
||||
backgroundColor: '#666'
|
||||
},
|
||||
color2: {
|
||||
backgroundColor: '#999'
|
||||
},
|
||||
color3: {
|
||||
backgroundColor: 'blue'
|
||||
},
|
||||
color4: {
|
||||
backgroundColor: 'orange'
|
||||
},
|
||||
color5: {
|
||||
backgroundColor: 'red'
|
||||
},
|
||||
fixed: {
|
||||
width: 20,
|
||||
height: 20
|
||||
}
|
||||
};
|
||||
|
||||
export default Radium(Box);
|
||||
@@ -45,4 +45,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -44,4 +44,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -44,4 +44,4 @@ const styles = {
|
||||
})
|
||||
};
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -27,4 +27,4 @@ const Box = styled.View`
|
||||
background-color: ${props => getColor(props.color)};
|
||||
`;
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -28,4 +28,4 @@ const Box = styled(View)`
|
||||
background-color: ${props => getColor(props.color)};
|
||||
`;
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -45,4 +45,4 @@ const styles = {
|
||||
})
|
||||
};
|
||||
|
||||
module.exports = Box;
|
||||
export default Box;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import theme from '../theme';
|
||||
|
||||
class GridView extends Component {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
class DeepTree extends Component {
|
||||
static propTypes = {
|
||||
@@ -30,10 +31,14 @@ class DeepTree extends Component {
|
||||
</Box>
|
||||
);
|
||||
for (let i = 0; i < wrap; i++) {
|
||||
result = <Box components={components}>{result}</Box>;
|
||||
result = (
|
||||
<Box components={components}>
|
||||
{result}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DeepTree;
|
||||
export default DeepTree;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import AspectRatio from '../AspectRatio';
|
||||
import GridView from '../GridView';
|
||||
import PropTypes from 'prop-types';
|
||||
import TweetActionsBar from '../TweetActionsBar';
|
||||
import TweetText from '../TweetText';
|
||||
import UserAvatar from '../UserAvatar';
|
||||
import UserNames from '../UserNames';
|
||||
import { Image, StyleSheet, Text, View } from 'react-native';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import theme from '../theme';
|
||||
|
||||
export class Tweet extends Component {
|
||||
@@ -61,7 +62,6 @@ export class Tweet extends Component {
|
||||
</AspectRatio>
|
||||
</View>
|
||||
: null}
|
||||
|
||||
</View>
|
||||
|
||||
<TweetActionsBar
|
||||
|
||||
@@ -2,9 +2,10 @@ import IconReply from '../Icons/Reply';
|
||||
import IconHeart from '../Icons/Heart';
|
||||
import IconRetweet from '../Icons/Retweet';
|
||||
import IconDirectMessage from '../Icons/DirectMessage';
|
||||
import { Text, View, StyleSheet } from 'react-native';
|
||||
import React, { PropTypes } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import theme from '../theme';
|
||||
import { Text, View, StyleSheet } from 'react-native';
|
||||
|
||||
const getIcon = (icon, highlighted) => {
|
||||
switch (icon) {
|
||||
@@ -45,7 +46,11 @@ export default class TweetAction extends React.Component {
|
||||
]}
|
||||
>
|
||||
{getIcon(displayMode, highlighted)}
|
||||
{count > 0 ? <Text style={styles.count}>{count}</Text> : null}
|
||||
{count > 0
|
||||
? <Text style={styles.count}>
|
||||
{count}
|
||||
</Text>
|
||||
: null}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import TweetAction from '../TweetAction';
|
||||
import { View, StyleSheet } from 'react-native';
|
||||
import React, { PropTypes, PureComponent } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
const actionNames = ['reply', 'retweet', 'like', 'directMessage'];
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import AppText from '../AppText';
|
||||
import React from 'react';
|
||||
import TweetTextPart from '../TweetTextPart';
|
||||
import React, { PropTypes } from 'react';
|
||||
import { array, number, string } from 'prop-types';
|
||||
|
||||
class TweetText extends React.Component {
|
||||
static displayName = 'TweetText';
|
||||
|
||||
static propTypes = {
|
||||
displayMode: TweetTextPart.propTypes.displayMode,
|
||||
lang: PropTypes.string,
|
||||
numberOfLines: PropTypes.number,
|
||||
textParts: PropTypes.array.isRequired
|
||||
lang: string,
|
||||
numberOfLines: number,
|
||||
textParts: array.isRequired
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { Image, StyleSheet, Text } from 'react-native';
|
||||
import React, { PropTypes } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import theme from '../theme';
|
||||
|
||||
const createTextEntity = ({ part }) => <Text>{`${part.prefix}${part.text}`}</Text>;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import AspectRatio from '../AspectRatio';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Image, StyleSheet } from 'react-native';
|
||||
import React, { PropTypes, PureComponent } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import theme from '../theme';
|
||||
|
||||
class UserAvatar extends PureComponent {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import AppText from '../AppText';
|
||||
import PropTypes from 'prop-types';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import React, { PropTypes, PureComponent } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
class UserNames extends PureComponent {
|
||||
static displayName = 'UserNames';
|
||||
@@ -28,7 +29,9 @@ class UserNames extends PureComponent {
|
||||
onPress={onPress}
|
||||
style={[styles.root, style]}
|
||||
>
|
||||
<AppText color="normal" weight="bold">{fullName}</AppText>
|
||||
<AppText color="normal" weight="bold">
|
||||
{fullName}
|
||||
</AppText>
|
||||
{layout === 'stack' ? ' \u000A' : ' '}
|
||||
<AppText color="deepGray" style={styles.screenName}>{`@${screenName}`}</AppText>
|
||||
</AppText>
|
||||
|
||||
@@ -28,4 +28,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = View;
|
||||
export default View;
|
||||
|
||||
@@ -10,4 +10,4 @@ class View extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = View;
|
||||
export default View;
|
||||
|
||||
@@ -26,4 +26,4 @@ const viewStyle = {
|
||||
minWidth: 0
|
||||
};
|
||||
|
||||
module.exports = View;
|
||||
export default View;
|
||||
|
||||
@@ -29,4 +29,4 @@ const styles = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = injectSheet(styles)(View);
|
||||
export default injectSheet(styles)(View);
|
||||
|
||||
31
benchmarks/src/components/View/radium.js
Normal file
31
benchmarks/src/components/View/radium.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import Radium from 'radium';
|
||||
import React from 'react';
|
||||
|
||||
class View extends React.Component {
|
||||
render() {
|
||||
const { style, ...other } = this.props;
|
||||
return <div {...other} style={[styles.root, style]} />;
|
||||
}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
root: {
|
||||
alignItems: 'stretch',
|
||||
borderWidth: 0,
|
||||
borderStyle: 'solid',
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
flexBasis: 'auto',
|
||||
flexDirection: 'column',
|
||||
flexShrink: 0,
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
position: 'relative',
|
||||
// fix flexbox bugs
|
||||
minHeight: 0,
|
||||
minWidth: 0
|
||||
}
|
||||
};
|
||||
|
||||
export default Radium(View);
|
||||
@@ -32,4 +32,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = View;
|
||||
export default View;
|
||||
|
||||
@@ -16,4 +16,4 @@ const View = styled.div`
|
||||
min-width: 0;
|
||||
`;
|
||||
|
||||
module.exports = View;
|
||||
export default View;
|
||||
|
||||
@@ -23,11 +23,11 @@ const fontSize = {
|
||||
large: '1.25rem'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
const theme = {
|
||||
colors,
|
||||
fontFamily:
|
||||
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif, ' +
|
||||
'"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', // emoji fonts
|
||||
'"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', // emoji fonts
|
||||
fontSize,
|
||||
lineHeight: 1.3125,
|
||||
spaceX: 0.6,
|
||||
@@ -36,3 +36,5 @@ module.exports = {
|
||||
return `${num}${unit}`;
|
||||
}
|
||||
};
|
||||
|
||||
export default theme;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import Box from './components/Box/css-modules';
|
||||
import View from './components/View/css-modules';
|
||||
|
||||
export default {
|
||||
const api = {
|
||||
Box,
|
||||
View
|
||||
};
|
||||
|
||||
export default api;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import Box from './components/Box/jss';
|
||||
import View from './components/View/jss';
|
||||
|
||||
export default {
|
||||
const api = {
|
||||
Box,
|
||||
View
|
||||
};
|
||||
|
||||
export default api;
|
||||
|
||||
9
benchmarks/src/radium.js
Normal file
9
benchmarks/src/radium.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import Box from './components/Box/radium';
|
||||
import View from './components/View/radium';
|
||||
|
||||
const api = {
|
||||
Box,
|
||||
View
|
||||
};
|
||||
|
||||
export default api;
|
||||
4
benchmarks/src/react-native-stylesheet.js
vendored
4
benchmarks/src/react-native-stylesheet.js
vendored
@@ -1,7 +1,9 @@
|
||||
import Box from './components/Box/react-native-stylesheet';
|
||||
import View from './components/View/react-native-stylesheet';
|
||||
|
||||
export default {
|
||||
const api = {
|
||||
Box,
|
||||
View
|
||||
};
|
||||
|
||||
export default api;
|
||||
|
||||
@@ -96,7 +96,7 @@ const tweet2 = {
|
||||
}
|
||||
};
|
||||
|
||||
const renderTweet = (label, components) =>
|
||||
const renderTweet = label =>
|
||||
createRenderBenchmark({
|
||||
name: `Tweet [${label}]`,
|
||||
runs: 10,
|
||||
|
||||
@@ -37,9 +37,9 @@ ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
aphrodite@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/aphrodite/-/aphrodite-1.2.1.tgz#a7b5066b198730be7b7a88f78dbefd77d4df5683"
|
||||
aphrodite@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/aphrodite/-/aphrodite-1.2.3.tgz#4b161e9eef319b1f90a889501f985d7b5e70b285"
|
||||
dependencies:
|
||||
asap "^2.0.3"
|
||||
inline-style-prefixer "^3.0.1"
|
||||
@@ -55,7 +55,15 @@ array-find-index@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
|
||||
|
||||
asap@^2.0.3, asap@^2.0.5, asap@~2.0.3:
|
||||
array-find@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8"
|
||||
|
||||
asap@^2.0.3, asap@^2.0.5:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f"
|
||||
|
||||
@@ -84,9 +92,9 @@ babel-code-frame@^6.11.0:
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
babel-runtime@^6.18.0, babel-runtime@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
|
||||
babel-runtime@^6.23.0:
|
||||
version "6.25.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.25.0.tgz#33b98eaa5d482bb01a8d1aa6b437ad2b01aec41c"
|
||||
dependencies:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.10.0"
|
||||
@@ -95,6 +103,10 @@ balanced-match@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1"
|
||||
@@ -103,10 +115,25 @@ big.js@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
|
||||
|
||||
bowser@^1.0.0, bowser@^1.6.0:
|
||||
bowser@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.6.0.tgz#37fc387b616cb6aef370dab4d6bd402b74c5c54d"
|
||||
|
||||
bowser@^1.6.0:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.7.1.tgz#a4de8f18a1a0dc9531eb2a92a1521fb6a9ba96a5"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brcast@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brcast/-/brcast-2.0.1.tgz#4311508f0634a6f5a2465b6cf2db27f06902aaca"
|
||||
|
||||
browserslist@^1.0.1, browserslist@^1.5.2, browserslist@^1.7.5:
|
||||
version "1.7.5"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.5.tgz#eca4713897b51e444283241facf3985de49a9e2b"
|
||||
@@ -204,6 +231,10 @@ colors@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
@@ -230,7 +261,7 @@ css-color-names@0.0.4:
|
||||
|
||||
css-in-js-utils@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://artifactory.twitter.biz:443/api/npm/js-virtual/css-in-js-utils/-/css-in-js-utils-1.0.3.tgz#9ac7e02f763cf85d94017666565ed68a5b5f3215"
|
||||
resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-1.0.3.tgz#9ac7e02f763cf85d94017666565ed68a5b5f3215"
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.2"
|
||||
|
||||
@@ -379,6 +410,10 @@ esutils@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
|
||||
exenv@^1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||
|
||||
fast-deep-equal@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-0.1.0.tgz#5c6f4599aba6b333ee3342e2ed978672f1001f8d"
|
||||
@@ -388,8 +423,8 @@ fastparse@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
|
||||
|
||||
fbjs@^0.8.12:
|
||||
version "0.8.12"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
|
||||
version "0.8.14"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
@@ -399,9 +434,9 @@ fbjs@^0.8.12:
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fbjs@^0.8.4, fbjs@^0.8.5, fbjs@^0.8.8, fbjs@^0.8.9:
|
||||
version "0.8.9"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.9.tgz#180247fbd347dcc9004517b904f865400a0c8f14"
|
||||
fbjs@^0.8.4, fbjs@^0.8.5, fbjs@^0.8.9:
|
||||
version "0.8.12"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
@@ -419,18 +454,33 @@ flexibility@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/flexibility/-/flexibility-2.0.1.tgz#ad323aafc40f469ce624286518fc4d7cd72b7c77"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
||||
function-bind@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
|
||||
|
||||
glamor@2.20.25:
|
||||
version "2.20.25"
|
||||
resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.25.tgz#71b84b82b67a9327771ac59de53ee915d148a4a3"
|
||||
glamor@^2.20.37:
|
||||
version "2.20.37"
|
||||
resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.37.tgz#3cd576deb760eaaf475dcc1f9b77bf6a7d2f8b26"
|
||||
dependencies:
|
||||
babel-runtime "^6.18.0"
|
||||
fbjs "^0.8.8"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.8"
|
||||
fbjs "^0.8.12"
|
||||
inline-style-prefixer "^3.0.6"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
glob@^7.0.5:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -490,7 +540,14 @@ indexes-of@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
|
||||
|
||||
inherits@2.0.1:
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
||||
|
||||
@@ -501,14 +558,7 @@ inline-style-prefixer@^2.0.1, inline-style-prefixer@^2.0.5:
|
||||
bowser "^1.0.0"
|
||||
hyphenate-style-name "^1.0.1"
|
||||
|
||||
inline-style-prefixer@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://artifactory.twitter.biz:443/api/npm/js-virtual/inline-style-prefixer/-/inline-style-prefixer-3.0.2.tgz#989865e0c5de7a946acbea71e16e02741efe0dd7"
|
||||
dependencies:
|
||||
bowser "^1.6.0"
|
||||
css-in-js-utils "^1.0.3"
|
||||
|
||||
inline-style-prefixer@^3.0.6:
|
||||
inline-style-prefixer@^3.0.1, inline-style-prefixer@^3.0.6:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.6.tgz#b27fe309b4168a31eaf38c8e8c60ab9e7c11731f"
|
||||
dependencies:
|
||||
@@ -529,7 +579,7 @@ is-function@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
|
||||
|
||||
is-in-browser@1.0.2, is-in-browser@^1.0.2:
|
||||
is-in-browser@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.0.2.tgz#f688bea8f1e5aadc3244ebc870d188cfb9b613cf"
|
||||
|
||||
@@ -605,70 +655,70 @@ jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
|
||||
jss-camel-case@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-4.0.0.tgz#39ef2a137aaa1e2f160ab826845305f8efabcfd5"
|
||||
jss-camel-case@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-camel-case/-/jss-camel-case-5.0.0.tgz#886c1fe56a8a11577454d6a8b4133caa6c1f53a0"
|
||||
|
||||
jss-compose@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-3.0.1.tgz#0ac07f20baf1d523c211016d383dab08dcfe4186"
|
||||
jss-compose@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-compose/-/jss-compose-4.0.0.tgz#f0109e8e8301a2678279301c24523dbc76115b9b"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-default-unit@^6.0.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-6.1.0.tgz#ea6ca838de119c17adbce597b21ba9c20f7f4d84"
|
||||
jss-default-unit@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-default-unit/-/jss-default-unit-7.0.0.tgz#176c1db91da870e3ad16301f6f4b4cfc6fe1e90a"
|
||||
|
||||
jss-expand@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-3.0.0.tgz#ce22bf8f9d99afa822738d82dcc3bdbf32766b1d"
|
||||
|
||||
jss-extend@^4.0.0:
|
||||
jss-expand@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-4.0.0.tgz#1c377d4efd67f34c997b699aa8bc1dab1c7edf95"
|
||||
resolved "https://registry.yarnpkg.com/jss-expand/-/jss-expand-4.0.0.tgz#71ec15386d7839bb23892acf9dcaa40b7fe9c785"
|
||||
|
||||
jss-extend@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-extend/-/jss-extend-5.0.0.tgz#08a1d4015d05dfe011e3a281457d471226865387"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-global@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-1.0.0.tgz#ba87850cd56d32e0623c3878fd5ef376a61e6f65"
|
||||
|
||||
jss-nested@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-4.0.0.tgz#70d8aaaeb0ae1c0ca6ac74b329255b71e58bf72e"
|
||||
dependencies:
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-preset-default@^2.0.0:
|
||||
jss-global@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-2.0.0.tgz#0368d99626b31067e8d04ab3c7cb17ba8354d422"
|
||||
resolved "https://registry.yarnpkg.com/jss-global/-/jss-global-2.0.0.tgz#a162f822f17e5d760151d908bdb41d7f2824c28f"
|
||||
|
||||
jss-nested@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-nested/-/jss-nested-5.0.0.tgz#c0752f31f2d465110d7de6ac83583dbed669faa0"
|
||||
dependencies:
|
||||
jss-camel-case "^4.0.0"
|
||||
jss-compose "^3.0.0"
|
||||
jss-default-unit "^6.0.0"
|
||||
jss-expand "^3.0.0"
|
||||
jss-extend "^4.0.0"
|
||||
jss-global "^1.0.0"
|
||||
jss-nested "^4.0.0"
|
||||
jss-props-sort "^4.0.0"
|
||||
jss-vendor-prefixer "^5.0.0"
|
||||
warning "^3.0.0"
|
||||
|
||||
jss-props-sort@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-4.0.0.tgz#ef4239c6795ca304c18dce9e0395a1789ed9f78a"
|
||||
jss-preset-default@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-preset-default/-/jss-preset-default-3.0.0.tgz#e43ee1ac526f689baf2bfd28ae95a6fdc3a02663"
|
||||
dependencies:
|
||||
jss-camel-case "^5.0.0"
|
||||
jss-compose "^4.0.0"
|
||||
jss-default-unit "^7.0.0"
|
||||
jss-expand "^4.0.0"
|
||||
jss-extend "^5.0.0"
|
||||
jss-global "^2.0.0"
|
||||
jss-nested "^5.0.0"
|
||||
jss-props-sort "^5.0.0"
|
||||
jss-vendor-prefixer "^6.0.0"
|
||||
|
||||
jss-vendor-prefixer@^5.0.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-5.1.0.tgz#59b73544de81e6b2efd71f6d3b744671826865a2"
|
||||
jss-props-sort@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-props-sort/-/jss-props-sort-5.0.0.tgz#8839c88433f64e8c1dab1a7068796f19b84f9195"
|
||||
|
||||
jss-vendor-prefixer@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jss-vendor-prefixer/-/jss-vendor-prefixer-6.0.0.tgz#be58124f0cbed76e98cc8eb5219dbb260f057d0b"
|
||||
dependencies:
|
||||
css-vendor "^0.3.8"
|
||||
|
||||
jss@^7.0.0:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/jss/-/jss-7.0.3.tgz#87a4ff5c9398f7ee7ddc06a6b02255a4c74d9e1b"
|
||||
jss@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jss/-/jss-8.1.0.tgz#b32f15efcce22446dfda4c2be09a04f38431da0a"
|
||||
dependencies:
|
||||
is-in-browser "1.0.2"
|
||||
warning "3.0.0"
|
||||
is-in-browser "^1.0.2"
|
||||
warning "^3.0.0"
|
||||
|
||||
loader-utils@^1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -694,7 +744,7 @@ lodash@^4.17.1:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.3.1:
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||
dependencies:
|
||||
@@ -712,6 +762,12 @@ math-expression-evaluator@^1.2.14:
|
||||
version "1.2.16"
|
||||
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.16.tgz#b357fa1ca9faefb8e48d10c14ef2bcb2d9f0a7c9"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
@@ -754,6 +810,16 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
postcss-calc@^5.2.0:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e"
|
||||
@@ -1010,19 +1076,13 @@ promise@^7.1.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.5.10:
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8:
|
||||
version "15.5.10"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.3.1"
|
||||
|
||||
prop-types@^15.5.4, prop-types@^15.5.8:
|
||||
version "15.5.8"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
|
||||
q@^1.1.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
|
||||
@@ -1034,6 +1094,16 @@ query-string@^4.1.0:
|
||||
object-assign "^4.1.0"
|
||||
strict-uri-encode "^1.0.0"
|
||||
|
||||
radium@^0.19.1:
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/radium/-/radium-0.19.1.tgz#0fbcc6d0ea5526bdb1e5e5371cad386775a3eec8"
|
||||
dependencies:
|
||||
array-find "^1.0.0"
|
||||
exenv "^1.2.1"
|
||||
inline-style-prefixer "^2.0.5"
|
||||
prop-types "^15.5.8"
|
||||
rimraf "^2.6.1"
|
||||
|
||||
react-addons-perf@^15.4.2:
|
||||
version "15.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-addons-perf/-/react-addons-perf-15.4.2.tgz#110bdcf5c459c4f77cb85ed634bcd3397536383b"
|
||||
@@ -1041,18 +1111,19 @@ react-addons-perf@^15.4.2:
|
||||
fbjs "^0.8.4"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
react-jss@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-6.1.1.tgz#01a548e6531b691186c3e8d8250980fb2938f1fe"
|
||||
react-jss@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-7.0.1.tgz#36c505c3798993edd46ea01734f171f895348e25"
|
||||
dependencies:
|
||||
hoist-non-react-statics "^1.2.0"
|
||||
jss "^7.0.0"
|
||||
jss-preset-default "^2.0.0"
|
||||
jss "^8.1.0"
|
||||
jss-preset-default "^3.0.0"
|
||||
prop-types "^15.5.8"
|
||||
theming "^1.1.0"
|
||||
|
||||
react-native-web@0.0.x:
|
||||
version "0.0.106"
|
||||
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.0.106.tgz#928427320b5963548b372a32b62459154f1e1d7e"
|
||||
version "0.0.116"
|
||||
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.0.116.tgz#e05e376b34617a54d61826e4bc06b0bdbfd3f4b2"
|
||||
dependencies:
|
||||
animated "^0.2.0"
|
||||
array-find-index "^1.0.2"
|
||||
@@ -1067,9 +1138,9 @@ react-native-web@0.0.x:
|
||||
prop-types "^15.5.10"
|
||||
react-timer-mixin "^0.13.3"
|
||||
|
||||
react-primitives@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-primitives/-/react-primitives-0.4.2.tgz#cb001c1122734f177559f5bf590aadd5129b0914"
|
||||
react-primitives@^0.4.3:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/react-primitives/-/react-primitives-0.4.3.tgz#4970afda5a32dccf5ea180380e3a0e16192e4b83"
|
||||
dependencies:
|
||||
animated "^0.1.5"
|
||||
asap "^2.0.5"
|
||||
@@ -1087,7 +1158,17 @@ react-timer-mixin@^0.13.3:
|
||||
version "0.13.3"
|
||||
resolved "https://registry.yarnpkg.com/react-timer-mixin/-/react-timer-mixin-0.13.3.tgz#0da8b9f807ec07dc3e854d082c737c65605b3d22"
|
||||
|
||||
reactxp@^0.34.3:
|
||||
react@^15.5.4:
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
|
||||
dependencies:
|
||||
create-react-class "^15.6.0"
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
reactxp@0.34.3:
|
||||
version "0.34.3"
|
||||
resolved "https://registry.yarnpkg.com/reactxp/-/reactxp-0.34.3.tgz#6481992e57758ae6ffffbfde3d497527bb495032"
|
||||
dependencies:
|
||||
@@ -1120,8 +1201,8 @@ regenerate@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
|
||||
|
||||
regenerator-runtime@^0.10.0:
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e"
|
||||
version "0.10.5"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
|
||||
|
||||
regexpu-core@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -1141,6 +1222,12 @@ regjsparser@^0.1.4:
|
||||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
rimraf@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
sax@~1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828"
|
||||
@@ -1179,7 +1266,7 @@ strict-uri-encode@^1.0.0:
|
||||
|
||||
string-hash@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://artifactory.twitter.biz:443/api/npm/js-virtual/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
|
||||
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
@@ -1194,9 +1281,9 @@ style-loader@^0.18.2:
|
||||
loader-utils "^1.0.2"
|
||||
schema-utils "^0.3.0"
|
||||
|
||||
styled-components@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.1.0.tgz#425805fca7efa5880aad2171f986bfd8a2f0808f"
|
||||
styled-components@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-2.1.1.tgz#7e9b5bc319ee3963b47aebb74f4658119ea9d484"
|
||||
dependencies:
|
||||
buffer "^5.0.3"
|
||||
css-to-react-native "^2.0.3"
|
||||
@@ -1205,7 +1292,7 @@ styled-components@^2.1.0:
|
||||
is-function "^1.0.1"
|
||||
is-plain-object "^2.0.1"
|
||||
prop-types "^15.5.4"
|
||||
stylis "^3.0.19"
|
||||
stylis "^3.2.1"
|
||||
supports-color "^3.2.3"
|
||||
|
||||
styletron-client@^2.5.7:
|
||||
@@ -1224,9 +1311,9 @@ styletron-utils@^2.5.4:
|
||||
dependencies:
|
||||
inline-style-prefixer "^2.0.1"
|
||||
|
||||
stylis@^3.0.19:
|
||||
version "3.1.9"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.1.9.tgz#638370451f980437f57c59e58d2e296be29fafb7"
|
||||
stylis@^3.2.1:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.2.3.tgz#fed751d792af3f48a247769f55aca05c1a100a09"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -1260,6 +1347,16 @@ synctasks@^0.2.9:
|
||||
version "0.2.17"
|
||||
resolved "https://registry.yarnpkg.com/synctasks/-/synctasks-0.2.17.tgz#38852f008878de2e941b6e458ddf552245268da1"
|
||||
|
||||
theming@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/theming/-/theming-1.1.0.tgz#0562760b55a1b919c2d5eeb94130351f8958e13a"
|
||||
dependencies:
|
||||
brcast "^2.0.0"
|
||||
is-function "^1.0.1"
|
||||
is-plain-object "^2.0.1"
|
||||
prop-types "^15.5.8"
|
||||
react "^15.5.4"
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.12"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb"
|
||||
@@ -1288,7 +1385,7 @@ vendors@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22"
|
||||
|
||||
warning@3.0.0, warning@^3.0.0:
|
||||
warning@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
|
||||
dependencies:
|
||||
@@ -1301,3 +1398,7 @@ whatwg-fetch@>=0.10.0:
|
||||
whet.extend@~0.9.9:
|
||||
version "0.9.9"
|
||||
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
||||
@@ -40,35 +40,40 @@ using `aria-label`.
|
||||
In some cases, we also want to alert the end user of the type of selected
|
||||
component (i.e., that it is a “button”). To provide more context to screen
|
||||
readers, you should specify the `accessibilityRole` property. (Note that React
|
||||
Native for Web provides a compatibility mapping of equivalent
|
||||
Native for Web also provides a compatibility mapping of equivalent
|
||||
`accessibilityTraits` and `accessibilityComponentType` values to
|
||||
`accessibilityRole`).
|
||||
|
||||
The `accessibilityRole` prop is used to infer an [analogous HTML
|
||||
element][html-aria-url] to use in addition to the resulting ARIA `role`, where
|
||||
possible. While this may contradict some ARIA recommendations, it also helps
|
||||
avoid certain HTML5 conformance errors and accessibility anti-patterns (e.g.,
|
||||
giving a `heading` role to a `button` element).
|
||||
element][html-aria-url] and ARIA `role`, where possible. In most cases, both
|
||||
the element and ARIA `role` are rendered. While this may contradict some ARIA
|
||||
recommendations, it also helps avoid certain HTML5 conformance errors and
|
||||
accessibility anti-patterns (e.g., giving a `heading` role to a `button`
|
||||
element) and browser bugs.
|
||||
|
||||
For example:
|
||||
|
||||
* `<View accessibilityRole='article' />` => `<article role='article' />`.
|
||||
* `<View accessibilityRole='banner' />` => `<header role='banner' />`.
|
||||
* `<View accessibilityRole='button' />` => `<button type='button' role='button' />`.
|
||||
* `<View accessibilityRole='button' />` => `<div role='button' tabIndex='0' />`.
|
||||
* `<Text accessibilityRole='label' />` => `<label />`.
|
||||
* `<Text accessibilityRole='link' href='/' />` => `<a role='link' href='/' />`.
|
||||
* `<View accessibilityRole='main' />` => `<main role='main' />`.
|
||||
|
||||
In the example below, the `TouchableWithoutFeedback` is announced by screen
|
||||
readers as a native Button.
|
||||
In the example below, the `TouchableHighlight` is announced by screen
|
||||
readers as a button.
|
||||
|
||||
```
|
||||
<TouchableWithoutFeedback accessibilityRole="button" onPress={this._onPress}>
|
||||
```js
|
||||
<TouchableHighlight accessibilityRole="button" onPress={this._handlePress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Press me!</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</TouchableHighlight>
|
||||
```
|
||||
|
||||
Note: The `button` role is not implemented using the native `button` element
|
||||
due to browsers limiting the use of flexbox layout on its children.
|
||||
|
||||
Note: Avoid changing `accessibilityRole` values over time or after user
|
||||
actions. Generally, accessibility APIs do not provide a means of notifying
|
||||
assistive technologies of a `role` value change.
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
# Getting started
|
||||
|
||||
This guide will help you to correctly configure build and test tools to work
|
||||
with React Native for Web.
|
||||
|
||||
Alternatively, you can quickly setup a local project using
|
||||
[create-react-app](https://github.com/facebookincubator/create-react-app)
|
||||
(which supports `react-native-web` out-of-the-box once installed),
|
||||
[react-native-web-starter](https://github.com/grabcode/react-native-web-starter),
|
||||
or [react-native-web-webpack](https://github.com/ndbroadbent/react-native-web-webpack).
|
||||
with React Native for Web. (Alternatively, you can quickly setup a local
|
||||
project using the starter kits listed in the README.)
|
||||
|
||||
It is recommended that your application provide a `Promise` and `Array.from`
|
||||
polyfill.
|
||||
|
||||
## Webpack and Babel
|
||||
## Web packager
|
||||
|
||||
[Webpack](https://webpack.js.org) is a popular build tool for web apps. Below is an
|
||||
example of how to configure a build that uses [Babel](https://babeljs.io/) to
|
||||
compile your JavaScript for the web.
|
||||
|
||||
Create a `web/webpack.config.js` file:
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
// web/webpack.config.js
|
||||
|
||||
// This is needed for webpack to compile JavaScript.
|
||||
// Many OSS React Native packages are not compiled to ES5 before being
|
||||
@@ -37,7 +34,7 @@ const babelLoaderConfiguration = {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
// The 'react-native' preset is recommended
|
||||
// The 'react-native' preset is recommended (or use your own .babelrc)
|
||||
presets: ['react-native']
|
||||
}
|
||||
}
|
||||
@@ -66,7 +63,8 @@ module.exports = {
|
||||
|
||||
plugins: [
|
||||
// `process.env.NODE_ENV === 'production'` must be `true` for production
|
||||
// builds to eliminate development checks and reduce build size.
|
||||
// builds to eliminate development checks and reduce build size. You may
|
||||
// wish to include additional optimizations.
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('production')
|
||||
})
|
||||
@@ -85,36 +83,97 @@ module.exports = {
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to the Webpack documentation for more information.
|
||||
|
||||
## Jest
|
||||
|
||||
[Jest](https://facebook.github.io/jest/) also needs to map `react-native` to `react-native-web`.
|
||||
To run in development:
|
||||
|
||||
```
|
||||
"jest": {
|
||||
"moduleNameMapper": {
|
||||
"react-native": "<rootDir>/node_modules/react-native-web"
|
||||
}
|
||||
}
|
||||
./node_modules/.bin/webpack-dev-server -d --config web/webpack.config.js --inline --hot --colors
|
||||
```
|
||||
|
||||
Please refer to the Jest documentation for more information.
|
||||
To build for production:
|
||||
|
||||
```
|
||||
./node_modules/.bin/webpack -p --config web/webpack.config.js
|
||||
```
|
||||
|
||||
Please refer to the Webpack documentation for more information on configuration.
|
||||
|
||||
## Web entry
|
||||
|
||||
Create a `index.web.js` file (or simply `index.js` for web-only apps).
|
||||
|
||||
### Client-side rendering
|
||||
|
||||
Rendering using `AppRegistry`:
|
||||
|
||||
```js
|
||||
// index.web.js
|
||||
|
||||
import App from './src/App';
|
||||
import React from 'react';
|
||||
import ReactNative, { AppRegistry } from 'react-native';
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App);
|
||||
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: document.getElementById('react-app')
|
||||
});
|
||||
```
|
||||
|
||||
Rendering within existing web apps is also possible using `ReactNative`:
|
||||
|
||||
```js
|
||||
import AppHeader from './src/AppHeader';
|
||||
import React from 'react';
|
||||
import ReactNative from 'react-native';
|
||||
|
||||
ReactNative.render(<AppHeader />, document.getElementById('react-app-header'))
|
||||
```
|
||||
|
||||
And finally, `react-native-web` components will also be rendering within a tree
|
||||
produced by calling `ReactDOM.render` (i.e., an existing web app), but
|
||||
otherwise it is not recommended.
|
||||
|
||||
### Server-side rendering
|
||||
|
||||
Server-side rendering is supported using the `AppRegistry`:
|
||||
|
||||
```js
|
||||
import App from './src/App';
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import ReactNative, { AppRegistry } from 'react-native'
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App)
|
||||
|
||||
// prerender the app
|
||||
const { element, stylesheets } = AppRegistry.getApplication('App', { initialProps });
|
||||
const initialHTML = ReactDOMServer.renderToString(element);
|
||||
const initialStyles = stylesheets.map((sheet) => ReactDOMServer.renderToStaticMarkup(sheet)).join('\n');
|
||||
|
||||
// construct HTML document
|
||||
const document = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
${initialStyles}
|
||||
</head>
|
||||
<body>
|
||||
${initialHTML}
|
||||
`
|
||||
```
|
||||
|
||||
## Web-specific code
|
||||
|
||||
Minor platform differences can use the `Platform` module.
|
||||
|
||||
```js
|
||||
import { AppRegistry, Platform } from 'react-native'
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
AppRegistry.registerComponent('MyApp', () => MyApp)
|
||||
|
||||
if (Platform.OS === 'web') {
|
||||
AppRegistry.runApplication('MyApp', {
|
||||
rootTag: document.getElementById('react-root')
|
||||
});
|
||||
}
|
||||
const styles = StyleSheet.create({
|
||||
height: (Platform.OS === 'web') ? 200 : 100,
|
||||
});
|
||||
```
|
||||
|
||||
More significant platform differences should use platform-specific files (see
|
||||
@@ -137,68 +196,16 @@ import MyComponent from './MyComponent';
|
||||
React Native will automatically import the correct variant for each specific
|
||||
target platform.
|
||||
|
||||
## Client-side rendering
|
||||
## Testing with Jest
|
||||
|
||||
Rendering using `ReactNative`:
|
||||
[Jest](https://facebook.github.io/jest/) also needs to map `react-native` to `react-native-web`.
|
||||
|
||||
```js
|
||||
import React from 'react'
|
||||
import ReactNative from 'react-native'
|
||||
|
||||
// component that renders the app
|
||||
const AppHeaderContainer = (props) => { /* ... */ }
|
||||
|
||||
ReactNative.render(<AppHeaderContainer />, document.getElementById('react-app-header'))
|
||||
```
|
||||
"jest": {
|
||||
"moduleNameMapper": {
|
||||
"react-native": "<rootDir>/node_modules/react-native-web"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rendering using `AppRegistry`:
|
||||
|
||||
```js
|
||||
import React from 'react'
|
||||
import ReactNative, { AppRegistry } from 'react-native'
|
||||
|
||||
// component that renders the app
|
||||
const AppContainer = (props) => { /* ... */ }
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => AppContainer)
|
||||
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: document.getElementById('react-app')
|
||||
})
|
||||
```
|
||||
|
||||
Rendering within `ReactDOM.render` also works when introducing
|
||||
`react-native-web` to an existing web app, but otherwise it is not recommended.
|
||||
|
||||
## Server-side rendering
|
||||
|
||||
Rendering using the `AppRegistry`:
|
||||
|
||||
```js
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import ReactNative, { AppRegistry } from 'react-native'
|
||||
|
||||
// component that renders the app
|
||||
const AppContainer = (props) => { /* ... */ }
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => AppContainer)
|
||||
|
||||
// prerender the app
|
||||
const { element, stylesheets } = AppRegistry.getApplication('App', { initialProps });
|
||||
const initialHTML = ReactDOMServer.renderToString(element);
|
||||
const initialStyles = stylesheets.map((sheet) => ReactDOMServer.renderToStaticMarkup(sheet)).join('\n');
|
||||
|
||||
// construct HTML document
|
||||
const document = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
${initialStyles}
|
||||
</head>
|
||||
<body>
|
||||
${initialHTML}
|
||||
`
|
||||
```
|
||||
Please refer to the Jest documentation for more information.
|
||||
|
||||
11
docs/package.json
Normal file
11
docs/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "yarn && build-storybook -o ./dist -c ./storybook/.storybook",
|
||||
"start": "start-storybook -p 9001 -c ./storybook/.storybook",
|
||||
"release": "yarn build && git checkout gh-pages && rm -rf ../storybook && mv dist ../storybook && git add -A && git commit -m \"Storybook deploy\" && git push origin gh-pages && git checkout -"
|
||||
},
|
||||
"dependencies": {
|
||||
"@storybook/addon-options": "^3.1.6",
|
||||
"@storybook/react": "^3.1.9"
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
import '@kadira/storybook-addon-options/register';
|
||||
import '@storybook/addon-options/register';
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { setOptions } from '@kadira/storybook-addon-options';
|
||||
import { setOptions } from '@storybook/addon-options';
|
||||
import centered from './decorator-centered';
|
||||
import { configure, addDecorator } from '@kadira/storybook';
|
||||
import { configure, addDecorator } from '@storybook/react';
|
||||
|
||||
const context = require.context('../', true, /Docs\.js$/);
|
||||
const context = require.context('../', true, /Screen\.js$/);
|
||||
|
||||
addDecorator(centered);
|
||||
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const DEV = process.env.NODE_ENV !== 'production';
|
||||
module.exports = (storybookBaseConfig, configType) => {
|
||||
const DEV = configType === 'DEVELOPMENT';
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
query: { cacheDirectory: true }
|
||||
},
|
||||
{
|
||||
test: /\.(gif|jpe?g|png|svg)$/,
|
||||
loader: 'url-loader',
|
||||
query: { name: '[name].[ext]' }
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
storybookBaseConfig.module.rules.push({
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: { cacheDirectory: true }
|
||||
}
|
||||
});
|
||||
|
||||
storybookBaseConfig.module.rules.push({
|
||||
test: /\.(gif|jpe?g|png|svg)$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: { name: '[name].[ext]' }
|
||||
}
|
||||
});
|
||||
|
||||
storybookBaseConfig.plugins.push(
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
|
||||
'process.env.__REACT_NATIVE_DEBUG_ENABLED__': DEV
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'react-native': path.join(__dirname, '../../../src/module')
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
storybookBaseConfig.resolve.alias = {
|
||||
'react-native': path.join(__dirname, '../../../src/module')
|
||||
};
|
||||
|
||||
return storybookBaseConfig;
|
||||
};
|
||||
|
||||
@@ -9,14 +9,13 @@ import PropColor from './examples/PropColor';
|
||||
import PropHidesWhenStopped from './examples/PropHidesWhenStopped';
|
||||
import PropSize from './examples/PropSize';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ActivityIndicatorScreen = () =>
|
||||
<UIExplorer title="ActivityIndicator" url="components/ActivityIndicator">
|
||||
<Description>Displays a customizable activity indicator</Description>
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="animating"
|
||||
@@ -25,7 +24,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropAnimating />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="color"
|
||||
@@ -34,7 +33,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropColor />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="hidesWhenStopped"
|
||||
@@ -43,7 +42,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropHidesWhenStopped />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="size"
|
||||
@@ -53,15 +52,7 @@ const sections = [
|
||||
render: () => <PropSize />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('ActivityIndicator', () =>
|
||||
<UIExplorer
|
||||
description="Displays a customizable activity indicator"
|
||||
sections={sections}
|
||||
title="ActivityIndicator"
|
||||
url="components/ActivityIndicator"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('ActivityIndicator', ActivityIndicatorScreen);
|
||||
@@ -8,18 +8,30 @@ import React from 'react';
|
||||
import PropColor from './examples/PropColor';
|
||||
import PropDisabled from './examples/PropDisabled';
|
||||
import PropOnPress from './examples/PropOnPress';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
const ButtonScreen = () =>
|
||||
<UIExplorer title="Button" url="components/Button">
|
||||
<Description>
|
||||
<AppText>
|
||||
A basic button component. Supports a minimal level of customization. You can build your own
|
||||
custom button using <Code>TouchableOpacity</Code> or <Code>TouchableNativeFeedback</Code>.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description="Overrides the text that's read by a screen reader when the user interacts with the element."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="color"
|
||||
@@ -28,16 +40,16 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropColor />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="disabled"
|
||||
typeInfo="?boolean"
|
||||
description="If `true`, disable all interactions for this element."
|
||||
description="If true, disable all interactions for this element."
|
||||
example={{
|
||||
render: () => <PropDisabled />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onPress"
|
||||
@@ -46,30 +58,16 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnPress />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem name="title" typeInfo="string" description="Text to display inside the button." />
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('Button', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
A basic button component. Supports a minimal level of customization.
|
||||
You can build your own custom button using <Code>TouchableOpacity</Code>
|
||||
or <Code>TouchableNativeFeedback</Code>.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="Button"
|
||||
url="components/Button"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('Button', ButtonScreen);
|
||||
@@ -16,14 +16,24 @@ import PropResizeMode from './examples/PropResizeMode';
|
||||
import PropSource from './examples/PropSource';
|
||||
import StaticGetSizeExample from './examples/StaticGetSize';
|
||||
import StaticPrefetchExample from './examples/StaticPrefetch';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ImageScreen = () =>
|
||||
<UIExplorer title="Image" url="components/Image">
|
||||
<Description>
|
||||
An accessibile image component with support for image resizing, default image, and child
|
||||
content.
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
@@ -32,34 +42,44 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="defaultSource"
|
||||
typeInfo="?object"
|
||||
description="An image to display as a placeholder while downloading the final image off the network. `{ uri: string, width, height }`"
|
||||
description={
|
||||
<AppText>
|
||||
An image to display as a placeholder while downloading the final image off the network.{' '}
|
||||
<Code>{'{ uri: string, width, height }'}</Code>
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
render: () => <PropDefaultSource />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="draggable"
|
||||
typeInfo="?boolean = true"
|
||||
description="When false, the image will not be draggable"
|
||||
example={{
|
||||
render: () => <PropDraggable />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onError"
|
||||
typeInfo="?function"
|
||||
description="Invoked on load error with `{nativeEvent: {error}}`."
|
||||
description={
|
||||
<AppText>
|
||||
Invoked on load error with <Code>{'{nativeEvent: {error}}'}</Code>.
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
render: () => <PropOnError />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLoad"
|
||||
@@ -68,7 +88,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnLoad />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLoadEnd"
|
||||
@@ -77,7 +97,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnLoadEnd />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLoadStart"
|
||||
@@ -86,7 +106,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropOnLoadStart />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="resizeMode"
|
||||
@@ -95,25 +115,27 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropResizeMode />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="source"
|
||||
typeInfo="?object"
|
||||
description="`uri` is a string representing the resource identifier for the image, which could be an http address or a base64 encoded image. `{ uri: string, width, height }`"
|
||||
description={
|
||||
<AppText>
|
||||
<Code>uri</Code> is a string representing the resource identifier for the image, which
|
||||
could be an http address or a base64 encoded image.{' '}
|
||||
<Code>{'{ uri: string, width, height }'}</Code>
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropSource />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem name="style" typeInfo="?style" />
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'Properties',
|
||||
entries: [
|
||||
<Section title="Properties">
|
||||
<DocItem
|
||||
name="static resizeMode"
|
||||
typeInfo="object"
|
||||
@@ -121,20 +143,28 @@ const sections = [
|
||||
code: '<Image resizeMode={Image.resizeMode.contain} />'
|
||||
}}
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
name="static getSize"
|
||||
typeInfo="(uri: string, success: (width, height) => {}, failure: function) => void"
|
||||
description="Retrieve the width and height (in pixels) of an image prior to displaying it. This method can fail if the image cannot be found, or fails to download.\n\n(In order to retrieve the image dimensions, the image may first need to be loaded or downloaded, after which it will be cached. This means that in principle you could use this method to preload images, however it is not optimized for that purpose, and may in future be implemented in a way that does not fully load/download the image data.)"
|
||||
description={[
|
||||
<AppText key={1}>
|
||||
Retrieve the width and height (in pixels) of an image prior to displaying it. This
|
||||
method can fail if the image cannot be found, or fails to download.
|
||||
</AppText>,
|
||||
<AppText key={2}>
|
||||
(In order to retrieve the image dimensions, the image may first need to be loaded or
|
||||
downloaded, after which it will be cached. This means that in principle you could use
|
||||
this method to preload images, however it is not optimized for that purpose, and may in
|
||||
future be implemented in a way that does not fully load/download the image data.)
|
||||
</AppText>
|
||||
]}
|
||||
example={{
|
||||
render: () => <StaticGetSizeExample />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static prefetch"
|
||||
@@ -144,15 +174,7 @@ const sections = [
|
||||
render: () => <StaticPrefetchExample />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('Image', () =>
|
||||
<UIExplorer
|
||||
description="An accessibile image component with support for image resizing, default image, and child content."
|
||||
sections={sections}
|
||||
title="Image"
|
||||
url="components/Image"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('Image', ImageScreen);
|
||||
@@ -43,7 +43,10 @@ class NetworkImageExample extends PureComponent {
|
||||
>
|
||||
{loader}
|
||||
</Image>
|
||||
{this.state.message && <Text style={helpers.styles.marginLeft}>{this.state.message}</Text>}
|
||||
{this.state.message &&
|
||||
<Text style={helpers.styles.marginLeft}>
|
||||
{this.state.message}
|
||||
</Text>}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@ import { Image, StyleSheet, Text } from 'react-native';
|
||||
|
||||
const ImageChildrenExample = () =>
|
||||
<Image source={sources.large} style={styles.image}>
|
||||
<Text style={styles.text}>
|
||||
React
|
||||
</Text>
|
||||
<Text style={styles.text}>React</Text>
|
||||
</Image>;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
@@ -13,9 +13,7 @@ const ImageResizeModeExample = () =>
|
||||
<View key={i}>
|
||||
<View style={styles.horizontal}>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Contain
|
||||
</Text>
|
||||
<Text style={[styles.resizeModeText]}>Contain</Text>
|
||||
<Image
|
||||
resizeMode={Image.resizeMode.contain}
|
||||
source={source}
|
||||
@@ -23,9 +21,7 @@ const ImageResizeModeExample = () =>
|
||||
/>
|
||||
</View>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Cover
|
||||
</Text>
|
||||
<Text style={[styles.resizeModeText]}>Cover</Text>
|
||||
<Image
|
||||
resizeMode={Image.resizeMode.cover}
|
||||
source={source}
|
||||
@@ -33,9 +29,7 @@ const ImageResizeModeExample = () =>
|
||||
/>
|
||||
</View>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Stretch
|
||||
</Text>
|
||||
<Text style={[styles.resizeModeText]}>Stretch</Text>
|
||||
<Image
|
||||
resizeMode={Image.resizeMode.stretch}
|
||||
source={source}
|
||||
@@ -43,15 +37,11 @@ const ImageResizeModeExample = () =>
|
||||
/>
|
||||
</View>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Repeat
|
||||
</Text>
|
||||
<Text style={[styles.resizeModeText]}>Repeat</Text>
|
||||
<Image resizeMode={'repeat'} source={source} style={styles.resizeMode} />
|
||||
</View>
|
||||
<View>
|
||||
<Text style={[styles.resizeModeText]}>
|
||||
Center
|
||||
</Text>
|
||||
<Text style={[styles.resizeModeText]}>Center</Text>
|
||||
<Image resizeMode={'center'} source={source} style={styles.resizeMode} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -30,7 +30,9 @@ class ImagePrefetchExample extends PureComponent {
|
||||
: null}
|
||||
{startLoad
|
||||
? <View>
|
||||
<Text>{this.state.events.join('\n')}</Text>
|
||||
<Text>
|
||||
{this.state.events.join('\n')}
|
||||
</Text>
|
||||
<Image
|
||||
onLoad={this._handleLoad}
|
||||
onLoadEnd={this._handleLoadEnd}
|
||||
|
||||
@@ -8,14 +8,13 @@ import PropIndeterminate from './examples/PropIndeterminate';
|
||||
import PropProgress from './examples/PropProgress';
|
||||
import PropTrackColor from './examples/PropTrackColor';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ProgressBarScreen = () =>
|
||||
<UIExplorer title="ProgressBar" url="components/ProgressBar">
|
||||
<Description>Display an activity progress bar</Description>
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
description="Color of the progress bar."
|
||||
@@ -24,7 +23,7 @@ const sections = [
|
||||
}}
|
||||
name="color"
|
||||
typeInfo="?string = #1976D2"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Whether the progress bar will show indeterminate progress."
|
||||
@@ -33,7 +32,7 @@ const sections = [
|
||||
}}
|
||||
name="indeterminate"
|
||||
typeInfo="?boolean = true"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The progress value (between 0 and 1)."
|
||||
@@ -42,7 +41,7 @@ const sections = [
|
||||
}}
|
||||
name="progress"
|
||||
typeInfo="?number"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Color of the track bar."
|
||||
@@ -52,11 +51,9 @@ const sections = [
|
||||
name="trackColor"
|
||||
typeInfo="?string = 'transparent'"
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="Custom sizes can be created using styles"
|
||||
example={{
|
||||
@@ -64,15 +61,7 @@ const sections = [
|
||||
render: () => <CustomSize />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('ProgressBar', () =>
|
||||
<UIExplorer
|
||||
description="Display an activity progress bar"
|
||||
sections={sections}
|
||||
title="ProgressBar"
|
||||
url="components/ProgressBar"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('ProgressBar', ProgressBarScreen);
|
||||
@@ -8,29 +8,44 @@ import { HorizontalExample } from './examples/Horizontal';
|
||||
import ScrollToExample from './examples/ScrollTo';
|
||||
import ScrollToEndExample from './examples/ScrollToEnd';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem, TextList } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
TextList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const ScrollViewScreen = () =>
|
||||
<UIExplorer title="ScrollView" url="components/ScrollView">
|
||||
<Description>
|
||||
<AppText>
|
||||
A scrollable <Code>View</Code> that provides itegration with the touch-locking responder
|
||||
system. <Code>ScrollView</Code>'s must have a bounded height: either set the height of the
|
||||
view directly (discouraged) or make sure all parent views have bounded height (e.g.,
|
||||
transfer <Code>{'{ flex: 1}'}</Code> down the view stack).
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="contentContainerStyle"
|
||||
typeInfo="?style"
|
||||
description="These styles will be applied to the scroll view content container which wraps all of the child views."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="horizontal"
|
||||
typeInfo="?boolean = false"
|
||||
description="When `true`, the scroll view's children are arranged horizontally in a row instead of vertically in a column."
|
||||
description="When true, the scroll view's children are arranged horizontally in a row instead of vertically in a column."
|
||||
example={{
|
||||
render: () => <HorizontalExample />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="keyboardDismissMode"
|
||||
@@ -41,37 +56,41 @@ const sections = [
|
||||
</AppText>,
|
||||
<TextList
|
||||
items={[
|
||||
'`none` (the default), drags do not dismiss the keyboard.',
|
||||
'`on-drag`, the keyboard is dismissed when a drag begins.',
|
||||
'`interactive` (not supported on web; same as `none`)'
|
||||
<AppText>
|
||||
<Code>none</Code> (the default): drags do not dismiss the keyboard.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
<Code>on-drag</Code>: the keyboard is dismissed when a drag begins.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
<Code>interactive</Code> (not supported on web; same as <Code>none</Code>)
|
||||
</AppText>
|
||||
]}
|
||||
/>
|
||||
]}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onContentSizeChange"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
Called when scrollable content view of the <Code>ScrollView</Code>
|
||||
changes. It's implemented using the <Code>onLayout</Code> handler
|
||||
attached to the content container which this <Code>ScrollView</Code> renders.
|
||||
Called when scrollable content view of the <Code>ScrollView</Code> changes. It's
|
||||
implemented using the <Code>onLayout</Code> handler attached to the content container
|
||||
which this <Code>ScrollView</Code> renders.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onScroll"
|
||||
typeInfo="?function"
|
||||
description={[
|
||||
<AppText>
|
||||
Fires at most once per frame during scrolling. The frequency of the events can
|
||||
be contolled using the <Code>scrollEventThrottle</Code> prop.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
Invoked on scroll with the following event:
|
||||
Fires at most once per frame during scrolling. The frequency of the events can be
|
||||
contolled using the <Code>scrollEventThrottle</Code> prop.
|
||||
</AppText>,
|
||||
<AppText>Invoked on scroll with the following event:</AppText>,
|
||||
<Code>{`{
|
||||
nativeEvent: {
|
||||
contentOffset: { x, y },
|
||||
@@ -80,58 +99,54 @@ const sections = [
|
||||
}
|
||||
}`}</Code>
|
||||
]}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollEnabled"
|
||||
typeInfo="?boolean = true"
|
||||
description="When false, the content does not scroll."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollEventThrottle"
|
||||
typeInfo="?number = 0"
|
||||
description={
|
||||
<AppText>
|
||||
This controls how often the scroll event will be fired while scrolling (as a
|
||||
time interval in ms). A lower number yields better accuracy for code that is
|
||||
tracking the scroll position, but can lead to scroll performance problems. The
|
||||
default value is <Code>0</Code>, which means the scroll event will be sent only once
|
||||
each
|
||||
time the view is scrolled.
|
||||
This controls how often the scroll event will be fired while scrolling (as a time
|
||||
interval in ms). A lower number yields better accuracy for code that is tracking the
|
||||
scroll position, but can lead to scroll performance problems. The default value is{' '}
|
||||
<Code>0</Code>, which means the scroll event will be sent only once each time the view
|
||||
is scrolled.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Instance methods',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Instance methods">
|
||||
<DocItem
|
||||
name="getInnerViewNode"
|
||||
typeInfo="() => node"
|
||||
description="Returns a reference to the underlying content container DOM node within the ScrollView."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="getScrollableNode"
|
||||
typeInfo="() => node"
|
||||
description="Returns a reference to the underlying scrollable DOM node."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="getScrollResponder"
|
||||
typeInfo="() => ScrollResponder"
|
||||
description={
|
||||
<AppText>
|
||||
Returns a reference to the underlying scroll responder, which supports
|
||||
operations like <Code>scrollTo</Code>. All <Code>ScrollView</Code>-like components
|
||||
should implement
|
||||
this method so that they can be composed while providing access to the
|
||||
underlying scroll responder's methods.
|
||||
Returns a reference to the underlying scroll responder, which supports operations like{' '}
|
||||
<Code>scrollTo</Code>. All <Code>ScrollView</Code>-like components should implement this
|
||||
method so that they can be composed while providing access to the underlying scroll
|
||||
responder's methods.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollTo"
|
||||
@@ -140,7 +155,7 @@ const sections = [
|
||||
example={{
|
||||
render: () => <ScrollToExample />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="scrollToEnd"
|
||||
@@ -150,23 +165,7 @@ const sections = [
|
||||
render: () => <ScrollToEndExample />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('ScrollView', () =>
|
||||
<UIExplorer
|
||||
description={
|
||||
<AppText>
|
||||
A scrollable <Code>View</Code> that provides itegration with the touch-locking responder
|
||||
system. <Code>ScrollView</Code>'s
|
||||
must have a bounded height: either set the height of the view directly (discouraged) or make
|
||||
sure all parent views have
|
||||
bounded height (e.g., transfer <Code>{'{ flex: 1}'}</Code> down the view stack).
|
||||
</AppText>
|
||||
}
|
||||
sections={sections}
|
||||
title="ScrollView"
|
||||
url="components/ScrollView"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('ScrollView', ScrollViewScreen);
|
||||
@@ -5,10 +5,11 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { action } from '@kadira/storybook';
|
||||
import { ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
const onScroll = action('ScrollView.onScroll');
|
||||
const onScroll = () => {
|
||||
console.log('ScrollView.onScroll');
|
||||
};
|
||||
|
||||
const VerticalExample = () =>
|
||||
<View style={styles.scrollViewContainer}>
|
||||
@@ -20,7 +21,9 @@ const VerticalExample = () =>
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>{i}</Text>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
@@ -37,7 +40,9 @@ const HorizontalExample = () =>
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>{i}</Text>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Button, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import { Button, ScrollView, StyleSheet, Text, TouchableHighlight, View } from 'react-native';
|
||||
|
||||
export default class ScrollToExample extends PureComponent {
|
||||
render() {
|
||||
@@ -20,9 +20,15 @@ export default class ScrollToExample extends PureComponent {
|
||||
style={styles.scrollViewStyle}
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>{i}</Text>
|
||||
</View>
|
||||
<TouchableHighlight
|
||||
key={i}
|
||||
onPress={() => {}}
|
||||
style={[styles.box, styles.horizontalBox]}
|
||||
>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
</TouchableHighlight>
|
||||
)}
|
||||
</ScrollView>
|
||||
<Button
|
||||
|
||||
@@ -21,7 +21,9 @@ export default class ScrollToEndExample extends PureComponent {
|
||||
>
|
||||
{Array.from({ length: 50 }).map((item, i) =>
|
||||
<View key={i} style={[styles.box, styles.horizontalBox]}>
|
||||
<Text>{i}</Text>
|
||||
<Text>
|
||||
{i}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
@@ -13,14 +13,28 @@ import PropThumbColor from './examples/PropThumbColor';
|
||||
import PropTrackColor from './examples/PropTrackColor';
|
||||
import PropValue from './examples/PropValue';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const SwitchScreen = () =>
|
||||
<UIExplorer title="Switch" url="components/Switch">
|
||||
<Description>
|
||||
<AppText>
|
||||
This is a controlled component that requires an <Code>onValueChange</Code> callback that
|
||||
updates the value prop in order for the component to reflect user actions. If the{' '}
|
||||
<Code>value</Code> prop is not updated, the component will continue to render the supplied{' '}
|
||||
<Code>value</Code> prop instead of the expected result of any user actions.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
description="The color of the thumb grip when the switch is turned on."
|
||||
@@ -29,7 +43,7 @@ const sections = [
|
||||
}}
|
||||
name="activeThumbColor"
|
||||
typeInfo="?color = #009688"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The color of the track when the switch is turned on."
|
||||
@@ -38,16 +52,16 @@ const sections = [
|
||||
}}
|
||||
name="activeTrackColor"
|
||||
typeInfo="?color = #A3D3CF"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="If `true` the user won't be able to interact with the switch."
|
||||
description="If true, the user won't be able to interact with the switch."
|
||||
example={{
|
||||
render: () => <PropDisabled />
|
||||
}}
|
||||
name="disabled"
|
||||
typeInfo="?boolean = false"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Invoked with the new value when the value changes."
|
||||
@@ -56,7 +70,7 @@ const sections = [
|
||||
}}
|
||||
name="onValueChange"
|
||||
typeInfo="?function"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The color of the thumb grip when the switch is turned off."
|
||||
@@ -65,7 +79,7 @@ const sections = [
|
||||
}}
|
||||
name="thumbColor"
|
||||
typeInfo="?color = #FAFAFA"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The color of the track when the switch is turned off."
|
||||
@@ -74,7 +88,7 @@ const sections = [
|
||||
}}
|
||||
name="trackColor"
|
||||
typeInfo="?color = #939393"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="The value of the switch. If `true` the switch will be turned on."
|
||||
@@ -83,21 +97,21 @@ const sections = [
|
||||
}}
|
||||
name="value"
|
||||
typeInfo="?boolean = false"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="(For compatibility with React Native. Equivalent to "activeTrackColor")"
|
||||
label="compat"
|
||||
name="onTintColor"
|
||||
typeInfo="?color"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="(For compatibility with React Native. Equivalent to "trackColor")"
|
||||
label="compat"
|
||||
name="tintColor"
|
||||
typeInfo="?color"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="(For compatibility with React Native. Equivalent to "thumbColor")"
|
||||
@@ -105,12 +119,9 @@ const sections = [
|
||||
name="thumbTintColor"
|
||||
typeInfo="?color"
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="Custom sizes can be created using styles"
|
||||
example={{
|
||||
@@ -118,22 +129,7 @@ const sections = [
|
||||
render: () => <CustomSize />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('Switch', () =>
|
||||
<UIExplorer
|
||||
description={
|
||||
<AppText>
|
||||
This is a controlled component that requires an <Code>onValueChange</Code> callback
|
||||
that updates the value prop in order for the component to reflect user actions. If
|
||||
the <Code>value</Code> prop is not updated, the component will continue to render the
|
||||
supplied <Code>value</Code> prop instead of the expected result of any user actions.
|
||||
</AppText>
|
||||
}
|
||||
sections={sections}
|
||||
title="Switch"
|
||||
url="components/Switch"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('Switch', SwitchScreen);
|
||||
@@ -28,7 +28,9 @@ class SwitchOnValueChangeExample extends PureComponent {
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchIsOn}
|
||||
/>
|
||||
<Text>{eventSwitchIsOn ? 'On' : 'Off'}</Text>
|
||||
<Text>
|
||||
{eventSwitchIsOn ? 'On' : 'Off'}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.alignCenter}>
|
||||
<Switch
|
||||
@@ -41,7 +43,9 @@ class SwitchOnValueChangeExample extends PureComponent {
|
||||
style={styles.marginBottom}
|
||||
value={eventSwitchRegressionIsOn}
|
||||
/>
|
||||
<Text>{eventSwitchRegressionIsOn ? 'On' : 'Off'}</Text>
|
||||
<Text>
|
||||
{eventSwitchRegressionIsOn ? 'On' : 'Off'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -8,8 +8,155 @@ import PropChildren from './examples/PropChildren';
|
||||
import PropNumberOfLines from './examples/PropNumberOfLines';
|
||||
import PropOnPress from './examples/PropOnPress';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem, StyleList } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
StyleList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const TextScreen = () =>
|
||||
<UIExplorer title="Text" url="components/Text">
|
||||
<Description>
|
||||
<AppText>
|
||||
Text is component for displaying text. It supports style, basic touch handling, and inherits
|
||||
typographic styles from ancestor elements.
|
||||
</AppText>
|
||||
<AppText>
|
||||
Text is unique relative to layout: child elements use text layout ("inline") rather than
|
||||
flexbox layout. This means that elements inside of a Text are not rectangles, as they wrap
|
||||
when reaching the edge of their container.
|
||||
</AppText>
|
||||
<AppText>NOTE: Text will transfer all other props to the rendered HTML element.</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description="Overrides the text that is read by a screen reader when the user interacts with the element. (This is implemented using 'aria-label'.)"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="accessibilityLiveRegion"
|
||||
typeInfo="?enum('assertive', 'none', 'polite')"
|
||||
description={
|
||||
<AppText>
|
||||
Indicates to assistive technologies whether to notify the user when the view changes.
|
||||
The values of this attribute are expressed in degrees of importance. When regions are
|
||||
specified as <Code>polite</Code> (recommended), updates take low priority. When regions
|
||||
are specified as <Code>assertive</Code>, assistive technologies will interrupt and
|
||||
immediately notify the user. (This is implemented using 'aria-live'.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="accessibilityRole"
|
||||
typeInfo="?enum(roles)"
|
||||
description={
|
||||
<AppText>
|
||||
Allows assistive technologies to present and support interaction with the view in a
|
||||
manner that is consistent with user expectations for similar views of that type. For
|
||||
example, marking a touchable view with an <Code>accessibilityRole</Code> of{' '}
|
||||
<Code>button</Code>. For compatibility with React Native{' '}
|
||||
<Code>accessibilityTraits</Code> and <Code>accessibilityComponentType</Code> are mapped
|
||||
to <Code>accessibilityRole</Code>. (This is implemented using ARIA roles.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="accessible"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>
|
||||
When <Code>true</Code>, indicates that the view is an accessibility element (i.e.,
|
||||
focusable) and groups its child content. By default, all the touchable elements and
|
||||
elements with <Code>accessibilityRole</Code> of <Code>button</Code> and{' '}
|
||||
<Code>link</Code> are accessible. (This is implemented using 'tabindex'.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
typeInfo="?any"
|
||||
description={`Child content. Nested text components will inherit the styles of their parents
|
||||
(only backgroundColor is inherited from non-Text parents). <Text>
|
||||
only supports other <Text> and raw text (strings) as children.`}
|
||||
example={{
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="importantForAccessibility"
|
||||
typeInfo="?enum('auto', 'no', 'no-hide-descendants', 'yes')"
|
||||
description={[
|
||||
<AppText>
|
||||
A value of <Code>no</Code> will remove the element from the tab flow.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
A value of <Code>no-hide-descendants</Code> will hide the element and its children from
|
||||
assistive technologies. (This is implemented using 'aria-hidden'.)
|
||||
</AppText>
|
||||
]}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="numberOfLines"
|
||||
typeInfo="?number"
|
||||
description="Truncates the text with an ellipsis after this many lines. Currently only supports `1`."
|
||||
example={{
|
||||
render: () => <PropNumberOfLines />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
Invoked on mount and layout changes with{' '}
|
||||
<Code>{'{ nativeEvent: { layout: { x, y, width, height } } }'}</Code>, where{' '}
|
||||
<Code>x</Code> and <Code>y</Code> are the offsets from the parent node.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onPress"
|
||||
typeInfo="?function"
|
||||
description="Called when the Text is pressed"
|
||||
example={{
|
||||
render: () => <PropOnPress />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="selectable"
|
||||
typeInfo="?boolean"
|
||||
description="When false, the text is not selectable."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
typeInfo="?style"
|
||||
description={<StyleList stylePropTypes={stylePropTypes} />}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests. The test ID is rendered to a 'data-testid' DOM attribute"
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
const stylePropTypes = [
|
||||
{
|
||||
@@ -112,154 +259,4 @@ const stylePropTypes = [
|
||||
}
|
||||
];
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description="Overrides the text that is read by a screen reader when the user interacts with the element. (This is implemented using 'aria-label'.)"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="accessibilityLiveRegion"
|
||||
typeInfo="?enum('assertive', 'none', 'polite')"
|
||||
description={
|
||||
<AppText>
|
||||
Indicates to assistive technologies whether to notify the user when the view changes.
|
||||
The values of
|
||||
this attribute are expressed in degrees of importance. When regions are specified as{
|
||||
' '
|
||||
}
|
||||
<Code>polite</Code> (recommended),
|
||||
updates take low priority. When regions are specified as <Code>assertive</Code>,
|
||||
assistive technologies will
|
||||
interrupt and immediately notify the user. (This is implemented using 'aria-live'.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="accessibilityRole"
|
||||
typeInfo="?enum(roles)"
|
||||
description={
|
||||
<AppText>
|
||||
Allows assistive technologies to present and support interaction with the view in a
|
||||
manner that is
|
||||
consistent with user expectations for similar views of that type. For example, marking a
|
||||
touchable
|
||||
view with an <Code>accessibilityRole</Code> of <Code>button</Code>. For compatibility
|
||||
with React
|
||||
Native <Code>accessibilityTraits</Code> and <Code>accessibilityComponentType</Code> are
|
||||
mapped
|
||||
to <Code>accessibilityRole</Code>. (This is implemented using ARIA roles.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="accessible"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>
|
||||
When <Code>true</Code>, indicates that the view is an accessibility element (i.e.,
|
||||
focusable) and
|
||||
groups its child content. By default, all the touchable elements and elements
|
||||
with <Code>accessibilityRole</Code> of <Code>button</Code> and <Code>link</Code> are
|
||||
accessible.
|
||||
(This is implemented using 'tabindex'.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="children"
|
||||
typeInfo="?any"
|
||||
description={`Child content. Nested text components will inherit the styles of their parents
|
||||
(only backgroundColor is inherited from non-Text parents). <Text>
|
||||
only supports other <Text> and raw text (strings) as children.`}
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropChildren />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="importantForAccessibility"
|
||||
typeInfo="?enum('auto', 'no', 'no-hide-descendants', 'yes')"
|
||||
description={
|
||||
'A value of `no` will remove the element from the tab flow.\n\nA value of `no-hide-descendants` will hide the element and its children from assistive technologies. (This is implemented using `aria-hidden`.)'
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="numberOfLines"
|
||||
typeInfo="?number"
|
||||
description="Truncates the text with an ellipsis after this many lines. Currently only supports `1`."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropNumberOfLines />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description="Invoked on mount and layout changes with `{ nativeEvent: { layout: { x, y, width, height } } }`, where `x` and `y` are the offsets from the parent node."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onPress"
|
||||
typeInfo="?function"
|
||||
description="Called when the Text is pressed"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropOnPress />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="selectable"
|
||||
typeInfo="?boolean"
|
||||
description="When `false`, the text is not selectable."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
typeInfo="?style"
|
||||
description={<StyleList stylePropTypes={stylePropTypes} />}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests. The test ID is rendered to a `data-testid` DOM attribute"
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('Text', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
Text is component for displaying text. It supports style, basic touch handling, and inherits
|
||||
typographic
|
||||
styles from ancestor elements.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
Text is unique relative to layout: child elements use text layout ("inline") rather than
|
||||
flexbox layout.
|
||||
This means that elements inside of a Text are not rectangles, as they wrap when reaching the
|
||||
edge of
|
||||
their container.
|
||||
</AppText>,
|
||||
<AppText>NOTE: Text will transfer all other props to the rendered HTML element.</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="Text"
|
||||
url="components/Text"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('Text', TextScreen);
|
||||
@@ -15,13 +15,8 @@ const Entity = ({ children }) =>
|
||||
const TextChildrenExample = () =>
|
||||
<View>
|
||||
<Text>
|
||||
This text contains an inline blue view
|
||||
{' '}
|
||||
<View style={{ width: 25, height: 25, backgroundColor: 'steelblue' }} />
|
||||
{' '}
|
||||
and
|
||||
an inline image
|
||||
{' '}
|
||||
This text contains an inline blue view{' '}
|
||||
<View style={{ width: 25, height: 25, backgroundColor: 'steelblue' }} /> and an inline image{' '}
|
||||
<Image
|
||||
source={{ uri: 'http://lorempixel.com/30/11' }}
|
||||
style={{ width: 30, height: 11, resizeMode: 'cover' }}
|
||||
@@ -34,9 +29,7 @@ const TextChildrenExample = () =>
|
||||
(Normal text,
|
||||
<Text style={{ fontWeight: 'bold' }}>
|
||||
(and bold
|
||||
<Text style={{ fontSize: 11, color: '#527fe4' }}>
|
||||
(and tiny inherited bold blue)
|
||||
</Text>
|
||||
<Text style={{ fontSize: 11, color: '#527fe4' }}>(and tiny inherited bold blue)</Text>
|
||||
)
|
||||
</Text>
|
||||
)
|
||||
@@ -47,9 +40,7 @@ const TextChildrenExample = () =>
|
||||
(is inherited
|
||||
<Text style={{ opacity: 0.7 }}>
|
||||
(and accumulated
|
||||
<Text style={{ backgroundColor: '#ffaaaa' }}>
|
||||
(and also applies to the background)
|
||||
</Text>
|
||||
<Text style={{ backgroundColor: '#ffaaaa' }}>(and also applies to the background)</Text>
|
||||
)
|
||||
</Text>
|
||||
)
|
||||
@@ -60,7 +51,6 @@ const TextChildrenExample = () =>
|
||||
<Entity>Entity Name</Entity>
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
</View>;
|
||||
|
||||
export default TextChildrenExample;
|
||||
|
||||
@@ -22,7 +22,9 @@ class TextOnPressExample extends React.Component {
|
||||
Text has built-in onPress handling
|
||||
</Text>
|
||||
<View style={styles.logBox}>
|
||||
<Text>{textLog}</Text>
|
||||
<Text>
|
||||
{textLog}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
/*
|
||||
import createReactClass from 'create-react-class';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { PropText, StyleList } from '../../ui-explorer';
|
||||
import UIExplorer, { PropText, storiesOf, StyleList } from '../../ui-explorer';
|
||||
import { Image, Text, View } from 'react-native';
|
||||
|
||||
const AttributeToggler = createReactClass({
|
||||
|
||||
@@ -19,14 +19,29 @@ import PropSelectTextOnFocus from './examples/PropSelectTextOnFocus';
|
||||
import TextInputEvents from './examples/TextInputEvents';
|
||||
import TextInputRewrite, { TextInputRewriteInvalidCharacters } from './examples/Rewrite';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem, StyleList, TextList } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
StyleList,
|
||||
TextList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const TextInputScreen = () =>
|
||||
<UIExplorer title="TextInput" url="components/TextInput">
|
||||
<Description>
|
||||
<AppText>
|
||||
Accessible single- and multi-line text input via a keyboard. Supports features such as
|
||||
auto-complete, auto-focus, placeholder text, and event callbacks. Note: some props are
|
||||
exclusive to or excluded from <Code>multiline</Code>.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
|
||||
<DocItem
|
||||
name="autoCapitalize"
|
||||
@@ -38,8 +53,12 @@ const sections = [
|
||||
<TextList
|
||||
key={2}
|
||||
items={[
|
||||
<AppText><Code>characters</Code>: Automatically capitalize all characters.</AppText>,
|
||||
<AppText><Code>none</Code>: Completely disables automatic capitalization.</AppText>,
|
||||
<AppText>
|
||||
<Code>characters</Code>: Automatically capitalize all characters.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
<Code>none</Code>: Completely disables automatic capitalization.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
<Code>sentences</Code>: Automatically capitalize the first letter of sentences.
|
||||
</AppText>,
|
||||
@@ -50,10 +69,9 @@ const sections = [
|
||||
/>
|
||||
]}
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropAutoCapitalize />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
@@ -61,49 +79,46 @@ const sections = [
|
||||
typeInfo="?string"
|
||||
description={
|
||||
<AppText>
|
||||
Indicates whether the value of the control can be automatically
|
||||
completed by the browser.{' '}
|
||||
Indicates whether the value of the control can be automatically completed by the
|
||||
browser.{' '}
|
||||
<AppText
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input"
|
||||
target="_blank"
|
||||
>
|
||||
Accepted
|
||||
values.
|
||||
Accepted values.
|
||||
</AppText>
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="autoCorrect"
|
||||
typeInfo="?boolean = true"
|
||||
description="Automatically correct spelling mistakes (only available in iOS Safari)."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="autoFocus"
|
||||
typeInfo="?boolean = false"
|
||||
description="If `true`, focuses the input on `componentDidMount`. Only the first form element in a document with `autofocus` is focused."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="blurOnSubmit"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>
|
||||
If <Code>true</Code>, the text field will blur when submitted. The
|
||||
default value is <Code>true</Code> for single-line fields and
|
||||
{' '}<Code>false</Code> for multiline fields. Note, for multiline fields
|
||||
setting <Code>blurOnSubmit</Code> to <Code>true</Code> means that
|
||||
pressing return will blur the field and trigger the <Code>onSubmitEditing</Code>{' '}
|
||||
event instead of inserting a newline
|
||||
into the field.
|
||||
If <Code>true</Code>, the text field will blur when submitted. The default value is{' '}
|
||||
<Code>true</Code> for single-line fields and <Code>false</Code> for multiline fields.
|
||||
Note, for multiline fields setting <Code>blurOnSubmit</Code> to <Code>true</Code> means
|
||||
that pressing return will blur the field and trigger the <Code>onSubmitEditing</Code>{' '}
|
||||
event instead of inserting a newline into the field.
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
render: () => <PropBlurOnSubmit />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="clearTextOnFocus"
|
||||
@@ -112,93 +127,88 @@ const sections = [
|
||||
example={{
|
||||
render: () => <PropClearTextOnFocus />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="defaultValue"
|
||||
typeInfo="?string"
|
||||
description={
|
||||
<AppText>
|
||||
Provides an initial value that will change when the user starts typing. Useful
|
||||
for simple use-cases where you don't want to deal with listening to events and
|
||||
updating the <Code>value</Code> prop to keep the controlled state in sync.
|
||||
Provides an initial value that will change when the user starts typing. Useful for
|
||||
simple use-cases where you don't want to deal with listening to events and updating the{' '}
|
||||
<Code>value</Code> prop to keep the controlled state in sync.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="editable"
|
||||
typeInfo="?boolean = true"
|
||||
description="If `false`, text is not editable (i.e., read-only). "
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropEditable />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="keyboardType"
|
||||
typeInfo="enum('default', 'email-address', 'numeric', 'phone-pad', 'search', 'url', 'web-search') = 'default'"
|
||||
description="Determines which keyboard to open on devices with a virtual keyboard. Safari iOS requires an ancestral `<form action>` element to display the `search` keyboard). (Not available when `multiline` is `true`.)"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropKeyboardType />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="maxLength"
|
||||
typeInfo="?number"
|
||||
description="Limits the maximum number of characters that can be entered."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropMaxLength />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="multiline"
|
||||
typeInfo="?boolean = false"
|
||||
description="If true, the text input can be multiple lines."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropMultiline />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="numberOfLines"
|
||||
typeInfo="?number"
|
||||
description="Sets the number of lines for a multiline `TextInput`. (Requires `multiline` to be `true`.)"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropNumberOfLines />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onBlur"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input is blurred."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onChange"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input's text changes."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onChangeText"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input's text changes. The text is passed as an argument to the callback handler."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onFocus"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the text input is focused."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onKeyPress"
|
||||
@@ -208,13 +218,19 @@ const sections = [
|
||||
Callback that is called when a key is pressed. This will be called with{' '}
|
||||
<Code>{`{
|
||||
nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
where keyValue is <Code>Enter</Code> or <Code>Backspace</Code> for
|
||||
respective keys and the typed-in character otherwise including <Code>' '</Code>
|
||||
for space. Modifier keys (e.g., <Code>shiftKey</Code>) are also included in
|
||||
the <Code>nativeEvent</Code>. Fires before <Code>onChange</Code> callbacks.
|
||||
where keyValue is <Code>Enter</Code> or <Code>Backspace</Code> for respective keys and
|
||||
the typed-in character otherwise including <Code>' '</Code>
|
||||
for space. Modifier keys (e.g., <Code>shiftKey</Code>) are also included in the{' '}
|
||||
<Code>nativeEvent</Code>. Fires before <Code>onChange</Code> callbacks.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description="Invoked on mount and layout changes with {x, y, width, height}."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onSelectionChange"
|
||||
@@ -228,49 +244,46 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
example={{
|
||||
render: () => <PropOnSelectionChange />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onSubmitEditing"
|
||||
typeInfo="?function"
|
||||
description="Callback that is called when the keyboard's submit button is pressed. When multiline={true}, this is only called if blurOnSubmit={true}."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="placeholder"
|
||||
typeInfo="?string"
|
||||
description="The string that will be rendered in an empty `TextInput` before text has been entered."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropPlaceholder />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="secureTextEntry"
|
||||
typeInfo="?boolean = false"
|
||||
description="If true, the text input obscures the text entered so that sensitive text like passwords stay secure. (Not available when `multiline` is `true`.)"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropSecureTextEntry />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="selection"
|
||||
typeInfo="?{ start: number, end: ?number }"
|
||||
description="The start and end of the text input's selection. Set start and end to the same value to position the cursor."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="selectTextOnFocus"
|
||||
typeInfo="?boolean = false"
|
||||
description="If `true`, all text will automatically be selected on focus."
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropSelectTextOnFocus />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
@@ -289,7 +302,7 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
]}
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="value"
|
||||
@@ -304,48 +317,44 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
href="https://facebook.github.io/react/docs/forms.html"
|
||||
target="_blank"
|
||||
/>{' '}
|
||||
work. To prevent
|
||||
user edits to the value set <Code>{'editable={false}'}</Code>.
|
||||
work. To prevent user edits to the value set <Code>{'editable={false}'}</Code>.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
<Section title="Instance methods">
|
||||
<DocItem name="blur" typeInfo="() => void" description="Blur the underlying DOM input." />
|
||||
|
||||
{
|
||||
title: 'Instance methods',
|
||||
entries: [
|
||||
<DocItem name="blur" typeInfo="() => void" description="Blur the underlying DOM input." />,
|
||||
<DocItem
|
||||
name="clear"
|
||||
typeInfo="() => void"
|
||||
description="Clear the text from the underlying DOM input."
|
||||
/>,
|
||||
<DocItem name="focus" typeInfo="() => void" description="Focus the underlying DOM input." />,
|
||||
/>
|
||||
|
||||
<DocItem name="focus" typeInfo="() => void" description="Focus the underlying DOM input." />
|
||||
|
||||
<DocItem
|
||||
name="isFocused"
|
||||
typeInfo="() => boolean"
|
||||
description="Returns `true` if the input is currently focused; `false` otherwise."
|
||||
/>
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="TextInput events"
|
||||
example={{
|
||||
render: () => <TextInputEvents />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Rewrite (<sp> to '_' with maxLength)"
|
||||
example={{
|
||||
render: () => <TextInputRewrite />
|
||||
}}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Rewrite (no spaces allowed)"
|
||||
@@ -353,15 +362,7 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
render: () => <TextInputRewriteInvalidCharacters />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('TextInput', () =>
|
||||
<UIExplorer
|
||||
description="Accessible single- and multi-line text input via a keyboard. Supports features such as auto-complete, auto-focus, placeholder text, and event callbacks. Note: some props are exclusive to or excluded from `multiline`."
|
||||
sections={sections}
|
||||
title="TextInput"
|
||||
url="components/TextInput"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('TextInput', TextInputScreen);
|
||||
@@ -87,21 +87,13 @@ class OnSelectionChangeExample extends React.Component {
|
||||
<Text>
|
||||
selection = {JSON.stringify(this.state.selection)}
|
||||
</Text>
|
||||
<Text onPress={this.placeAt(0)}>
|
||||
Place at Start (0, 0)
|
||||
</Text>
|
||||
<Text onPress={this.placeAt(0)}>Place at Start (0, 0)</Text>
|
||||
<Text onPress={this.placeAt(length)}>
|
||||
Place at End ({length}, {length})
|
||||
</Text>
|
||||
<Text onPress={this.placeAtRandom}>
|
||||
Place at Random
|
||||
</Text>
|
||||
<Text onPress={this.select(0, length)}>
|
||||
Select All
|
||||
</Text>
|
||||
<Text onPress={this.selectRandom}>
|
||||
Select Random
|
||||
</Text>
|
||||
<Text onPress={this.placeAtRandom}>Place at Random</Text>
|
||||
<Text onPress={this.select(0, length)}>Select All</Text>
|
||||
<Text onPress={this.selectRandom}>Select Random</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -53,7 +53,8 @@ export default class TextEventsExample extends React.Component {
|
||||
style={[helperStyles.textinput, { maxWidth: 200 }]}
|
||||
/>
|
||||
<Text style={styles.eventLabel}>
|
||||
{this.state.curText}{'\n'}
|
||||
{this.state.curText}
|
||||
{'\n'}
|
||||
(prev: {this.state.prevText}){'\n'}
|
||||
(prev2: {this.state.prev2Text}){'\n'}
|
||||
(prev3: {this.state.prev3Text})
|
||||
|
||||
@@ -37,7 +37,9 @@ export class WithLabel extends React.Component {
|
||||
return (
|
||||
<View style={withLabelStyles.labelContainer}>
|
||||
<View style={withLabelStyles.label}>
|
||||
<Text>{this.props.label}</Text>
|
||||
<Text>
|
||||
{this.props.label}
|
||||
</Text>
|
||||
</View>
|
||||
{this.props.children}
|
||||
</View>
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import CustomStyleOverrides from './examples/CustomStyleOverrides';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import { TouchableHighlightDisabled } from './examples/PropDisabled';
|
||||
import UIExplorer, { AppText, DocItem } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...TouchableWithoutFeedback props" />,
|
||||
|
||||
<DocItem
|
||||
name="activeOpacity"
|
||||
typeInfo="?number = 0.85"
|
||||
description="Determines what the opacity of the wrapped view should be when touch is active."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onHideUnderlay"
|
||||
typeInfo="?function"
|
||||
description="Called immediately after the underlay is hidden."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onShowUnderlay"
|
||||
typeInfo="?function"
|
||||
description="Called immediately after the underlay is shown"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="underlayColor"
|
||||
typeInfo="?color = black"
|
||||
description="The color of the underlay that will show through when the touch is active."
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
<DocItem
|
||||
description="Disabled TouchableHighlight"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <TouchableHighlightDisabled />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
description="Custom style overrides"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <CustomStyleOverrides />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('TouchableHighlight', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
A wrapper for making views respond properly to touches. On press down, the
|
||||
opacity of the wrapped view is decreased, which allows the underlay color to
|
||||
show through, darkening or tinting the view.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
The underlay comes from wrapping the child in a new View, which can affect
|
||||
layout, and sometimes cause unwanted visual artifacts if not used correctly,
|
||||
for example if the backgroundColor of the wrapped view isn't explicitly set to
|
||||
an opaque color.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
TouchableHighlight must have one child (not zero or more than one). If you wish
|
||||
to have several child components, wrap them in a View.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="TouchableHighlight"
|
||||
url="components/Touchable"
|
||||
/>
|
||||
);
|
||||
@@ -0,0 +1,92 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import CustomStyleOverrides from './examples/CustomStyleOverrides';
|
||||
import DelayEvents from './examples/DelayEvents';
|
||||
import FeedbackEvents from './examples/FeedbackEvents';
|
||||
import React from 'react';
|
||||
import { TouchableHighlightDisabled } from './examples/PropDisabled';
|
||||
import UIExplorer, { AppText, Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const TouchableHighlightScreen = () =>
|
||||
<UIExplorer title="TouchableHighlight" url="components/Touchable">
|
||||
<Description>
|
||||
<AppText>
|
||||
A wrapper for making views respond properly to touches. On press down, the opacity of the
|
||||
wrapped view is decreased, which allows the underlay color to show through, darkening or
|
||||
tinting the view.
|
||||
</AppText>
|
||||
<AppText>
|
||||
The underlay comes from wrapping the child in a new View, which can affect layout, and
|
||||
sometimes cause unwanted visual artifacts if not used correctly, for example if the
|
||||
backgroundColor of the wrapped view isn't explicitly set to an opaque color.
|
||||
</AppText>
|
||||
<AppText>
|
||||
TouchableHighlight must have one child (not zero or more than one). If you wish to have
|
||||
several child components, wrap them in a View.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...TouchableWithoutFeedback props" />
|
||||
|
||||
<DocItem
|
||||
name="activeOpacity"
|
||||
typeInfo="?number = 0.85"
|
||||
description="Determines what the opacity of the wrapped view should be when touch is active."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onHideUnderlay"
|
||||
typeInfo="?function"
|
||||
description="Called immediately after the underlay is hidden."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onShowUnderlay"
|
||||
typeInfo="?function"
|
||||
description="Called immediately after the underlay is shown"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="underlayColor"
|
||||
typeInfo="?color = black"
|
||||
description="The color of the underlay that will show through when the touch is active."
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="Disabled"
|
||||
example={{
|
||||
render: () => <TouchableHighlightDisabled />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Feedback events"
|
||||
example={{
|
||||
render: () => <FeedbackEvents touchable="highlight" />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Delay events"
|
||||
example={{
|
||||
render: () => <DelayEvents touchable="highlight" />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Custom style overrides"
|
||||
example={{
|
||||
render: () => <CustomStyleOverrides />
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('TouchableHighlight', TouchableHighlightScreen);
|
||||
@@ -4,68 +4,71 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import DelayEvents from './examples/DelayEvents';
|
||||
import FeedbackEvents from './examples/FeedbackEvents';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import { TouchableOpacityDisabled } from './examples/PropDisabled';
|
||||
import UIExplorer, { AppText, DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { AppText, Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...TouchableWithoutFeedback props" />,
|
||||
const TouchableOpacityScreen = () =>
|
||||
<UIExplorer title="TouchableOpacity" url="components/Touchable">
|
||||
<Description>
|
||||
<AppText>
|
||||
A wrapper for making views respond properly to touches. On press down, the opacity of the
|
||||
wrapped view is decreased, dimming it.
|
||||
</AppText>
|
||||
<AppText>
|
||||
Opacity is controlled by wrapping the children in an Animated.View, which is added to the
|
||||
view hiearchy. Be aware that this can affect layout.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...TouchableWithoutFeedback props" />
|
||||
|
||||
<DocItem
|
||||
name="activeOpacity"
|
||||
typeInfo="?number = 0.2"
|
||||
description="Determines what the opacity of the wrapped view should be when touch is active."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="focusedOpacity"
|
||||
typeInfo="?number = 0.7"
|
||||
description="Determines what the opacity of the wrapped view should be when it is focused."
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Instance methods',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Instance methods">
|
||||
<DocItem
|
||||
name="setOpacityTo"
|
||||
typeInfo="(value: number, duration: number) => void"
|
||||
description="Transition the touchable to a new opacity."
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="Disabled TouchableOpacity"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <TouchableOpacityDisabled />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('TouchableOpacity', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
A wrapper for making views respond properly to touches. On press down, the opacity of the
|
||||
wrapped view is decreased, dimming it.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
Opacity is controlled by wrapping the children in an Animated.View, which is added to the
|
||||
view hiearchy. Be aware that this can affect layout.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="TouchableOpacity"
|
||||
url="components/Touchable"
|
||||
/>
|
||||
);
|
||||
<DocItem
|
||||
description="Feedback events"
|
||||
example={{
|
||||
render: () => <FeedbackEvents touchable="opacity" />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Delay events"
|
||||
example={{
|
||||
render: () => <DelayEvents touchable="opacity" />
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('TouchableOpacity', TouchableOpacityScreen);
|
||||
@@ -4,17 +4,36 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import DelayEvents from './examples/DelayEvents';
|
||||
import FeedbackEvents from './examples/FeedbackEvents';
|
||||
import React from 'react';
|
||||
import PropHitSlop from './examples/PropHitSlop';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import { TouchableWithoutFeedbackDisabled } from './examples/PropDisabled';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem name="...View props" />,
|
||||
const TouchableWithoutFeedbackScreen = () =>
|
||||
<UIExplorer title="TouchableWithoutFeedback" url="components/Touchable">
|
||||
<Description>
|
||||
<AppText>
|
||||
Do not use unless you have a very good reason. All the elements that respond to press should
|
||||
have a visual feedback when touched. This is one of the primary reason a "web" app doesn't
|
||||
feel "native".
|
||||
</AppText>
|
||||
<AppText>
|
||||
NOTE: <Code>TouchableWithoutFeedback</Code> supports only one child. If you wish to have
|
||||
several child components, wrap them in a <Code>View</Code>.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem name="...View props" />
|
||||
<DocItem
|
||||
name="delayLongPress"
|
||||
typeInfo="?number"
|
||||
@@ -23,8 +42,7 @@ const sections = [
|
||||
Delay in ms, from <Code>onPressIn</Code>, before <Code>onLongPress</Code> is called.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
/>
|
||||
<DocItem
|
||||
name="delayPressIn"
|
||||
typeInfo="?number"
|
||||
@@ -33,8 +51,7 @@ const sections = [
|
||||
Delay in ms, from the start of the touch, before <Code>onPressIn</Code> is called.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
/>
|
||||
<DocItem
|
||||
name="delayPressOut"
|
||||
typeInfo="?number"
|
||||
@@ -43,28 +60,27 @@ const sections = [
|
||||
Delay in ms, from the release of the touch, before <Code>onPressOut</Code> is called.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
/>
|
||||
<DocItem
|
||||
name="disabled"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>If <Code>true</Code>, disable all interactions for this component.</AppText>
|
||||
<AppText>
|
||||
If <Code>true</Code>, disable all interactions for this component.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
example={{
|
||||
render: () => <TouchableWithoutFeedbackDisabled />
|
||||
}}
|
||||
/>
|
||||
<DocItem name="onLongPress" typeInfo="?function" />,
|
||||
|
||||
<DocItem
|
||||
name="onPress"
|
||||
typeInfo="?function"
|
||||
description="Called when the touch is released, but not if cancelled (e.g. by a scroll that steals the responder lock)."
|
||||
/>,
|
||||
|
||||
<DocItem name="onPressIn" typeInfo="?function" />,
|
||||
|
||||
<DocItem name="onPressOut" typeInfo="?function" />,
|
||||
|
||||
/>
|
||||
<DocItem name="onPressIn" typeInfo="?function" />
|
||||
<DocItem name="onPressOut" typeInfo="?function" />
|
||||
<DocItem
|
||||
name="pressRetentionOffset"
|
||||
typeInfo="?{top: number, left: number, bottom: number, right: number}"
|
||||
@@ -73,33 +89,27 @@ of the button, before deactivating the button. Once deactivated, try moving it
|
||||
back and you'll see that the button is once again reactivated! Move it back and
|
||||
forth several times while the scroll view is disabled. Ensure you pass in a
|
||||
constant to reduce memory allocations.`}
|
||||
/>,
|
||||
|
||||
/>
|
||||
<DocItem name="style" typeInfo="?style" />
|
||||
]
|
||||
},
|
||||
</Section>
|
||||
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [<DocItem description="Hit slop" example={{ render: () => <PropHitSlop /> }} />]
|
||||
}
|
||||
];
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="Feedback events"
|
||||
example={{
|
||||
render: () => <FeedbackEvents touchable="withoutFeedback" />
|
||||
}}
|
||||
/>
|
||||
|
||||
storiesOf('Components', module).add('TouchableWithoutFeedback', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
Do not use unless you have a very good reason. All the elements that respond to
|
||||
press should have a visual feedback when touched. This is one of the primary
|
||||
reason a "web" app doesn't feel "native".
|
||||
</AppText>,
|
||||
<AppText>
|
||||
NOTE: <Code>TouchableWithoutFeedback</Code> supports only one child. If you wish to have
|
||||
several child components, wrap them in a <Code>View</Code>.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="TouchableWithoutFeedback"
|
||||
url="components/Touchable"
|
||||
/>
|
||||
);
|
||||
<DocItem
|
||||
description="Delay events"
|
||||
example={{
|
||||
render: () => <DelayEvents touchable="withoutFeedback" />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem description="Hit slop" example={{ render: () => <PropHitSlop /> }} />
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('Components', module).add('TouchableWithoutFeedback', TouchableWithoutFeedbackScreen);
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { oneOf } from 'prop-types';
|
||||
import React, { PureComponent } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableOpacity,
|
||||
TouchableWithoutFeedback,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
const Touchables = {
|
||||
highlight: TouchableHighlight,
|
||||
opacity: TouchableOpacity,
|
||||
withoutFeedback: TouchableWithoutFeedback
|
||||
};
|
||||
|
||||
export default class TouchableDelayEvents extends PureComponent {
|
||||
static propTypes = {
|
||||
touchable: oneOf(['highlight', 'opacity', 'withoutFeedback'])
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
touchable: 'highlight'
|
||||
};
|
||||
|
||||
state = { eventLog: [] };
|
||||
|
||||
render() {
|
||||
const Touchable = Touchables[this.props.touchable];
|
||||
const { displayName } = Touchable;
|
||||
return (
|
||||
<View>
|
||||
<View>
|
||||
<Touchable
|
||||
delayLongPress={800}
|
||||
delayPressIn={400}
|
||||
delayPressOut={1000}
|
||||
onLongPress={this._createPressHandler('longPress: 800ms delay')}
|
||||
onPress={this._createPressHandler('press')}
|
||||
onPressIn={this._createPressHandler('pressIn: 400ms delay')}
|
||||
onPressOut={this._createPressHandler('pressOut: 1000ms delay')}
|
||||
>
|
||||
<View>
|
||||
<Text style={styles.touchableText}>
|
||||
{displayName}
|
||||
</Text>
|
||||
</View>
|
||||
</Touchable>
|
||||
</View>
|
||||
<View style={styles.eventLogBox}>
|
||||
{this.state.eventLog.map((e, ii) =>
|
||||
<Text key={ii}>
|
||||
{e}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_createPressHandler = eventName => {
|
||||
return () => {
|
||||
const limit = 6;
|
||||
this.setState(state => {
|
||||
const eventLog = state.eventLog.slice(0, limit - 1);
|
||||
eventLog.unshift(eventName);
|
||||
return { eventLog };
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
touchableText: {
|
||||
borderRadius: 8,
|
||||
padding: 5,
|
||||
borderWidth: 1,
|
||||
borderColor: 'black',
|
||||
color: '#007AFF',
|
||||
borderStyle: 'solid',
|
||||
textAlign: 'center'
|
||||
},
|
||||
eventLogBox: {
|
||||
padding: 10,
|
||||
marginTop: 10,
|
||||
height: 120,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderColor: '#f0f0f0',
|
||||
backgroundColor: '#f9f9f9'
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { oneOf } from 'prop-types';
|
||||
import React, { PureComponent } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableOpacity,
|
||||
TouchableWithoutFeedback,
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
const Touchables = {
|
||||
highlight: TouchableHighlight,
|
||||
opacity: TouchableOpacity,
|
||||
withoutFeedback: TouchableWithoutFeedback
|
||||
};
|
||||
|
||||
export default class TouchableFeedbackEvents extends PureComponent {
|
||||
static propTypes = {
|
||||
touchable: oneOf(['highlight', 'opacity', 'withoutFeedback'])
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
touchable: 'highlight'
|
||||
};
|
||||
|
||||
state = { eventLog: [] };
|
||||
|
||||
render() {
|
||||
const Touchable = Touchables[this.props.touchable];
|
||||
return (
|
||||
<View>
|
||||
<View>
|
||||
<Touchable
|
||||
onLongPress={this._createPressHandler('longPress')}
|
||||
onPress={this._createPressHandler('press')}
|
||||
onPressIn={this._createPressHandler('pressIn')}
|
||||
onPressOut={this._createPressHandler('pressOut')}
|
||||
>
|
||||
<View>
|
||||
<Text style={styles.touchableText}>Press Me</Text>
|
||||
</View>
|
||||
</Touchable>
|
||||
</View>
|
||||
<View style={styles.eventLogBox}>
|
||||
{this.state.eventLog.map((e, ii) =>
|
||||
<Text key={ii}>
|
||||
{e}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_createPressHandler = eventName => {
|
||||
return () => {
|
||||
const limit = 6;
|
||||
this.setState(state => {
|
||||
const eventLog = state.eventLog.slice(0, limit - 1);
|
||||
eventLog.unshift(eventName);
|
||||
return { eventLog };
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
touchableText: {
|
||||
borderRadius: 8,
|
||||
padding: 5,
|
||||
borderWidth: 1,
|
||||
borderColor: 'black',
|
||||
color: '#007AFF',
|
||||
borderStyle: 'solid',
|
||||
textAlign: 'center'
|
||||
},
|
||||
eventLogBox: {
|
||||
padding: 10,
|
||||
marginTop: 10,
|
||||
height: 120,
|
||||
borderWidth: StyleSheet.hairlineWidth,
|
||||
borderColor: '#f0f0f0',
|
||||
backgroundColor: '#f9f9f9'
|
||||
}
|
||||
});
|
||||
@@ -3,8 +3,18 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { action } from '@kadira/storybook';
|
||||
import { StyleSheet, View, Text, TouchableHighlight, TouchableOpacity } from 'react-native';
|
||||
import {
|
||||
StyleSheet,
|
||||
View,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableOpacity,
|
||||
TouchableWithoutFeedback
|
||||
} from 'react-native';
|
||||
|
||||
const action = msg => () => {
|
||||
console.log(msg);
|
||||
};
|
||||
|
||||
class TouchableHighlightDisabled extends React.Component {
|
||||
render() {
|
||||
@@ -17,9 +27,7 @@ class TouchableHighlightDisabled extends React.Component {
|
||||
style={[styles.row, styles.block]}
|
||||
underlayColor="rgb(210, 230, 255)"
|
||||
>
|
||||
<Text style={styles.disabledButton}>
|
||||
Disabled TouchableHighlight
|
||||
</Text>
|
||||
<Text style={styles.disabledButton}>Disabled TouchableHighlight</Text>
|
||||
</TouchableHighlight>
|
||||
|
||||
<TouchableHighlight
|
||||
@@ -28,9 +36,7 @@ class TouchableHighlightDisabled extends React.Component {
|
||||
style={[styles.row, styles.block]}
|
||||
underlayColor="rgb(210, 230, 255)"
|
||||
>
|
||||
<Text style={styles.button}>
|
||||
Enabled TouchableHighlight
|
||||
</Text>
|
||||
<Text style={styles.button}>Enabled TouchableHighlight</Text>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
@@ -61,7 +67,27 @@ class TouchableOpacityDisabled extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export { TouchableHighlightDisabled, TouchableOpacityDisabled };
|
||||
class TouchableWithoutFeedbackDisabled extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<TouchableWithoutFeedback disabled={true} onPress={action('TouchableWithoutFeedback')}>
|
||||
<View style={[styles.row, styles.block]}>
|
||||
<Text style={styles.disabledButton}>Disabled TouchableWithoutFeedback</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
|
||||
<TouchableWithoutFeedback disabled={false} onPress={action('TouchableWithoutFeedback')}>
|
||||
<View style={[styles.row, styles.block]}>
|
||||
<Text style={styles.button}>Enabled TouchableWithoutFeedback</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { TouchableHighlightDisabled, TouchableOpacityDisabled, TouchableWithoutFeedbackDisabled };
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
@@ -70,12 +96,5 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
block: {
|
||||
padding: 10
|
||||
},
|
||||
button: {
|
||||
color: '#007AFF'
|
||||
},
|
||||
disabledButton: {
|
||||
color: '#007AFF',
|
||||
opacity: 0.5
|
||||
}
|
||||
});
|
||||
|
||||
@@ -39,7 +39,9 @@ export default class TouchableHitSlopExample extends React.Component {
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.logBox}>
|
||||
<Text>{log}</Text>
|
||||
<Text>
|
||||
{log}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -17,92 +17,6 @@ import {
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
class TouchableFeedbackEvents extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { eventLog: [] };
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View testID="touchable_feedback_events">
|
||||
<View style={[styles.row, { justifyContent: 'center' }]}>
|
||||
<TouchableOpacity
|
||||
accessibilityComponentType="button"
|
||||
accessibilityLabel="touchable feedback events"
|
||||
accessibilityTraits="button"
|
||||
onLongPress={this._createPressHandler('longPress')}
|
||||
onPress={this._createPressHandler('press')}
|
||||
onPressIn={this._createPressHandler('pressIn')}
|
||||
onPressOut={this._createPressHandler('pressOut')}
|
||||
style={styles.wrapper}
|
||||
testID="touchable_feedback_events_button"
|
||||
>
|
||||
<Text style={styles.button}>
|
||||
Press Me
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.eventLogBox} testID="touchable_feedback_events_console">
|
||||
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_createPressHandler = eventName => {
|
||||
return () => {
|
||||
const limit = 6;
|
||||
const eventLog = this.state.eventLog.slice(0, limit - 1);
|
||||
eventLog.unshift(eventName);
|
||||
this.setState({ eventLog });
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
class TouchableDelayEvents extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { eventLog: [] };
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View testID="touchable_delay_events">
|
||||
<View style={[styles.row, { justifyContent: 'center' }]}>
|
||||
<TouchableOpacity
|
||||
delayLongPress={800}
|
||||
delayPressIn={400}
|
||||
delayPressOut={1000}
|
||||
onLongPress={this._createPressHandler('longPress - 800ms delay')}
|
||||
onPress={this._createPressHandler('press')}
|
||||
onPressIn={this._createPressHandler('pressIn - 400ms delay')}
|
||||
onPressOut={this._createPressHandler('pressOut - 1000ms delay')}
|
||||
style={styles.wrapper}
|
||||
testID="touchable_delay_events_button"
|
||||
>
|
||||
<Text style={styles.button}>
|
||||
Press Me
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.eventLogBox} testID="touchable_delay_events_console">
|
||||
{this.state.eventLog.map((e, ii) => <Text key={ii}>{e}</Text>)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_createPressHandler = eventName => {
|
||||
return () => {
|
||||
const limit = 6;
|
||||
const eventLog = this.state.eventLog.slice(0, limit - 1);
|
||||
eventLog.unshift(eventName);
|
||||
this.setState({ eventLog });
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const heartImage = { uri: 'https://pbs.twimg.com/media/BlXBfT3CQAA6cVZ.png:small' };
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
@@ -214,33 +128,5 @@ const examples = [
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Touchable feedback events',
|
||||
description:
|
||||
'<Touchable*> components accept onPress, onPressIn, ' +
|
||||
'onPressOut, and onLongPress as props.',
|
||||
render() {
|
||||
return <TouchableFeedbackEvents />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Touchable delay for events',
|
||||
description:
|
||||
'<Touchable*> components also accept delayPressIn, ' +
|
||||
'delayPressOut, and delayLongPress as props. These props impact the ' +
|
||||
'timing of feedback events.',
|
||||
render() {
|
||||
return <TouchableDelayEvents />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Disabled Touchable*',
|
||||
description:
|
||||
'<Touchable*> components accept disabled prop which prevents ' +
|
||||
'any interaction with component',
|
||||
render() {
|
||||
return <TouchableDisabled />;
|
||||
}
|
||||
}
|
||||
];
|
||||
*/
|
||||
|
||||
@@ -8,10 +8,296 @@ import PropPointerEvents from './examples/PropPointerEvents';
|
||||
import transformExamples from './examples/transforms';
|
||||
import ZIndexExample from './examples/ZIndex';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem, StyleList } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
ExternalLink,
|
||||
Section,
|
||||
storiesOf,
|
||||
StyleList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const ViewScreen = () =>
|
||||
<UIExplorer title="View" url="components/View">
|
||||
<Description>
|
||||
<AppText>
|
||||
View is the fundamental UI building block. It is a component that supports style, layout
|
||||
with flexbox, and accessibility controls. It can be nested inside another View and has
|
||||
0-to-many children of any type.
|
||||
</AppText>
|
||||
<AppText>
|
||||
Also, refer to React Native's documentation about the Gesture Responder System. NOTE: View
|
||||
will transfer all other props to the rendered HTML element.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Props">
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description="Overrides the text that's read by a screen reader when the user interacts with the element. (This is implemented using 'aria-label'.)"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="accessibilityLiveRegion"
|
||||
typeInfo="?enum('assertive', 'none', 'polite')"
|
||||
description={
|
||||
<AppText>
|
||||
Indicates to assistive technologies whether to notify the user when the view changes.
|
||||
The values of this attribute are expressed in degrees of importance. When regions are
|
||||
specified as <Code>polite</Code> (recommended), updates take low priority. When regions
|
||||
are specified as <Code>assertive</Code>, assistive technologies will interrupt and
|
||||
immediately notify the user. (This is implemented using 'aria-live'.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="accessibilityRole"
|
||||
typeInfo="?enum(roles)"
|
||||
description={
|
||||
<AppText>
|
||||
Allows assistive technologies to present and support interaction with the view in a
|
||||
manner that is consistent with user expectations for similar views of that type. For
|
||||
example, marking a touchable view with an <Code>accessibilityRole</Code> of{' '}
|
||||
<Code>button</Code>. For compatibility with React Native{' '}
|
||||
<Code>accessibilityTraits</Code> and <Code>accessibilityComponentType</Code> are mapped
|
||||
to <Code>accessibilityRole</Code>. (This is implemented using ARIA roles.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="accessible"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>
|
||||
When <Code>true</Code>, indicates that the view is an accessibility element (i.e.,
|
||||
focusable) and groups its child content. By default, all the touchable elements and
|
||||
elements with <Code>accessibilityRole</Code> of <Code>button</Code> and{' '}
|
||||
<Code>link</Code> are accessible. (This is implemented using 'tabindex'.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem name="children" typeInfo="?element" description="Child content" />
|
||||
|
||||
<DocItem
|
||||
name="hitSlop"
|
||||
typeInfo="?object"
|
||||
description={[
|
||||
<AppText>
|
||||
This defines how far a touch event can start away from the view (in pixels). Typical
|
||||
interface guidelines recommend touch targets that are at least 30 - 40
|
||||
points/density-independent pixels.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
For example, if a touchable view has a height of <Code>20</Code> the touchable height
|
||||
can be extended to <Code>40</Code> with hitSlop.
|
||||
</AppText>
|
||||
]}
|
||||
example={{
|
||||
code: '<View hitSlop={{top: 10, bottom: 10, left: 0, right: 0}} />'
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="importantForAccessibility"
|
||||
typeInfo="?enum('auto', 'no', 'no-hide-descendants', 'yes')"
|
||||
description={[
|
||||
<AppText>
|
||||
A value of <Code>no</Code> will remove the element from the tab flow.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
A value of <Code>no-hide-descendants</Code> will hide the element and its children from
|
||||
assistive technologies. (This is implemented using 'aria-hidden'.)
|
||||
</AppText>
|
||||
]}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
Invoked on mount and layout changes with{' '}
|
||||
<Code>{'{ nativeEvent: { layout: { x, y, width, height } } }'}</Code>, where{' '}
|
||||
<Code>x</Code> and <Code>y</Code> are the offsets from the parent node.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onMoveShouldSetResponder"
|
||||
typeInfo="?function => boolean"
|
||||
description={
|
||||
<AppText>
|
||||
Does this view want to "claim" touch responsiveness? This is called for every touch move
|
||||
on the <Code>View</Code> when it is not the responder.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onMoveShouldSetResponderCapture"
|
||||
typeInfo="?function => boolean"
|
||||
description={
|
||||
<AppText>
|
||||
If a parent <Code>View</Code> wants to prevent a child <Code>View</Code> from becoming
|
||||
responder on a move, it should have this handler return <Code>true</Code>.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onResponderGrant"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
The <Code>View</Code> is now responding to touch events. This is the time to highlight
|
||||
and show the user what is happening. For most touch interactions, you'll simply want to
|
||||
wrap your component in <Code>TouchableHighlight</Code> or <Code>TouchableOpacity</Code>.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onResponderMove"
|
||||
typeInfo="?function"
|
||||
description="The user is moving their finger."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onResponderReject"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
Another responder is already active and will not release it to the <Code>View</Code>{' '}
|
||||
asking to be the responder.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onResponderRelease"
|
||||
typeInfo="?function"
|
||||
description="Fired at the end of the touch."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onResponderTerminate"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
The responder has been taken from the <Code>View</Code>.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onResponderTerminationRequest"
|
||||
typeInfo="?function"
|
||||
description={
|
||||
<AppText>
|
||||
Some other <Code>View</Code> wants to become responder and is asking this{' '}
|
||||
<Code>View</Code> to release its responder. Returning <Code>true</Code> allows its
|
||||
release.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onStartShouldSetResponder"
|
||||
typeInfo="?function => boolean"
|
||||
description="Does this view want to become responder on the start of a touch?"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="onStartShouldSetResponderCapture"
|
||||
typeInfo="?function => boolean"
|
||||
description={
|
||||
<AppText>
|
||||
If a parent <Code>View</Code> wants to prevent a child <Code>View</Code> from becoming
|
||||
the responder on a touch start, it should have this handler return <Code>true</Code>.
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="pointerEvents"
|
||||
typeInfo="?enum('auto', 'box-only', 'box-none', 'none') = 'auto'"
|
||||
description={
|
||||
<AppText>
|
||||
Controls whether the View can be the target of touch events. The enhanced{' '}
|
||||
<Code>pointerEvents</Code> modes provided are not part of the CSS spec, therefore,{' '}
|
||||
<Code>pointerEvents</Code> is excluded from <Code>style</Code>.
|
||||
<Code>box-none</Code> preserves pointer events on the element's children;{' '}
|
||||
<Code>box-only</Code> disables pointer events on the element's children.
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
render: () => <PropPointerEvents />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
typeInfo="?style"
|
||||
description={<StyleList stylePropTypes={stylePropTypes} />}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests. The test ID is rendered to a 'data-testid' DOM attribute"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="compat"
|
||||
name="accessibilityComponentType"
|
||||
typeInfo="?enum(roles)"
|
||||
description={
|
||||
<AppText>
|
||||
(For compatibility with React Native. Equivalent to <Code>accessibilityRole</Code>.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="compat"
|
||||
name="accessibilityTraits"
|
||||
typeInfo="?enum(roles) | Array<role>"
|
||||
description={
|
||||
<AppText>
|
||||
(For compatibility with React Native. Equivalent to <Code>accessibilityRole</Code>.)
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section title="More examples">
|
||||
<DocItem
|
||||
description="z-index"
|
||||
example={{
|
||||
render: () => <ZIndexExample />
|
||||
}}
|
||||
/>
|
||||
{transformExamples.map(({ title, render }, i) =>
|
||||
<DocItem description={title} key={i} example={{ render }} />
|
||||
)}
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
const stylePropTypes = [
|
||||
{
|
||||
label: 'web',
|
||||
name: (
|
||||
<ExternalLink href="https://drafts.csswg.org/css-variables/">Custom properties</ExternalLink>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: 'alignContent',
|
||||
typeInfo: 'string'
|
||||
@@ -463,6 +749,11 @@ const stylePropTypes = [
|
||||
name: 'shadowRadius',
|
||||
typeInfo: 'number | string'
|
||||
},
|
||||
{
|
||||
label: 'web',
|
||||
name: 'touchAction',
|
||||
typeInfo: 'string'
|
||||
},
|
||||
{
|
||||
name: 'top',
|
||||
typeInfo: 'number | string'
|
||||
@@ -521,228 +812,4 @@ const stylePropTypes = [
|
||||
}
|
||||
];
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Props',
|
||||
entries: [
|
||||
<DocItem
|
||||
name="accessibilityLabel"
|
||||
typeInfo="?string"
|
||||
description="Overrides the text that's read by a screen reader when the user interacts with the element. (This is implemented using 'aria-label'.)"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="accessibilityLiveRegion"
|
||||
typeInfo="?enum('assertive', 'none', 'polite')"
|
||||
description={
|
||||
<AppText>
|
||||
Indicates to assistive technologies whether to notify the user when the view changes.
|
||||
The values of
|
||||
this attribute are expressed in degrees of importance. When regions are specified as{
|
||||
' '
|
||||
}
|
||||
<Code>polite</Code> (recommended),
|
||||
updates take low priority. When regions are specified as <Code>assertive</Code>,
|
||||
assistive technologies will
|
||||
interrupt and immediately notify the user. (This is implemented using 'aria-live'.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
name="accessibilityRole"
|
||||
typeInfo="?enum(roles)"
|
||||
description={
|
||||
<AppText>
|
||||
Allows assistive technologies to present and support interaction with the view in a
|
||||
manner that is
|
||||
consistent with user expectations for similar views of that type. For example, marking a
|
||||
touchable
|
||||
view with an <Code>accessibilityRole</Code> of <Code>button</Code>. For compatibility
|
||||
with React
|
||||
Native <Code>accessibilityTraits</Code> and <Code>accessibilityComponentType</Code> are
|
||||
mapped
|
||||
to <Code>accessibilityRole</Code>. (This is implemented using ARIA roles.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="accessible"
|
||||
typeInfo="?boolean"
|
||||
description={
|
||||
<AppText>
|
||||
When <Code>true</Code>, indicates that the view is an accessibility element (i.e.,
|
||||
focusable) and
|
||||
groups its child content. By default, all the touchable elements and elements
|
||||
with <Code>accessibilityRole</Code> of <Code>button</Code> and <Code>link</Code> are
|
||||
accessible.
|
||||
(This is implemented using 'tabindex'.)
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem name="children" typeInfo="?element" description="Child content" />,
|
||||
|
||||
<DocItem
|
||||
name="hitSlop"
|
||||
typeInfo="?object"
|
||||
description={
|
||||
'This defines how far a touch event can start away from the view (in pixels). Typical interface guidelines recommend touch targets that are at least 30 - 40 points/density-independent pixels.\n\nFor example, if a touchable view has a height of `20` the touchable height can be extended to `40` with hitSlop.'
|
||||
}
|
||||
example={{
|
||||
code: '<View hitSlop={{top: 10, bottom: 10, left: 0, right: 0}} />',
|
||||
render: () => null
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="importantForAccessibility"
|
||||
typeInfo="?enum('auto', 'no', 'no-hide-descendants', 'yes')"
|
||||
description={
|
||||
'A value of `no` will remove the element from the tab flow.\n\nA value of `no-hide-descendants` will hide the element and its children from assistive technologies. (This is implemented using `aria-hidden`.)'
|
||||
}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onLayout"
|
||||
typeInfo="?function"
|
||||
description="Invoked on mount and layout changes with `{ nativeEvent: { layout: { x, y, width, height } } }`, where `x` and `y` are the offsets from the parent node."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onMoveShouldSetResponder"
|
||||
typeInfo="?function => boolean"
|
||||
description="Does this view want to "claim" touch responsiveness? This is called for every touch move on the `View` when it is not the responder."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onMoveShouldSetResponderCapture"
|
||||
typeInfo="?function => boolean"
|
||||
description="If a parent `View` wants to prevent a child `View` from becoming responder on a move, it should have this handler return `true`."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onResponderGrant"
|
||||
typeInfo="?function"
|
||||
description="The `View` is now responding to touch events. This is the time to highlight and show the user what is happening. For most touch interactions, you'll simply want to wrap your component in `TouchableHighlight` or `TouchableOpacity`."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onResponderMove"
|
||||
typeInfo="?function"
|
||||
description="The user is moving their finger."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onResponderReject"
|
||||
typeInfo="?function"
|
||||
description="Another responder is already active and will not release it to the `View` asking to be the responder."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onResponderRelease"
|
||||
typeInfo="?function"
|
||||
description="Fired at the end of the touch."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onResponderTerminate"
|
||||
typeInfo="?function"
|
||||
description="The responder has been taken from the `View`."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onResponderTerminationRequest"
|
||||
typeInfo="?function"
|
||||
description="Some other `View` wants to become responder and is asking this `View` to release its responder. Returning `true` allows its release."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onStartShouldSetResponder"
|
||||
typeInfo="?function => boolean"
|
||||
description="Does this view want to become responder on the start of a touch?"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="onStartShouldSetResponderCapture"
|
||||
typeInfo="?function => boolean"
|
||||
description="If a parent `View` wants to prevent a child `View` from becoming the responder on a touch start, it should have this handler return `true`."
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="pointerEvents"
|
||||
typeInfo="?enum('auto', 'box-only', 'box-none', 'none') = 'auto'"
|
||||
description="Controls whether the View can be the target of touch events. The enhanced `pointerEvents` modes provided are not part of the CSS spec, therefore, `pointerEvents` is excluded from `style`. `box-none` preserves pointer events on the element's children; `box-only` disables pointer events on the element's children"
|
||||
example={{
|
||||
code: '',
|
||||
render: () => <PropPointerEvents />
|
||||
}}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="style"
|
||||
typeInfo="?style"
|
||||
description={<StyleList stylePropTypes={stylePropTypes} />}
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
name="testID"
|
||||
typeInfo="?string"
|
||||
description="Used to locate this view in end-to-end tests. The test ID is rendered to a `data-testid` DOM attribute"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
label="compat"
|
||||
name="accessibilityComponentType"
|
||||
typeInfo="?enum(roles)"
|
||||
description="(For compatibility with React Native. Equivalent to "accessibilityRole".)"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
label="compat"
|
||||
name="accessibilityTraits"
|
||||
typeInfo="?enum(roles) | Array<role>"
|
||||
description="(For compatibility with React Native. Equivalent to "accessibilityRole".)"
|
||||
/>
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
title: 'More examples',
|
||||
entries: [
|
||||
<DocItem
|
||||
description="z-index"
|
||||
example={{
|
||||
render: () => <ZIndexExample />
|
||||
}}
|
||||
/>
|
||||
].concat(
|
||||
transformExamples.map(({ title, render }) =>
|
||||
<DocItem description={title} example={{ render }} />
|
||||
)
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('Components', module).add('View', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
View is the fundamental UI building block. It is a component that supports style, layout
|
||||
with flexbox,
|
||||
and accessibility controls. It can be nested inside another View and has 0-to-many children
|
||||
of any type.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
Also, refer to React Native's documentation about the Gesture Responder System. NOTE: View
|
||||
will
|
||||
transfer all other props to the rendered HTML element.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="View"
|
||||
url="components/View"
|
||||
/>
|
||||
);
|
||||
storiesOf('Components', module).add('View', ViewScreen);
|
||||
@@ -9,7 +9,9 @@ import { Text, TouchableHighlight, View } from 'react-native';
|
||||
const ViewStyleExample = () =>
|
||||
<View pointerEvents="box-none">
|
||||
<View pointerEvents="box-none">
|
||||
<View pointerEvents="none"><Text onPress={logger}>none</Text></View>
|
||||
<View pointerEvents="none">
|
||||
<Text onPress={logger}>none</Text>
|
||||
</View>
|
||||
<TouchableHighlight onPress={logger} pointerEvents="auto">
|
||||
<Text>auto</Text>
|
||||
</TouchableHighlight>
|
||||
|
||||
@@ -22,7 +22,9 @@ export default class ZIndex extends React.Component {
|
||||
{ marginTop: 0, backgroundColor: '#E57373', zIndex: indices[0] }
|
||||
]}
|
||||
>
|
||||
<Text>ZIndex {indices[0]}</Text>
|
||||
<Text>
|
||||
ZIndex {indices[0]}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
@@ -30,7 +32,9 @@ export default class ZIndex extends React.Component {
|
||||
{ marginLeft: 50, backgroundColor: '#FFF176', zIndex: indices[1] }
|
||||
]}
|
||||
>
|
||||
<Text>ZIndex {indices[1]}</Text>
|
||||
<Text>
|
||||
ZIndex {indices[1]}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
@@ -38,7 +42,9 @@ export default class ZIndex extends React.Component {
|
||||
{ marginLeft: 100, backgroundColor: '#81C784', zIndex: indices[2] }
|
||||
]}
|
||||
>
|
||||
<Text>ZIndex {indices[2]}</Text>
|
||||
<Text>
|
||||
ZIndex {indices[2]}
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
@@ -46,7 +52,9 @@ export default class ZIndex extends React.Component {
|
||||
{ marginLeft: 150, backgroundColor: '#64B5F6', zIndex: indices[3] }
|
||||
]}
|
||||
>
|
||||
<Text>ZIndex {indices[3]}</Text>
|
||||
<Text>
|
||||
ZIndex {indices[3]}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
|
||||
@@ -64,9 +64,7 @@ class Flip extends React.Component {
|
||||
}
|
||||
]}
|
||||
>
|
||||
<Text style={styles.flipText}>
|
||||
This text is flipping great.
|
||||
</Text>
|
||||
<Text style={styles.flipText}>This text is flipping great.</Text>
|
||||
</Animated.View>
|
||||
<Animated.View
|
||||
style={[
|
||||
@@ -87,9 +85,7 @@ class Flip extends React.Component {
|
||||
}
|
||||
]}
|
||||
>
|
||||
<Text style={styles.flipText}>
|
||||
On the flip side...
|
||||
</Text>
|
||||
<Text style={styles.flipText}>On the flip side...</Text>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -3,64 +3,83 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
const AppRegistryScreen = () =>
|
||||
<UIExplorer title="AppRegistry" url="apis/AppRegistry">
|
||||
<Description>
|
||||
<AppText>
|
||||
AppRegistry is the control point for registering, running, prerendering, and unmounting all
|
||||
apps. App root components should register themselves with{' '}
|
||||
<Code>AppRegistry.registerComponent</Code>. Apps can be run by invoking{' '}
|
||||
<Code>AppRegistry.runApplication</Code>
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
description="Returns the given application's element and stylesheets. Use this for server-side rendering."
|
||||
label="web"
|
||||
name="static getApplication"
|
||||
typeInfo="(appKey: string, appParameters: ?object) => { element: ReactElement; stylesheets: Array<ReactElement> }"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={[
|
||||
<AppText>
|
||||
Register multiple applications. <Code>AppConfig</Code> type is:
|
||||
</AppText>,
|
||||
<Code>{`{
|
||||
appKey: string;
|
||||
component: ComponentProvider;
|
||||
run?: function
|
||||
}`}</Code>
|
||||
]}
|
||||
name="static registerConfig"
|
||||
typeInfo="(config: Array<AppConfig>) => avoid"
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
Register multiple applications. <Code>AppConfig</Code> is of type
|
||||
<Code>{'{ appKey: string; component: ComponentProvider; run?: Function }'}</Code>.
|
||||
Register a component provider under the given <Code>appKey</Code>.
|
||||
</AppText>
|
||||
}
|
||||
name="static registerConfig"
|
||||
typeInfo="(config: Array<AppConfig>) => avoid"
|
||||
/>,
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>Register a component provider under the given <Code>appKey</Code>.</AppText>
|
||||
}
|
||||
example={{
|
||||
code: 'AppRegistry.registerComponent("MyApp", () => AppComponent)'
|
||||
}}
|
||||
name="static registerComponent"
|
||||
typeInfo="(appKey: string, getComponentFunc: ComponentProvider) => void"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
Register a custom render function for an application. The
|
||||
function will receive the <Code>appParameters</Code> passed
|
||||
to <Code>runApplication</Code>.
|
||||
Register a custom render function for an application. The function will receive the{' '}
|
||||
<Code>appParameters</Code> passed to <Code>runApplication</Code>.
|
||||
</AppText>
|
||||
}
|
||||
name="static registerRunnable"
|
||||
typeInfo="(appKey: string, run: Function) => void"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Returns all registered app keys"
|
||||
name="static getAppKeys"
|
||||
typeInfo="() => Array<string>"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
Runs the application that was registered under <Code>appKey</Code>. The
|
||||
Runs the application that was registered under <Code>appKey</Code>. The{' '}
|
||||
<Code>appParameters</Code> must include the <Code>rootTag</Code> into which the
|
||||
application is rendered, and optionally any <Code>initialProps</Code>.
|
||||
</AppText>
|
||||
@@ -73,7 +92,7 @@ const sections = [
|
||||
}}
|
||||
name="static runApplication"
|
||||
typeInfo="(appKey: string, appParameters?: object) => void"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
@@ -86,22 +105,7 @@ const sections = [
|
||||
name="static unmountApplicationComponentAtRootTag"
|
||||
typeInfo="(rootTag: HTMLElement) => void"
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('AppRegistry', () =>
|
||||
<UIExplorer
|
||||
description={
|
||||
<AppText>
|
||||
AppRegistry is the control point for registering, running,
|
||||
prerendering, and unmounting all apps. App root components should
|
||||
register themselves with <Code>AppRegistry.registerComponent</Code>. Apps can be
|
||||
run by invoking <Code>AppRegistry.runApplication</Code>
|
||||
</AppText>
|
||||
}
|
||||
sections={sections}
|
||||
title="AppRegistry"
|
||||
url="apis/AppRegistry"
|
||||
/>
|
||||
);
|
||||
storiesOf('APIs', module).add('AppRegistry', AppRegistryScreen);
|
||||
@@ -6,38 +6,50 @@
|
||||
|
||||
import React from 'react';
|
||||
import StateChangesExample from './examples/StateChanges';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Properties',
|
||||
entries: [
|
||||
const AppStateScreen = () =>
|
||||
<UIExplorer title="AppState" url="apis/AppState">
|
||||
<Description>
|
||||
<AppText>
|
||||
AppState can tell you if the app is in the foreground or background, and notify you when the
|
||||
state changes. States: <Code>active</Code> (the app is running in the foreground),{' '}
|
||||
<Code>background</Code> (the app is running in the background, i.e., the user has not
|
||||
focused the app's tab).
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Properties">
|
||||
<DocItem
|
||||
name="static isAvailable"
|
||||
description="Determines whether the browser environment supports AppState."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static currentState"
|
||||
description="Returns the current state of the app: "active" or "background"."
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
name="static addEventListener"
|
||||
typeInfo="(type: string, handler: Function) => void"
|
||||
description={
|
||||
<AppText>
|
||||
Add a handler to <Code>AppState</Code> changes by listening to the
|
||||
<Code>change</Code> event type and providing the <Code>handler</Code>. The
|
||||
handler is called with the app state value.
|
||||
<Code>change</Code> event type and providing the <Code>handler</Code>. The handler is
|
||||
called with the app state value.
|
||||
</AppText>
|
||||
}
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static removeEventListener"
|
||||
@@ -49,32 +61,15 @@ const sections = [
|
||||
</AppText>
|
||||
}
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Example',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Example">
|
||||
<DocItem
|
||||
example={{
|
||||
render: () => <StateChangesExample />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('AppState', () =>
|
||||
<UIExplorer
|
||||
description={
|
||||
<AppText>
|
||||
AppState can tell you if the app is in the foreground or background,
|
||||
and notify you when the state changes. States: <Code>active</Code> (the app is
|
||||
running in the foreground), <Code>background</Code> (the app is running in the
|
||||
background, i.e., the user has not focused the app's tab).
|
||||
</AppText>
|
||||
}
|
||||
sections={sections}
|
||||
title="AppState"
|
||||
url="apis/AppState"
|
||||
/>
|
||||
);
|
||||
storiesOf('APIs', module).add('AppState', AppStateScreen);
|
||||
@@ -30,9 +30,15 @@ export default class StateChanges extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text>Active count: {this.state.active}</Text>
|
||||
<Text>Background count: {this.state.background}</Text>
|
||||
<Text>Current state is: {this.state.currentState}</Text>
|
||||
<Text>
|
||||
Active count: {this.state.active}
|
||||
</Text>
|
||||
<Text>
|
||||
Background count: {this.state.background}
|
||||
</Text>
|
||||
<Text>
|
||||
Current state is: {this.state.currentState}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,49 +3,72 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
const AsyncStorageScreen = () =>
|
||||
<UIExplorer title="AsyncStorage" url="apis/AsyncStorage">
|
||||
<Description>
|
||||
<AppText>
|
||||
AsyncStorage is a simple, unencrypted, asynchronous, persistent, key-value storage system
|
||||
that is global to the domain. It's a facade over, and should be used instead of{' '}
|
||||
<Code>window.localStorage</Code> to provide an asynchronous API and multi functions. Each
|
||||
method returns a <Code>Promise</Code> object.
|
||||
</AppText>
|
||||
<AppText>
|
||||
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.
|
||||
</AppText>
|
||||
<AppText>
|
||||
The batched functions are useful for executing a lot of operations at once, allowing for
|
||||
optimizations to provide the convenience of a single promise after all operations are
|
||||
complete.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
Erases all AsyncStorage. You probably don't want to call this - use
|
||||
<Code>removeItem</Code> or <Code>multiRemove</Code> to clear only
|
||||
your own keys instead. Returns a Promise object.
|
||||
<Code>removeItem</Code> or <Code>multiRemove</Code> to clear only your own keys instead.
|
||||
Returns a Promise object.
|
||||
</AppText>
|
||||
}
|
||||
name="static clear"
|
||||
typeInfo="function"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Gets all known keys. Returns a Promise object."
|
||||
name="static getAllKeys"
|
||||
typeInfo=""
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Fetches the value of the given key. Returns a Promise object.."
|
||||
name="static getItem"
|
||||
typeInfo="(key: string) => {}"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Merges existing value with input value, assuming they are stringified JSON. Returns a Promise object."
|
||||
name="static mergeItem"
|
||||
typeInfo="(key: string, value: string) => {}"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
<Code>multiGet</Code> results in an array of key-value pair arrays
|
||||
that matches the input format of <Code>multiSet</Code>. Returns a
|
||||
Promise object.
|
||||
<Code>multiGet</Code> results in an array of key-value pair arrays that matches the
|
||||
input format of <Code>multiSet</Code>. Returns a Promise object.
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
@@ -53,33 +76,31 @@ const sections = [
|
||||
}}
|
||||
name="static multiGet"
|
||||
typeInfo="(keys: Array<string>) => {}"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
multiMerge takes an array of key-value array pairs that match the output of{' '}
|
||||
<Code>multiGet</Code>.
|
||||
It merges existing values with input values, assuming they are stringified JSON. Returns
|
||||
a Promise object.
|
||||
<Code>multiGet</Code>. It merges existing values with input values, assuming they are
|
||||
stringified JSON. Returns a Promise object.
|
||||
</AppText>
|
||||
}
|
||||
name="static multiMerge"
|
||||
typeInfo="(keyValuePairs: Array<Array<string>>) => {}"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Delete all the keys in the keys array. Returns a Promise object."
|
||||
name="static multiRemove"
|
||||
typeInfo="(keys: Array<string>) => {}"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
<AppText>
|
||||
<Code>multiSet</Code> takes an array of key-value array pairs that
|
||||
match the output of <Code>multiGet</Code>. Returns a Promise
|
||||
object.
|
||||
<Code>multiSet</Code> takes an array of key-value array pairs that match the output of{' '}
|
||||
<Code>multiGet</Code>. Returns a Promise object.
|
||||
</AppText>
|
||||
}
|
||||
example={{
|
||||
@@ -87,46 +108,20 @@ const sections = [
|
||||
}}
|
||||
name="static multiSet"
|
||||
typeInfo="(keyValuePairs: Array<Array<string>>) => {}"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Removes the value of the given key. Returns a Promise object."
|
||||
name="static removeItem"
|
||||
typeInfo="(key: string) => {}"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Sets the value of the given key. Returns a Promise object."
|
||||
name="static setItem"
|
||||
typeInfo="(key: string, value: string) => {}"
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('AsyncStorage', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
AsyncStorage is a simple, unencrypted, asynchronous, persistent,
|
||||
key-value storage system that is global to the domain. It's a facade
|
||||
over, and should be used instead of <Code>window.localStorage</Code> to
|
||||
provide an asynchronous API and multi functions. Each method returns
|
||||
a <Code>Promise</Code> object.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
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.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
The batched functions are useful for executing a lot of operations at
|
||||
once, allowing for optimizations to provide the convenience of a
|
||||
single promise after all operations are complete.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="AsyncStorage"
|
||||
url="apis/AsyncStorage"
|
||||
/>
|
||||
);
|
||||
storiesOf('APIs', module).add('AsyncStorage', AsyncStorageScreen);
|
||||
@@ -4,19 +4,22 @@
|
||||
|
||||
import React from 'react';
|
||||
import SetStringExample from './examples/SetString';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
const ClipboardScreen = () =>
|
||||
<UIExplorer title="Clipboard" url="apis/Clipboard">
|
||||
<Description>
|
||||
Clipboard gives you an interface for setting to the clipboard. (Getting clipboard content is
|
||||
not supported on web.)
|
||||
</Description>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
description="Determines whether the browser environment supports Clipboard at all."
|
||||
label="web"
|
||||
name="static isAvailable"
|
||||
typeInfo="() => boolean"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description={
|
||||
@@ -27,7 +30,7 @@ const sections = [
|
||||
}}
|
||||
name="static setString"
|
||||
typeInfo="(string) => boolean"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Not properly supported on Web. Returns a `Promise` of an empty string."
|
||||
@@ -35,15 +38,7 @@ const sections = [
|
||||
name="static getString"
|
||||
typeInfo="()"
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('Clipboard', () =>
|
||||
<UIExplorer
|
||||
description="Clipboard gives you an interface for setting to the clipboard. (Getting clipboard content is not supported on web.)"
|
||||
sections={sections}
|
||||
title="Clipboard"
|
||||
url="apis/Clipboard"
|
||||
/>
|
||||
);
|
||||
storiesOf('APIs', module).add('Clipboard', ClipboardScreen);
|
||||
@@ -1,33 +0,0 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import React from 'react';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
<DocItem
|
||||
name="static get"
|
||||
typeInfo="(dimension: string) => Object"
|
||||
description="Get a dimension (e.g., `window` or `screen`)."
|
||||
example={{
|
||||
code: "const { height, width } = Dimensions.get('window')"
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('APIs', module).add('Dimensions', () =>
|
||||
<UIExplorer
|
||||
description="Note: dimensions 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."
|
||||
sections={sections}
|
||||
title="Dimensions"
|
||||
/>
|
||||
);
|
||||
75
docs/storybook/2-apis/Dimensions/DimensionsScreen.js
Normal file
75
docs/storybook/2-apis/Dimensions/DimensionsScreen.js
Normal file
@@ -0,0 +1,75 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import DimensionsChange from './examples/DimensionsChange';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
TextList
|
||||
} from '../../ui-explorer';
|
||||
import React from 'react';
|
||||
|
||||
const DimensionsScreen = () =>
|
||||
<UIExplorer title="Dimensions" url="apis/Dimensions">
|
||||
<Description>
|
||||
Note: dimensions 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.
|
||||
</Description>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
name="static get"
|
||||
typeInfo="(dimension: string) => Object"
|
||||
description="Get a dimension (e.g., `window` or `screen`)."
|
||||
example={{
|
||||
code: "const { height, width } = Dimensions.get('window')"
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static set"
|
||||
typeInfo="(dimensions: ?{[key:string]: any}) => void"
|
||||
description="This should only be called server-side with an estimate
|
||||
for initial dimensions to be used when pre-rendering pages on the
|
||||
server."
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static addEventLitener"
|
||||
typeInfo="(type: string, handler: function) => void"
|
||||
description={[
|
||||
<AppText>Add an event handler. Supported events:</AppText>,
|
||||
<TextList
|
||||
items={[
|
||||
<AppText>
|
||||
<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.
|
||||
</AppText>
|
||||
]}
|
||||
/>
|
||||
]}
|
||||
example={{
|
||||
render: () => <DimensionsChange />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static removeEventLitener"
|
||||
typeInfo="(type: string, handler: function) => void"
|
||||
description="Remove an event handler."
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('Dimensions', DimensionsScreen);
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Button, Dimensions, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export default class ChangeEventExample extends Component {
|
||||
state = {
|
||||
listened: false,
|
||||
logs: []
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
Dimensions.removeEventListener('change', this._handleChange);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { logs, listened } = this.state;
|
||||
const buttonTitle = listened ? 'Remove listener' : 'Add listener';
|
||||
return (
|
||||
<View>
|
||||
<Button onPress={this.toggle} title={buttonTitle} />
|
||||
<ScrollView style={styles.logs}>
|
||||
{logs.map((log, i) =>
|
||||
<Text key={i} style={styles.log}>
|
||||
{log}
|
||||
</Text>
|
||||
)}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
const { listened } = this.state;
|
||||
if (listened) {
|
||||
Dimensions.removeEventListener('change', this._handleChange);
|
||||
this._log('Removed listener');
|
||||
} else {
|
||||
Dimensions.addEventListener('change', this._handleChange);
|
||||
this._log('Added listener');
|
||||
}
|
||||
this.setState(() => ({ listened: !listened }));
|
||||
};
|
||||
|
||||
_handleChange = ({ window, screen }) => {
|
||||
window = JSON.stringify(window, null, 2);
|
||||
screen = JSON.stringify(screen, null, 2);
|
||||
this._log(`Changed\nwindow = ${window}\nscreen = ${screen}`);
|
||||
};
|
||||
|
||||
_log = msg => {
|
||||
this.setState(state => ({
|
||||
logs: [`${new Date().toTimeString()} - ${msg}`, ...state.logs]
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
logs: {
|
||||
maxHeight: 256
|
||||
},
|
||||
log: {
|
||||
fontFamily: 'monospace, monospace',
|
||||
marginTop: 8,
|
||||
marginBottom: 8
|
||||
}
|
||||
});
|
||||
@@ -4,36 +4,33 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import RTLToggleExample from './examples/RTLToggle';
|
||||
import RTLToggle from './examples/RTLToggle';
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Properties',
|
||||
entries: [
|
||||
const I18nManagerScreen = () =>
|
||||
<UIExplorer title="I18nManager" url="apis/I18nManager">
|
||||
<Description>Control and set the layout and writing direction of the application.</Description>
|
||||
<Section title="Properties">
|
||||
<DocItem
|
||||
name="isRTL"
|
||||
typeInfo="boolean = false"
|
||||
description="Whether the application is currently in RTL mode."
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
name="static allowRTL"
|
||||
typeInfo="(allowRTL: boolean) => void"
|
||||
description="Allow the application to display in RTL mode."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="static forceRTL"
|
||||
typeInfo="(forceRTL: boolean) => void"
|
||||
description="Force the application to display in RTL mode."
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
label="web"
|
||||
@@ -41,26 +38,16 @@ const sections = [
|
||||
typeInfo="(isRTL: boolean) => void"
|
||||
description="Set the application's preferred writing direction to RTL. You will need to determine the user's preferred locale server-side (from HTTP headers) and decide whether it's an RTL language."
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Examples',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Examples">
|
||||
<DocItem
|
||||
description="Toggling LTR/RTL layout at runtime"
|
||||
example={{
|
||||
render: () => <RTLToggleExample />
|
||||
render: () => <RTLToggle />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('I18nManager', () =>
|
||||
<UIExplorer
|
||||
description="Control and set the layout and writing direction of the application."
|
||||
sections={sections}
|
||||
title="I18nManager"
|
||||
url="apis/I18nManager"
|
||||
/>
|
||||
);
|
||||
storiesOf('APIs', module).add('I18nManager', I18nManagerScreen);
|
||||
@@ -21,12 +21,8 @@ export default class RTLToggle extends PureComponent {
|
||||
The writing direction of text is automatically determined by the browser, independent of
|
||||
the global writing direction of the app.
|
||||
</Text>
|
||||
<Text style={[styles.text, styles.rtlText]}>
|
||||
أحب اللغة العربية
|
||||
</Text>
|
||||
<Text style={[styles.text, styles.textAlign]}>
|
||||
textAlign toggles
|
||||
</Text>
|
||||
<Text style={[styles.text, styles.rtlText]}>أحب اللغة العربية</Text>
|
||||
<Text style={[styles.text, styles.textAlign]}>textAlign toggles</Text>
|
||||
<View style={styles.horizontal}>
|
||||
<View style={[styles.box, { backgroundColor: 'lightblue' }]}>
|
||||
<Text>One</Text>
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { DocItem } from '../../ui-explorer';
|
||||
import OpenURLExample from './examples/OpenURL';
|
||||
import React from 'react';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
<DocItem name="canOpenURL" typeInfo="(url) => Promise<true>" />,
|
||||
|
||||
<DocItem name="getInitialURL" typeInfo="() => Promise<string>" />,
|
||||
|
||||
<DocItem
|
||||
name="openURL"
|
||||
typeInfo="(url: string) => Promise<>"
|
||||
description="Try to open the given url in a secure fashion. The method returns a Promise object. If the url opens, the promise is resolved. If not, the promise is rejected."
|
||||
example={{
|
||||
render: () => <OpenURLExample />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('APIs', module).add('Linking', () =>
|
||||
<UIExplorer
|
||||
description="Linking gives you a general interface for securely opening external URLs from JavaScript."
|
||||
sections={sections}
|
||||
title="Linking"
|
||||
url="apis/Linking"
|
||||
/>
|
||||
);
|
||||
33
docs/storybook/2-apis/Linking/LinkingScreen.js
Normal file
33
docs/storybook/2-apis/Linking/LinkingScreen.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/* eslint-disable react/jsx-sort-props */
|
||||
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import OpenURL from './examples/OpenURL';
|
||||
import React from 'react';
|
||||
import UIExplorer, { Description, DocItem, Section, storiesOf } from '../../ui-explorer';
|
||||
|
||||
const LinkingScreen = () =>
|
||||
<UIExplorer title="Linking" url="apis/Linking">
|
||||
<Description>
|
||||
Linking gives you a general interface for securely opening external URLs from JavaScript.
|
||||
</Description>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem name="canOpenURL" typeInfo="(url) => Promise<true>" />
|
||||
|
||||
<DocItem name="getInitialURL" typeInfo="() => Promise<string>" />
|
||||
|
||||
<DocItem
|
||||
name="openURL"
|
||||
typeInfo="(url: string) => Promise<>"
|
||||
description="Try to open the given url in a secure fashion. The method returns a Promise object. If the url opens, the promise is resolved. If not, the promise is rejected."
|
||||
example={{
|
||||
render: () => <OpenURL />
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('Linking', LinkingScreen);
|
||||
@@ -17,7 +17,9 @@ export default class OpenURL extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text onPress={this.handlePress} style={styles.text}>Linking.openURL</Text>
|
||||
<Text onPress={this.handlePress} style={styles.text}>
|
||||
Linking.openURL
|
||||
</Text>
|
||||
<Text
|
||||
accessibilityRole="link"
|
||||
href="https://mathiasbynens.github.io/rel-noopener/malicious.html"
|
||||
|
||||
@@ -3,23 +3,56 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import UIExplorer, { AppText, Code, DocItem } from '../../ui-explorer';
|
||||
import UIExplorer, {
|
||||
AppText,
|
||||
Code,
|
||||
Description,
|
||||
DocItem,
|
||||
Section,
|
||||
storiesOf,
|
||||
TextList
|
||||
} from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Methods',
|
||||
entries: [
|
||||
const NetInfoScreen = () =>
|
||||
<UIExplorer title="NetInfo" url="apis/NetInfo">
|
||||
<Description>
|
||||
<AppText>
|
||||
NetInfo asynchronously determines the online/offline status of the application.
|
||||
</AppText>
|
||||
<AppText>
|
||||
Note that support for retrieving the connection type depends upon browswer support (and is
|
||||
limited to mobile browsers). It will default to <Code>unknown</Code> when support is
|
||||
missing.
|
||||
</AppText>
|
||||
</Description>
|
||||
|
||||
<Section title="Methods">
|
||||
<DocItem
|
||||
description={
|
||||
'Invokes the listener whenever network status changes. The listener receives one of the following connectivity types (from the DOM connection API): bluetooth, cellular, ethernet, mixed, none, other, unknown, wifi, wimax'
|
||||
}
|
||||
description={[
|
||||
<AppText>
|
||||
Invokes the listener whenever network status changes. The listener receives one of the
|
||||
following connectivity types (from the DOM connection API):
|
||||
</AppText>,
|
||||
<TextList
|
||||
items={[
|
||||
'bluetooth',
|
||||
'cellular',
|
||||
'ethernet',
|
||||
'mixed',
|
||||
'none',
|
||||
'other',
|
||||
'unknown',
|
||||
'wifi',
|
||||
'wimax'
|
||||
]}
|
||||
/>
|
||||
]}
|
||||
example={{
|
||||
code: "NetInfo.addEventListener('change', (connectionType) => {})"
|
||||
}}
|
||||
name="static addEventListener"
|
||||
typeInfo="(eventName, handler) => void"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Returns a promise that resolves with one of the connectivity types listed above."
|
||||
@@ -30,18 +63,16 @@ const sections = [
|
||||
}}
|
||||
name="static fetch"
|
||||
typeInfo="() => Promise<string>"
|
||||
/>,
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
description="Removes the listener for network status changes."
|
||||
name="static removeEventListener"
|
||||
typeInfo="(eventName, handler) => void"
|
||||
/>
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Properties',
|
||||
entries: [
|
||||
</Section>
|
||||
|
||||
<Section title="Properties">
|
||||
<DocItem
|
||||
description="An object with the same methods as above but the listener receives a boolean which represents the internet connectivity. Use this if you are only interested with whether the device has internet connectivity."
|
||||
example={{
|
||||
@@ -52,24 +83,7 @@ const sections = [
|
||||
name="isConnected"
|
||||
typeInfo="ObjectExpression"
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
</Section>
|
||||
</UIExplorer>;
|
||||
|
||||
storiesOf('APIs', module).add('NetInfo', () =>
|
||||
<UIExplorer
|
||||
description={[
|
||||
<AppText>
|
||||
NetInfo asynchronously determines the online/offline status of the application.
|
||||
</AppText>,
|
||||
<AppText>
|
||||
Note that support for retrieving the connection type depends upon browswer support (and is
|
||||
limited to mobile browsers).
|
||||
It will default to <Code>unknown</Code> when support is missing.
|
||||
</AppText>
|
||||
]}
|
||||
sections={sections}
|
||||
title="NetInfo"
|
||||
url="apis/NetInfo"
|
||||
/>
|
||||
);
|
||||
storiesOf('APIs', module).add('NetInfo', NetInfoScreen);
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import DraggableCircleExample from './examples/DraggableCircle';
|
||||
import { storiesOf } from '@kadira/storybook';
|
||||
import React from 'react';
|
||||
import UIExplorer, { AppText, DocItem } from '../../ui-explorer';
|
||||
|
||||
const sections = [
|
||||
{
|
||||
title: 'Examples',
|
||||
entries: [
|
||||
<DocItem
|
||||
example={{
|
||||
render: () => <DraggableCircleExample />
|
||||
}}
|
||||
/>
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
storiesOf('APIs', module).add('PanResponder', () =>
|
||||
<UIExplorer
|
||||
description={
|
||||
<AppText>
|
||||
PanResponder reconciles several touches into a single gesture. It makes single-touch
|
||||
gestures resilient to extra touches, and can be used to recognize simple multi-touch
|
||||
gestures. For more information, please refer to the React Native{' '}
|
||||
<AppText
|
||||
accessibilityTraits="link"
|
||||
href="https://facebook.github.io/react-native/docs/panresponder.html"
|
||||
style={{ color: '#1B95E0' }}
|
||||
target="_blank"
|
||||
>
|
||||
PanResponder documentation
|
||||
</AppText>
|
||||
</AppText>
|
||||
}
|
||||
sections={sections}
|
||||
title="PanResponder"
|
||||
url="apis/PanResponder"
|
||||
/>
|
||||
);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user