Update documentation examples

This commit is contained in:
Nicolas Gallagher
2017-06-09 14:51:57 -07:00
parent 05069253a1
commit 7f256c6423
18 changed files with 622 additions and 462 deletions

View File

@@ -3,15 +3,13 @@ import { StyleSheet, View } from 'react-native';
const styles = StyleSheet.create({
root: {
alignItems: 'center',
height: '100vh',
justifyContent: 'center'
minHeight: '100vh'
}
});
export default function(renderStory) {
return (
<View style={[StyleSheet.absoluteFill, styles.root]}>
<View style={styles.root}>
{renderStory()}
</View>
);

View File

@@ -1,34 +1,61 @@
import { Clipboard, Text, TextInput, View } from 'react-native';
import React, { Component } from 'react';
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import { Button, Clipboard, StyleSheet, TextInput, View } from 'react-native';
import React, { Component } from 'react';
const styles = StyleSheet.create({
buttonBox: {
maxWidth: 300
},
textInput: {
borderColor: '#AAB8C2',
borderWidth: 1,
height: 200,
marginTop: 20,
padding: 10
}
});
class ClipboardExample extends Component {
render() {
return (
<View style={{ minWidth: 300 }}>
<Text onPress={this._handleSet}>Copy to clipboard</Text>
<View>
<View style={styles.buttonBox}>
<Button onPress={this._handleSet} title="Copy to clipboard" />
</View>
<TextInput
multiline={true}
placeholder={'Try pasting here afterwards'}
style={{ borderWidth: 1, height: 200, marginVertical: 20 }}
style={styles.textInput}
/>
<Text onPress={this._handleGet}>
(Clipboard.getString returns a Promise that always resolves to an empty string on web)
</Text>
</View>
);
}
_handleGet() {
Clipboard.getString().then(value => {
console.log(`Clipboard value: ${value}`);
});
}
_handleSet() {
const success = Clipboard.setString('This text was copied to the clipboard by React Native');
console.log(`Clipboard.setString success? ${success}`);
}
}
storiesOf('api: Clipboard', module).add('setString', () => <ClipboardExample />);
const examples = [
{
title: 'Clipboard.setString',
description:
'(Note that `Clipboard.getString` returns a Promise that always resolves to an empty string on web.)',
render: () => <ClipboardExample />
},
{
title: 'Clipboard.getString',
description:
'Not properly supported on Web. Returns a Promise that always resolves to an empty string on web.'
}
];
storiesOf('APIs', module).add('Clipboard', () =>
<UIExplorer
description="Clipboard gives you an interface for setting to the clipboard."
examples={examples}
title="Clipboard"
/>
);

View File

@@ -1,4 +1,5 @@
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import { I18nManager, StyleSheet, TouchableHighlight, Text, View } from 'react-native';
import React, { Component } from 'react';
@@ -85,4 +86,13 @@ const styles = StyleSheet.create({
}
});
storiesOf('api: I18nManager', module).add('RTL layout', () => <I18nManagerExample />);
const examples = [
{
title: 'RTL toggle',
render: () => <I18nManagerExample />
}
];
storiesOf('APIs', module).add('I18nManager', () =>
<UIExplorer examples={examples} title="I18nManager" />
);

View File

@@ -1,6 +1,7 @@
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import { Linking, StyleSheet, Text, View } from 'react-native';
import React, { Component } from 'react';
import { storiesOf } from '@kadira/storybook';
const url = 'https://mathiasbynens.github.io/rel-noopener/malicious.html';
@@ -36,4 +37,11 @@ const styles = StyleSheet.create({
}
});
storiesOf('api: Linking', module).add('Safe linking', () => <LinkingExample />);
const examples = [
{
title: 'Safe external links',
render: () => <LinkingExample />
}
];
storiesOf('APIs', module).add('Linking', () => <UIExplorer examples={examples} title="Linking" />);

View File

@@ -3,6 +3,7 @@
import createReactClass from 'create-react-class';
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import { PanResponder, StyleSheet, View } from 'react-native';
const CIRCLE_SIZE = 80;
@@ -97,12 +98,23 @@ const styles = StyleSheet.create({
height: CIRCLE_SIZE,
borderRadius: CIRCLE_SIZE / 2,
position: 'absolute',
left: 0,
top: 0
},
container: {
flex: 1,
minHeight: 400,
paddingTop: 64
}
});
storiesOf('api: PanResponder', module).add('example', () => <PanResponderExample />);
const examples = [
{
title: 'Draggable circle',
render: () => <PanResponderExample />
}
];
storiesOf('APIs', module).add('PanResponder', () =>
<UIExplorer examples={examples} title="PanResponder" />
);

View File

@@ -26,8 +26,9 @@
import createReactClass from 'create-react-class';
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import { ActivityIndicator, StyleSheet, View } from 'react-native';
import TimerMixin from 'react-timer-mixin';
import UIExplorer from '../../UIExplorer';
import { ActivityIndicator, StyleSheet, View } from 'react-native';
const ToggleAnimatingActivityIndicator = createReactClass({
mixins: [TimerMixin],
@@ -64,62 +65,59 @@ const ToggleAnimatingActivityIndicator = createReactClass({
const examples = [
{
title: 'Default',
description: 'Renders small and blue',
render() {
return <ActivityIndicator style={[styles.centering]} />;
return (
<View style={styles.horizontal}>
<ActivityIndicator />
</View>
);
}
},
{
title: 'Custom colors',
description: 'Any color value is supported',
render() {
return (
<View style={styles.horizontal}>
<ActivityIndicator color="#0000ff" />
<ActivityIndicator color="#aa00aa" />
<ActivityIndicator color="#aa3300" />
<ActivityIndicator color="#00aa00" />
<ActivityIndicator color="#1DA1F2" style={styles.rightPadding} />
<ActivityIndicator color="#17BF63" style={styles.rightPadding} />
<ActivityIndicator color="#F45D22" style={styles.rightPadding} />
<ActivityIndicator color="#794BC4" style={styles.rightPadding} />
<ActivityIndicator color="#E0245E" style={styles.rightPadding} />
<ActivityIndicator color="#FFAD1F" style={styles.rightPadding} />
</View>
);
}
},
{
title: 'Large',
render() {
return (
<ActivityIndicator color="white" size="large" style={[styles.centering, styles.gray]} />
);
}
},
{
title: 'Large, custom colors',
title: 'Custom sizes',
description:
'There are 2 predefined sizes: "small" and "large". The size can be further customized as a number (pixels) or using scale transforms',
render() {
return (
<View style={styles.horizontal}>
<ActivityIndicator color="#0000ff" size="large" />
<ActivityIndicator color="#aa00aa" size="large" />
<ActivityIndicator color="#aa3300" size="large" />
<ActivityIndicator color="#00aa00" size="large" />
<ActivityIndicator size={20} style={styles.rightPadding} />
<ActivityIndicator size="small" style={styles.rightPadding} />
<ActivityIndicator size={36} style={styles.rightPadding} />
<ActivityIndicator size="large" style={styles.rightPadding} />
<ActivityIndicator size={60} style={styles.rightPadding} />
<ActivityIndicator
size="large"
style={{ marginLeft: 20, transform: [{ scale: 1.75 }] }}
/>
</View>
);
}
},
{
title: 'Start/stop',
title: 'Animation controls (start, pause, hide)',
description: 'The animation can be paused, and the component hidden',
render() {
return (
<View style={[styles.horizontal, styles.centering]}>
<View style={[styles.horizontal]}>
<ToggleAnimatingActivityIndicator hidesWhenStopped={false} style={styles.rightPadding} />
<ToggleAnimatingActivityIndicator />
<ToggleAnimatingActivityIndicator hidesWhenStopped={false} />
</View>
);
}
},
{
title: 'Custom size',
render() {
return (
<View style={[styles.horizontal, styles.centering]}>
<ActivityIndicator size={40} />
<ActivityIndicator size="large" style={{ marginLeft: 20, transform: [{ scale: 1.5 }] }} />
</View>
);
}
@@ -127,21 +125,23 @@ const examples = [
];
const styles = StyleSheet.create({
centering: {
alignItems: 'center',
justifyContent: 'center',
padding: 8
},
gray: {
backgroundColor: '#cccccc'
},
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 8
alignItems: 'center',
flexDirection: 'row'
},
rightPadding: {
paddingRight: 10
}
});
examples.forEach(example => {
storiesOf('component: ActivityIndicator', module).add(example.title, () => example.render());
});
storiesOf('Components', module).add('ActivityIndicator', () =>
<UIExplorer
description="Displays a customizable activity indicator"
examples={examples}
title="ActivityIndicator"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/ActivityIndicator.md"
/>
);

View File

@@ -1,54 +1,66 @@
import React from 'react';
import UIExplorer from '../../UIExplorer';
import { action, storiesOf } from '@kadira/storybook';
import { Button, View } from 'react-native';
import { Button, StyleSheet, View } from 'react-native';
const onButtonPress = action('Button has been pressed!');
const examples = [
{
title: 'Simple Button',
title: 'Default',
description:
'The title and onPress handler are required. It is ' +
'recommended to set accessibilityLabel to help make your app usable by ' +
'recommended to set "accessibilityLabel" to help make your app usable by ' +
'everyone.',
render: function() {
render() {
return (
<Button
accessibilityLabel="See an informative alert"
onPress={onButtonPress}
title="Press Me"
title="Press me"
/>
);
}
},
{
title: 'Adjusted color',
title: 'Custom colors',
description:
'Adjusts the color in a way that looks standard on each ' +
'platform. On iOS, the color prop controls the color of the text. On ' +
'Android, the color adjusts the background color of the button.',
render: function() {
render() {
return (
<Button
accessibilityLabel="Learn more about purple"
color="#841584"
onPress={onButtonPress}
title="Press Purple"
/>
<View>
<Button color="#17BF63" onPress={onButtonPress} title="Press me" />
<View style={styles.verticalDivider} />
<Button color="#F45D22" onPress={onButtonPress} title="Press me" />
<View style={styles.verticalDivider} />
<Button color="#794BC4" onPress={onButtonPress} title="Press me" />
<View style={styles.verticalDivider} />
<Button color="#E0245E" onPress={onButtonPress} title="Press me" />
</View>
);
}
},
{
title: 'Disabled',
description: 'All interactions for the component are disabled.',
render() {
return <Button disabled onPress={onButtonPress} title="Disabled button" />;
}
},
{
title: 'Fit to text layout',
description: 'This layout strategy lets the title define the width of the button',
render: function() {
render() {
return (
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={styles.horizontal}>
<Button
accessibilityLabel="This sounds great!"
onPress={onButtonPress}
title="This looks great!"
/>
<View style={styles.horizontalDivider} />
<Button
accessibilityLabel="Ok, Great!"
color="#841584"
@@ -58,23 +70,26 @@ const examples = [
</View>
);
}
},
{
title: 'Disabled Button',
description: 'All interactions for the component are disabled.',
render: function() {
return (
<Button
accessibilityLabel="See an informative alert"
disabled
onPress={onButtonPress}
title="I Am Disabled"
/>
);
}
}
];
examples.forEach(example => {
storiesOf('component: Button', module).add(example.title, () => example.render());
const styles = StyleSheet.create({
horizontalDivider: {
width: '0.6rem'
},
horizontal: {
flexDirection: 'row'
},
verticalDivider: {
height: '1.3125rem'
}
});
storiesOf('Components', module).add('Button', () =>
<UIExplorer
description="A basic button component. Supports a minimal level of customization. You can build your own custom button using &quot;TouchableOpacity&quot; or &quot;TouchableNativeFeedback&quot;"
examples={examples}
title="Button"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/Button.md"
/>
);

View File

@@ -23,32 +23,32 @@
* @flow
*/
import createReactClass from 'create-react-class';
import React from 'react';
import UIExplorer from '../../UIExplorer';
import { storiesOf } from '@kadira/storybook';
import { ActivityIndicator, Image, StyleSheet, Text, View } from 'react-native';
const base64Icon =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
//var ImageCapInsetsExample = require('./ImageCapInsetsExample');
const IMAGE_PREFETCH_URL = 'http://origami.design/public/images/bird-logo.png?r=1&t=' + Date.now();
const prefetchTask = Image.prefetch(IMAGE_PREFETCH_URL);
const NetworkImageCallbackExample = createReactClass({
getInitialState: function() {
return {
class NetworkImageCallbackExample extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
events: [],
startLoadPrefetched: false,
mountTime: new Date()
};
},
}
componentWillMount() {
this.setState({ mountTime: new Date() });
},
}
render: function() {
render() {
const { mountTime } = this.state;
return (
@@ -90,24 +90,21 @@ const NetworkImageCallbackExample = createReactClass({
</Text>
</View>
);
},
_loadEventFired(event) {
this.setState(state => {
return (state.events = [...state.events, event]);
});
}
});
const NetworkImageExample = createReactClass({
getInitialState: function() {
return {
error: false,
loading: false,
progress: 0
};
},
render: function() {
_loadEventFired = event => {
this.setState(state => (state.events = [...state.events, event]));
};
}
class NetworkImageExample extends React.Component {
state = {
error: false,
loading: false,
progress: 0
};
render() {
const loader = this.state.loading
? <View style={styles.progress}>
<Text>{this.state.progress}%</Text>
@@ -130,21 +127,21 @@ const NetworkImageExample = createReactClass({
{loader}
</Image>;
}
});
}
const ImageSizeExample = createReactClass({
getInitialState: function() {
return {
width: 0,
height: 0
};
},
componentDidMount: function() {
class ImageSizeExample extends React.Component {
state = {
width: 0,
height: 0
};
componentDidMount() {
Image.getSize(this.props.source.uri, (width, height) => {
this.setState({ width, height });
});
},
render: function() {
}
render() {
return (
<View>
<Text>
@@ -163,7 +160,7 @@ const ImageSizeExample = createReactClass({
</View>
);
}
});
}
/*
var MultipleSourcesExample = createReactClass({
@@ -226,7 +223,7 @@ var MultipleSourcesExample = createReactClass({
const examples = [
{
title: 'Plain Network Image',
title: 'Plain network image',
description:
'If the `source` prop `uri` property is prefixed with ' +
'"http", then it will be downloaded from the network.',
@@ -244,7 +241,7 @@ const examples = [
}
},
{
title: 'Plain Static Image',
title: 'Plain static image',
description:
'Static assets should be placed in the source code tree, and ' +
'required in the same way as JavaScript modules.',
@@ -260,8 +257,8 @@ const examples = [
}
},
{
title: 'Image Loading Events',
render: function() {
title: 'Image loading events',
render() {
return (
<NetworkImageCallbackExample
prefetchedSource={{ uri: IMAGE_PREFETCH_URL }}
@@ -271,31 +268,19 @@ const examples = [
}
},
{
title: 'Error Handler',
render: function() {
title: 'Error handler',
render() {
return (
<NetworkImageExample
source={{ uri: 'http://TYPO_ERROR_facebook.github.io/react/img/logo_og.png' }}
/>
);
},
platform: 'ios'
},
{
title: 'Image Download Progress',
render: function() {
return (
<NetworkImageExample
source={{ uri: 'http://origami.design/public/images/bird-logo.png?r=1' }}
/>
);
},
platform: 'ios'
}
},
{
title: 'defaultSource',
description: 'Show a placeholder image when a network image is loading',
render: function() {
render() {
return (
<Image
defaultSource={require('./bunny.png')}
@@ -303,38 +288,51 @@ const examples = [
style={styles.base}
/>
);
},
platform: 'ios'
}
},
{
title: 'Border Color',
render: function() {
title: 'Border color',
render() {
return (
<View style={styles.horizontal}>
<Image
source={smallImage}
style={[styles.base, styles.background, { borderWidth: 3, borderColor: '#f099f0' }]}
style={[
styles.base,
styles.background,
{
borderColor: '#f099f0',
borderWidth: 3
}
]}
/>
</View>
);
}
},
{
title: 'Border Width',
render: function() {
title: 'Border width',
render() {
return (
<View style={styles.horizontal}>
<Image
source={smallImage}
style={[styles.base, styles.background, { borderWidth: 5, borderColor: '#f099f0' }]}
style={[
styles.base,
styles.background,
{
borderColor: '#f099f0',
borderWidth: 5
}
]}
/>
</View>
);
}
},
{
title: 'Border Radius',
render: function() {
title: 'Border radius',
render() {
return (
<View style={styles.horizontal}>
<Image source={fullImage} style={[styles.base, { borderRadius: 5 }]} />
@@ -347,8 +345,8 @@ const examples = [
}
},
{
title: 'Background Color',
render: function() {
title: 'Background color',
render() {
return (
<View style={styles.horizontal}>
<Image source={smallImage} style={styles.base} />
@@ -370,7 +368,7 @@ const examples = [
},
{
title: 'Opacity',
render: function() {
render() {
return (
<View style={styles.horizontal}>
<Image source={fullImage} style={[styles.base, { opacity: 1 }]} />
@@ -385,7 +383,7 @@ const examples = [
},
{
title: 'Nesting',
render: function() {
render() {
return (
<Image source={fullImage} style={{ width: 60, height: 60, backgroundColor: 'transparent' }}>
<Text style={styles.nestedText}>
@@ -395,62 +393,10 @@ const examples = [
);
}
},
/*
{
title: 'Tint Color',
description: 'The `tintColor` style prop changes all the non-alpha ' +
'pixels to the tint color.',
render: function() {
return (
<View>
<View style={styles.horizontal}>
<Image
source={require('./uie_thumb_normal@2x.png')}
style={[styles.icon, {borderRadius: 5, tintColor: '#5ac8fa' }]}
/>
<Image
source={require('./uie_thumb_normal@2x.png')}
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#4cd964' }]}
/>
<Image
source={require('./uie_thumb_normal@2x.png')}
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#ff2d55' }]}
/>
<Image
source={require('./uie_thumb_normal@2x.png')}
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#8e8e93' }]}
/>
</View>
<Text style={styles.sectionText}>
It also works with downloaded images:
</Text>
<View style={styles.horizontal}>
<Image
source={smallImage}
style={[styles.base, {borderRadius: 5, tintColor: '#5ac8fa' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#4cd964' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#ff2d55' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#8e8e93' }]}
/>
</View>
</View>
);
},
},
*/
{
title: 'Resize Mode',
title: 'Resize mode',
description: 'The `resizeMode` style prop controls how the image is rendered within the frame.',
render: function() {
render() {
return (
<View>
{[smallImage, fullImage].map((image, index) => {
@@ -511,7 +457,7 @@ const examples = [
},
{
title: 'Animated GIF',
render: function() {
render() {
return (
<Image
source={{
@@ -521,33 +467,19 @@ const examples = [
style={styles.gif}
/>
);
},
platform: 'ios'
}
},
{
title: 'Base64 image',
render: function() {
render() {
return <Image source={{ uri: base64Icon, scale: 3 }} style={styles.base64} />;
},
platform: 'ios'
}
},
/*
{
title: 'Cap Insets',
title: 'Image dimensions',
description:
'When the image is resized, the corners of the size specified ' +
'by capInsets will stay a fixed size, but the center content and ' +
'borders of the image will be stretched. This is useful for creating ' +
'resizable rounded buttons, shadows, and other resizable assets.',
render: function() {
return <ImageCapInsetsExample />;
},
platform: 'ios',
},
*/
{
title: 'Image Size',
render: function() {
'`Image.getSize` provides the dimensions of an image as soon as they are available (i.e., before loading is complete)',
render() {
return (
<ImageSizeExample
source={{
@@ -557,18 +489,6 @@ const examples = [
);
}
}
/*
{
title: 'MultipleSourcesExample',
description:
'The `source` prop allows passing in an array of uris, so that native to choose which image ' +
'to diplay based on the size of the of the target image',
render: function() {
return <MultipleSourcesExample />;
},
platform: 'android',
},
*/
];
const fullImage = { uri: 'http://facebook.github.io/react/img/logo_og.png' };
@@ -576,12 +496,12 @@ const smallImage = { uri: 'http://facebook.github.io/react/img/logo_small_2x.png
const styles = StyleSheet.create({
base: {
width: 38,
height: 38
height: 38,
width: 38
},
progress: {
flex: 1,
alignItems: 'center',
flex: 1,
flexDirection: 'row',
width: 100
},
@@ -595,24 +515,24 @@ const styles = StyleSheet.create({
marginVertical: 6
},
nestedText: {
marginLeft: 12,
marginTop: 20,
backgroundColor: 'transparent',
color: 'white'
color: 'white',
marginLeft: 12,
marginTop: 20
},
resizeMode: {
width: 90,
height: 60,
borderColor: 'black',
borderWidth: 0.5,
borderColor: 'black'
height: 60,
width: 90
},
resizeModeText: {
fontSize: 11,
marginBottom: 3
},
icon: {
width: 15,
height: 15
height: 15,
width: 15
},
horizontal: {
flexDirection: 'row'
@@ -627,13 +547,16 @@ const styles = StyleSheet.create({
resizeMode: 'contain'
},
touchableText: {
fontWeight: '500',
color: 'blue'
color: 'blue',
fontWeight: '500'
}
});
examples.forEach(example => {
storiesOf('component: Image', module)
.addDecorator(renderStory => <View style={{ width: '100%' }}>{renderStory()}</View>)
.add(example.title, () => example.render());
});
storiesOf('Components', module).add('Image', () =>
<UIExplorer
description="An accessibile image component with support for image resizing, default image, and child content."
examples={examples}
title="Image"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/Image.md"
/>
);

View File

@@ -28,6 +28,7 @@ import { ProgressBar, StyleSheet, View } from 'react-native';
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import TimerMixin from 'react-timer-mixin';
import UIExplorer from '../../UIExplorer';
const ProgressBarExample = createReactClass({
mixins: [TimerMixin],
@@ -56,10 +57,7 @@ const ProgressBarExample = createReactClass({
render() {
return (
<View style={styles.container}>
<ProgressBar color="purple" progress={this.getProgress(0.2)} style={styles.progressView} />
<ProgressBar color="red" progress={this.getProgress(0.4)} style={styles.progressView} />
<ProgressBar color="orange" progress={this.getProgress(0.6)} style={styles.progressView} />
<ProgressBar color="yellow" progress={this.getProgress(0.8)} style={styles.progressView} />
<ProgressBar color="#794BC4" progress={this.getProgress(0.2)} style={styles.progressView} />
</View>
);
}
@@ -67,16 +65,76 @@ const ProgressBarExample = createReactClass({
const examples = [
{
title: 'progress',
title: 'Default',
render() {
return <ProgressBar progress={0.5} />;
}
},
{
title: 'Controlled',
render() {
return <ProgressBarExample />;
}
},
{
title: 'indeterminate',
title: 'Indeterminate',
render() {
return <ProgressBar indeterminate style={styles.progressView} trackColor="#D1E3F6" />;
}
},
{
title: 'Custom colors',
render() {
return (
<View>
<ProgressBar color="#1DA1F2" progress={1} />
<View style={styles.verticalDivider} />
<ProgressBar color="#17BF63" progress={0.8} />
<View style={styles.verticalDivider} />
<ProgressBar color="#F45D22" progress={0.6} />
<View style={styles.verticalDivider} />
<ProgressBar color="#794BC4" progress={0.4} />
<View style={styles.verticalDivider} />
<ProgressBar color="#E0245E" progress={0.2} />
</View>
);
}
},
{
title: 'Custom track colors',
render() {
return (
<View>
<ProgressBar color="#1DA1F2" progress={0.1} trackColor="#D1E3F6" />
<View style={styles.verticalDivider} />
<ProgressBar color="#1DA1F2" progress={0.2} trackColor="rgba(121, 74, 196, 0.34)" />
<View style={styles.verticalDivider} />
<ProgressBar color="#1DA1F2" progress={0.3} trackColor="rgba(224, 36, 94, 0.35)" />
</View>
);
}
},
{
title: 'Custom sizes',
render() {
return (
<View>
<ProgressBar
color="#1DA1F2"
progress={0.33}
style={{ height: 10 }}
trackColor="#D1E3F6"
/>
<View style={styles.verticalDivider} />
<ProgressBar
color="#1DA1F2"
progress={0.33}
style={{ height: 15 }}
trackColor="#D1E3F6"
/>
</View>
);
}
}
];
@@ -89,9 +147,17 @@ const styles = StyleSheet.create({
progressView: {
marginTop: 20,
minWidth: 200
},
verticalDivider: {
height: '1.3125rem'
}
});
examples.forEach(example => {
storiesOf('component: ProgressBar', module).add(example.title, () => example.render());
});
storiesOf('Components', module).add('ProgressBar', () =>
<UIExplorer
description="Display an activity progress bar"
examples={examples}
title="ProgressBar"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/ProgressBar.md"
/>
);

View File

@@ -1,45 +1,51 @@
/* eslint-disable react/jsx-no-bind */
import React from 'react';
import UIExplorer from '../../UIExplorer';
import { action, storiesOf } from '@kadira/storybook';
import { ScrollView, StyleSheet, Text, TouchableHighlight, View } from 'react-native';
const onScroll = action('ScrollView.onScroll');
storiesOf('component: ScrollView', module)
.add('vertical', () =>
<View style={styles.scrollViewContainer}>
<ScrollView
contentContainerStyle={styles.scrollViewContentContainerStyle}
onScroll={onScroll}
scrollEventThrottle={1000} // 1 event per second
style={styles.scrollViewStyle}
>
{Array.from({ length: 50 }).map((item, i) =>
<View key={i} style={styles.box}>
<TouchableHighlight onPress={() => {}}><Text>{i}</Text></TouchableHighlight>
</View>
)}
</ScrollView>
</View>
)
.add('horizontal', () =>
<View style={styles.scrollViewContainer}>
<ScrollView
contentContainerStyle={styles.scrollViewContentContainerStyle}
horizontal
onScroll={onScroll}
scrollEventThrottle={16} // ~60 events per second
style={styles.scrollViewStyle}
>
{Array.from({ length: 50 }).map((item, i) =>
<View key={i} style={[styles.box, styles.horizontalBox]}>
<Text>{i}</Text>
</View>
)}
</ScrollView>
</View>
);
const examples = [
{
title: 'vertical',
render: () =>
<View style={styles.scrollViewContainer}>
<ScrollView
contentContainerStyle={styles.scrollViewContentContainerStyle}
onScroll={onScroll}
scrollEventThrottle={1000} // 1 event per second
style={styles.scrollViewStyle}
>
{Array.from({ length: 50 }).map((item, i) =>
<View key={i} style={styles.box}>
<TouchableHighlight onPress={() => {}}><Text>{i}</Text></TouchableHighlight>
</View>
)}
</ScrollView>
</View>
},
{
title: 'horizontal',
render: () =>
<View style={styles.scrollViewContainer}>
<ScrollView
contentContainerStyle={styles.scrollViewContentContainerStyle}
horizontal
onScroll={onScroll}
scrollEventThrottle={16} // ~60 events per second
style={styles.scrollViewStyle}
>
{Array.from({ length: 50 }).map((item, i) =>
<View key={i} style={[styles.box, styles.horizontalBox]}>
<Text>{i}</Text>
</View>
)}
</ScrollView>
</View>
}
];
const styles = StyleSheet.create({
box: {
@@ -48,7 +54,7 @@ const styles = StyleSheet.create({
borderWidth: 1
},
scrollViewContainer: {
height: '200px',
height: 200,
width: 300
},
scrollViewStyle: {
@@ -59,3 +65,11 @@ const styles = StyleSheet.create({
padding: 10
}
});
storiesOf('Components', module).add('ScrollView', () =>
<UIExplorer
examples={examples}
title="ScrollView"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/ScrollView.md"
/>
);

View File

@@ -27,6 +27,7 @@ import createReactClass from 'create-react-class';
import { Switch, Text, View } from 'react-native';
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
const BasicSwitchExample = createReactClass({
getInitialState() {
@@ -198,6 +199,10 @@ const examples = [
}
];
examples.forEach(example => {
storiesOf('component: Switch', module).add(example.title, () => example.render());
});
storiesOf('Components', module).add('Switch', () =>
<UIExplorer
examples={examples}
title="Switch"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/Switch.md"
/>
);

View File

@@ -26,6 +26,7 @@
import createReactClass from 'create-react-class';
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import { Image, Text, View } from 'react-native';
const Entity = createReactClass({
@@ -561,8 +562,10 @@ const examples = [
}
];
examples.forEach(example => {
storiesOf('component: Text', module)
.addDecorator(renderStory => <View style={{ width: 320 }}>{renderStory()}</View>)
.add(example.title, () => example.render());
});
storiesOf('Components', module).add('Text', () =>
<UIExplorer
examples={examples}
title="Text"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/Text.md"
/>
);

View File

@@ -25,6 +25,7 @@
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import { any, bool, object, string } from 'prop-types';
import { StyleSheet, Text, TextInput, View } from 'react-native';
@@ -464,7 +465,7 @@ const styles = StyleSheet.create({
const examples = [
{
title: 'Auto-focus',
render: function() {
render() {
return (
<View>
<TextInput
@@ -478,19 +479,19 @@ const examples = [
},
{
title: "Live Re-Write (<sp> -> '_') + maxLength",
render: function() {
render() {
return <RewriteExample />;
}
},
{
title: 'Live Re-Write (no spaces allowed)',
render: function() {
render() {
return <RewriteExampleInvalidCharacters />;
}
},
{
title: 'Auto-capitalize',
render: function() {
render() {
return (
<View>
<WithLabel label="none">
@@ -511,7 +512,7 @@ const examples = [
},
{
title: 'Auto-correct',
render: function() {
render() {
return (
<View>
<WithLabel label="true">
@@ -526,7 +527,7 @@ const examples = [
},
{
title: 'Keyboard types',
render: function() {
render() {
const keyboardTypes = [
'default',
//'ascii-capable',
@@ -553,7 +554,7 @@ const examples = [
},
{
title: 'Keyboard appearance',
render: function() {
render() {
const keyboardAppearance = ['default', 'light', 'dark'];
const examples = keyboardAppearance.map(type => {
return (
@@ -567,7 +568,7 @@ const examples = [
},
{
title: 'Return key types',
render: function() {
render() {
const returnKeyTypes = [
'default',
'go',
@@ -593,7 +594,7 @@ const examples = [
},
{
title: 'Enable return key automatically',
render: function() {
render() {
return (
<View>
<WithLabel label="true">
@@ -605,7 +606,7 @@ const examples = [
},
{
title: 'Secure text entry',
render: function() {
render() {
return (
<View>
<WithLabel label="true">
@@ -617,13 +618,13 @@ const examples = [
},
{
title: 'Event handling',
render: function(): React.Element<any> {
render(): React.Element<any> {
return <TextEventsExample />;
}
},
{
title: 'Colored input text',
render: function() {
render() {
return (
<View>
<TextInput defaultValue="Blue" style={[styles.default, { color: 'blue' }]} />
@@ -634,7 +635,7 @@ const examples = [
},
{
title: 'Colored highlight/cursor for text input',
render: function() {
render() {
return (
<View>
<TextInput defaultValue="Highlight me" selectionColor={'green'} style={styles.default} />
@@ -649,7 +650,7 @@ const examples = [
},
{
title: 'Clear button mode',
render: function() {
render() {
return (
<View>
<WithLabel label="never">
@@ -670,7 +671,7 @@ const examples = [
},
{
title: 'Clear and select',
render: function() {
render() {
return (
<View>
<WithLabel label="clearTextOnFocus">
@@ -695,13 +696,13 @@ const examples = [
},
{
title: 'Blur on submit',
render: function(): React.Element<any> {
render(): React.Element<any> {
return <BlurOnSubmitExample />;
}
},
{
title: 'Multiline blur on submit',
render: function() {
render() {
return (
<View>
<TextInput
@@ -720,7 +721,7 @@ const examples = [
},
{
title: 'Multiline',
render: function() {
render() {
return (
<View>
<TextInput multiline={true} placeholder="multiline text input" style={styles.multiline} />
@@ -759,7 +760,7 @@ const examples = [
},
{
title: 'Number of lines',
render: function() {
render() {
return (
<View>
<TextInput
@@ -773,7 +774,7 @@ const examples = [
},
{
title: 'Auto-expanding',
render: function() {
render() {
return (
<View>
<AutoExpandingTextInput
@@ -787,13 +788,13 @@ const examples = [
},
{
title: 'Attributed text',
render: function() {
render() {
return <TokenizedTextExample />;
}
},
{
title: 'Text selection & cursor placement',
render: function() {
render() {
return (
<View>
<SelectionExample style={styles.default} value="text selection can be changed" />
@@ -808,7 +809,7 @@ const examples = [
},
{
title: 'TextInput maxLength',
render: function() {
render() {
return (
<View>
<WithLabel label="maxLength: 5">
@@ -829,6 +830,10 @@ const examples = [
}
];
examples.forEach(example => {
storiesOf('component: TextInput', module).add(example.title, () => example.render());
});
storiesOf('Components', module).add('TextInput', () =>
<UIExplorer
examples={examples}
title="TextInput"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/TextInput.md"
/>
);

View File

@@ -24,7 +24,8 @@
*/
import React from 'react';
import { storiesOf, action } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import { action, storiesOf } from '@kadira/storybook';
import {
Image,
StyleSheet,
@@ -36,95 +37,6 @@ import {
View
} from 'react-native';
const examples = [
{
title: '<TouchableHighlight>',
description:
'TouchableHighlight works by adding an extra view with a ' +
'black background under the single child view. This works best when the ' +
'child view is fully opaque, although it can be made to work as a simple ' +
'background color change as well with the activeOpacity and ' +
'underlayColor props.',
render: function() {
return (
<View>
<View style={styles.row}>
<TouchableHighlight
onPress={() => console.log('stock THW image - highlight')}
style={styles.wrapper}
>
<Image source={heartImage} style={styles.image} />
</TouchableHighlight>
<TouchableHighlight
activeOpacity={1}
onPress={() => console.log('custom THW text - highlight')}
style={styles.wrapper}
underlayColor="rgb(210, 230, 255)"
>
<View style={styles.wrapperCustom}>
<Text style={styles.text}>
Tap Here For Custom Highlight!
</Text>
</View>
</TouchableHighlight>
</View>
</View>
);
}
},
{
title: '<Text onPress={fn}> with highlight',
render: function() {
return <TextOnPressBox />;
}
},
{
title: 'Touchable feedback events',
description:
'<Touchable*> components accept onPress, onPressIn, ' +
'onPressOut, and onLongPress as props.',
render: function() {
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: function() {
return <TouchableDelayEvents />;
}
},
{
title: '3D Touch / Force Touch',
description: 'iPhone 6s and 6s plus support 3D touch, which adds a force property to touches',
render: function() {
return <ForceTouchExample />;
},
platform: 'ios'
},
{
title: 'Touchable Hit Slop',
description:
'<Touchable*> components accept hitSlop prop which extends the touch area ' +
'without changing the view bounds.',
render: function() {
return <TouchableHitSlop />;
}
},
{
title: 'Disabled Touchable*',
description:
'<Touchable*> components accept disabled prop which prevents ' +
'any interaction with component',
render: function() {
return <TouchableDisabled />;
}
}
];
class TextOnPressBox extends React.Component {
constructor(props) {
super(props);
@@ -398,6 +310,66 @@ class TouchableDisabled extends React.Component {
}
}
class TouchableStyling extends React.Component {
constructor(props, context) {
super(props, context);
this.buttons = ['a', 'b', 'c'];
this.state = {};
this.select = this.select.bind(this);
}
select(selectedButton) {
const newState = {};
this.buttons.forEach(button => {
newState[button] = selectedButton === button;
});
this.setState(newState);
}
render() {
return (
<View style={touchableStylingStyles.container}>
{this.buttons.map(button => {
const tstyle = [
touchableStylingStyles.textInput,
this.state[button] && touchableStylingStyles.blue
];
return (
<TouchableHighlight
key={button}
onPress={this.select.bind(this, button)}
style={tstyle}
>
<Text style={[this.state[button] && touchableStylingStyles.white]}>
Button {button} {this.state[button] ? 'On' : 'Off'}
</Text>
</TouchableHighlight>
);
})}
</View>
);
}
}
const touchableStylingStyles = StyleSheet.create({
blue: {
backgroundColor: 'rgb(100, 100, 200)',
borderColor: 'white'
},
white: {
color: 'white'
},
container: {
backgroundColor: '#f6f6f6'
},
textInput: {
borderWidth: 3,
borderColor: 'black',
padding: 20,
width: 200
}
});
const heartImage = { uri: 'https://pbs.twimg.com/media/BlXBfT3CQAA6cVZ.png:small' };
const styles = StyleSheet.create({
@@ -473,6 +445,105 @@ const styles = StyleSheet.create({
}
});
examples.forEach(example => {
storiesOf('component: Touchable*', module).add(example.title, () => example.render());
});
const examples = [
{
title: '<TouchableHighlight>',
description:
'TouchableHighlight works by adding an extra view with a ' +
'black background under the single child view. This works best when the ' +
'child view is fully opaque, although it can be made to work as a simple ' +
'background color change as well with the activeOpacity and ' +
'underlayColor props.',
render() {
return (
<View>
<View style={styles.row}>
<TouchableHighlight
onPress={() => console.log('stock THW image - highlight')}
style={styles.wrapper}
>
<Image source={heartImage} style={styles.image} />
</TouchableHighlight>
<TouchableHighlight
activeOpacity={1}
onPress={() => console.log('custom THW text - highlight')}
style={styles.wrapper}
underlayColor="rgb(210, 230, 255)"
>
<View style={styles.wrapperCustom}>
<Text style={styles.text}>
Tap Here For Custom Highlight!
</Text>
</View>
</TouchableHighlight>
</View>
</View>
);
}
},
{
title: '<Text onPress={fn}> with highlight',
render() {
return <TextOnPressBox />;
}
},
{
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: 'Touchable styling',
render() {
return <TouchableStyling />;
}
},
{
title: '3D Touch / Force Touch',
description: 'iPhone 6s and 6s plus support 3D touch, which adds a force property to touches',
render() {
return <ForceTouchExample />;
},
platform: 'ios'
},
{
title: 'Touchable Hit Slop',
description:
'<Touchable*> components accept hitSlop prop which extends the touch area ' +
'without changing the view bounds.',
render() {
return <TouchableHitSlop />;
}
},
{
title: 'Disabled Touchable*',
description:
'<Touchable*> components accept disabled prop which prevents ' +
'any interaction with component',
render() {
return <TouchableDisabled />;
}
}
];
storiesOf('Components', module).add('Touchables', () =>
<UIExplorer
examples={examples}
title="Touchables"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/TouchableWithoutFeedback.md"
/>
);

View File

@@ -26,6 +26,8 @@
import createReactClass from 'create-react-class';
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import UIExplorer from '../../UIExplorer';
import ViewTransformsExample from './ViewTransformsExample';
import { StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native';
const styles = StyleSheet.create({
@@ -288,8 +290,12 @@ const examples = [
return <View style={[styles.shadowBox, styles.shadow, { borderRadius: 50 }]} />;
}
}
];
].concat(ViewTransformsExample);
examples.forEach(example => {
storiesOf('component: View', module).add(example.title, () => example.render());
});
storiesOf('Components', module).add('View', () =>
<UIExplorer
examples={examples}
title="View"
url="https://github.com/necolas/react-native-web/blob/master/docs/components/View.md"
/>
);

View File

@@ -22,21 +22,20 @@
* @flow
*/
import createReactClass from 'create-react-class';
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import { Animated, StyleSheet, Text, View } from 'react-native';
const Flip = createReactClass({
getInitialState() {
return {
class Flip extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
theta: new Animated.Value(45)
};
},
}
componentDidMount() {
this._animate();
},
}
_animate() {
this.state.theta.setValue(0);
@@ -44,7 +43,7 @@ const Flip = createReactClass({
toValue: 360,
duration: 5000
}).start(this._animate);
},
}
render() {
return (
@@ -95,7 +94,7 @@ const Flip = createReactClass({
</View>
);
}
});
}
const styles = StyleSheet.create({
box1: {
@@ -256,6 +255,4 @@ const examples = [
}
];
examples.forEach(example => {
storiesOf('component: View (transforms)', module).add(example.title, () => example.render());
});
module.exports = examples;

View File

@@ -2,4 +2,4 @@ import React from 'react';
import { storiesOf } from '@kadira/storybook';
import Game2048 from './Game2048';
storiesOf('demo: Game2048', module).add('the game', () => <Game2048 />);
storiesOf('Example apps', module).add('Game2048', () => <Game2048 />);

View File

@@ -2,4 +2,4 @@ import React from 'react';
import { storiesOf } from '@kadira/storybook';
import TicTacToe from './TicTacToe';
storiesOf('demo: TicTacToe', module).add('the game', () => <TicTacToe />);
storiesOf('Example apps', module).add('TicTacToe', () => <TicTacToe />);