From abf2c0307fa939e7bf117d83484719b74b5a9e3e Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Mon, 7 Sep 2015 09:38:25 -0700 Subject: [PATCH] Rewrite documentation --- README.md | 58 +++++-- docs/components/Image.md | 97 +++++++++-- docs/components/ListView.md | 41 +++++ docs/components/ScrollView.md | 40 +++++ docs/components/Swipeable.md | 93 +++++++++++ docs/components/Text.md | 55 +++++- docs/components/TextInput.md | 114 ++++++++++++- docs/components/Touchable.md | 59 +++++++ docs/components/View.md | 157 +++++++++++++----- docs/react-native-web-style/style-props.md | 89 ---------- .../styling.md => style.md} | 0 11 files changed, 627 insertions(+), 176 deletions(-) create mode 100644 docs/components/ListView.md create mode 100644 docs/components/ScrollView.md create mode 100644 docs/components/Swipeable.md create mode 100644 docs/components/Touchable.md delete mode 100644 docs/react-native-web-style/style-props.md rename docs/{react-native-web-style/styling.md => style.md} (100%) diff --git a/README.md b/README.md index 1492b707..9d28151a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # React Native for Web [![Build Status][travis-image]][travis-url] -[![npm version][npm-image]][npm-url] (14 KB gzipped) +[![npm version][npm-image]][npm-url] -The core [React Native][react-native-url] components built for the web, backed -by a precomputed CSS library. +The core [React Native][react-native-url] components adapted and expanded upon +for the web, backed by a precomputed CSS library. ~19KB minified and gzipped. ## Table of contents @@ -50,19 +50,46 @@ const styles = { ## Components -Partial implementations of… +### [`Image`](docs/components/Image.md) -* [`Image`](docs/components/Image.md) -* [`Text`](docs/components/Text.md) -* [`TextInput`](docs/components/TextInput.md) -* [`View`](docs/components/View.md) +An accessibile image component with support for image resizing, default image, +and child content. + +### [`ListView`](docs/components/ListView.md) + +(TODO) + +### [`ScrollView`](docs/components/ListView.md) + +(TODO) + +### [`Swipeable`](docs/components/Swipeable.md) + +Touch bindings for swipe gestures. + +### [`Text`](docs/components/Text.md) + +Displays text as an inline block and supports basic press handling. + +### [`TextInput`](docs/components/TextInput.md) + +Accessible single- and multi-line text input via a keyboard. Supports features + +### [`Touchable`](docs/components/Touchable.md) + +Touch bindings for press and long press. + +### [`View`](docs/components/View.md) + +The fundamental UI building block: layout with flexbox, layout and positioning +styles, and accessibility controls. ## Styling -React Native Web provides a mechanism to declare all your styles and layout -inline with the components that use them. The `View` component makes it easy -to build common layouts with flexbox, such as stacked and nested boxes with -margin and padding. +React Native for Web provides a mechanism to declare all your styles and layout +inline with the components that use them. The `View` component makes it easy to +build common layouts with flexbox, such as stacked and nested boxes with margin +and padding. Styling is identical to using inline styles in React, but most inline styles are converted to single-purpose classes. The current implementation includes @@ -70,7 +97,7 @@ are converted to single-purpose classes. The current implementation includes proportion of common styles. A more sophisticated build-time implementation may produce a slightly larger CSS file for large apps, and fall back to fewer inline styles. Read more about the [styling -strategy](docs/react-native-web-style/styling.md). +strategy](docs/style.md). See this [guide to flexbox][flexbox-guide-url]. @@ -144,6 +171,11 @@ welcome! Thanks to current and past members of the React and React Native teams (in particular Vjeux and Pete Hunt), and Tobias Koppers for Webpack and CSS loader. +Thanks to [react-swipeable](https://github.com/dogfessional/react-swipeable/) +for the current implementation of `Swipeable`, and to +[react-tappable](https://github.com/JedWatson/react-tappable) for backing the +current implementation of `Touchable`. + ## License Copyright (c) 2015 Nicolas Gallagher. Released under the [MIT diff --git a/docs/components/Image.md b/docs/components/Image.md index 01ddbeec..0596f9d2 100644 --- a/docs/components/Image.md +++ b/docs/components/Image.md @@ -1,30 +1,82 @@ -# Image spec +# Image -#### PropTypes +An accessibile image component with support for image resizing, default image, +and child content. -All other props are transferred to the resulting `img`. +## Props -+ `accessibilityLabel`: `string` -+ `source`: `object` -+ `style`: `ImageStylePropTypes` +**accessibilityLabel** string -#### ImageStylePropTypes +The text that's read by the screen reader when the user interacts with the image. -+ `BackgroundPropTypes` -+ `BorderThemePropTypes` -+ `LayoutPropTypes` -+ `opacity`: `string` +**children** any -#### Examples +Content to display over the image. + +**defaultSource** { uri: string } + +An image to display as a placeholder while downloading the final image off the network. + +**onError** function + +Invoked on load error with `{nativeEvent: {error}}`. + +**onLoad** function + +Invoked when load completes successfully. + +**onLoadEnd** function + +Invoked when load either succeeds or fails, + +**onLoadStart** function + +Invoked on load start. + +**resizeMode** oneOf('clip', 'contain', 'cover', 'stretch') + +Determines how to resize the image when the frame doesn't match the raw image +dimensions. Default: `cover`. + +**source** { uri: string } + +`uri` is a string representing the resource identifier for the image, which +could be an http address or a base64 encoded image. + +**style** style + +[View](docs/components/View) style + +Defaults: ```js +{ + alignSelf: 'flex-start', + backgroundColor: 'lightGray' +} +``` + +**testID** string + +Used to locate a view in end-to-end tests. + +## Examples + +```js +import placeholderAvatar from './placeholderAvatar.png' import React, { Image } from 'react-native-web' const { Component, PropTypes } = React; class Avatar extends Component { + constructor(props, context) { + super(props, context) + this.state = { isLoaded: false } + } + static propTypes = { size: PropTypes.oneOf(['small', 'normal', 'large']), + testID: Image.propTypes.testID, user: PropTypes.object } @@ -32,12 +84,23 @@ class Avatar extends Component { size: 'normal' } + _onLoad(e) { + console.log('Avatar.onLoad', e) + this.setState({ isLoaded: true }) + } + render() { + const { size, testID, user } = this.props + const { isLoaded } = this.state + return ( ) } @@ -47,7 +110,8 @@ const style = { base: { borderColor: 'white', borderRadius: '5px', - borderWidth: '5px' + borderWidth: '5px', + opacity: 0.5, }, small: { height: '32px', @@ -59,7 +123,10 @@ const style = { }, large: { height: '64px', - width: '32px' + width: '64px' + } + isLoaded: { + opacity: 1 } } ``` diff --git a/docs/components/ListView.md b/docs/components/ListView.md new file mode 100644 index 00000000..8cbdbb3a --- /dev/null +++ b/docs/components/ListView.md @@ -0,0 +1,41 @@ +# ListView + +## Props + +**children** any + +Content to display over the image. + +**style** style + ++ `property` type + +Defaults: + +```js +{ +} +``` + + +## Examples + +```js +import React, { ListView } from 'react-native-web' + +const { Component, PropTypes } = React; + +class Example extends Component { + static propTypes = { + } + + static defaultProps = { + } + + render() { + return ( + + ) + } +} +``` diff --git a/docs/components/ScrollView.md b/docs/components/ScrollView.md new file mode 100644 index 00000000..b2d58c3e --- /dev/null +++ b/docs/components/ScrollView.md @@ -0,0 +1,40 @@ +# ScrollView + +## Props + +**children** any + +Content to display over the image. + +**style** style + ++ `property` type + +Defaults: + +```js +{ +} +``` + + +## Examples + +```js +import React, { ScrollView } from 'react-native-web' + +const { Component, PropTypes } = React; + +class Example extends Component { + static propTypes = { + } + + static defaultProps = { + } + + render() { + return ( + ) + } +} +``` diff --git a/docs/components/Swipeable.md b/docs/components/Swipeable.md new file mode 100644 index 00000000..fce5a49d --- /dev/null +++ b/docs/components/Swipeable.md @@ -0,0 +1,93 @@ +# Swipeable + +## Props + +**delta** number + +Number of pixels that must be swiped before events are dispatched. Default: `10`. + +**flickThreshold** number + +The velocity threshold at which a swipe is considered a flick. Default: `0.6`. + +**onSwiped** function + +(SyntheticTouchEvent, deltaX, deltaY, isFlick) => swipeHandler + +Called once a swipe has ended. + +**onSwipedDown** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called once a swipe-down has ended. + +**onSwipedLeft** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called once a swipe-left has ended. + +**onSwipedUp** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called once a swipe-up has ended. + +**onSwipedRight** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called once a swipe-right has ended. + +**onSwipingDown** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called while a swipe-down is in progress. + +**onSwipingLeft** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called while a swipe-left is in progress. + +**onSwipingRight** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called while a swipe-right is in progress. + +**onSwipingUp** function + +(SyntheticTouchEvent, delta, isFlick) => swipeHandler + +Called while a swipe-up is in progress. + +## Examples + +```js +import React, { Swipeable } from 'react-native-web' + +const { Component, PropTypes } = React; + +class Example extends Component { + static propTypes = { + } + + static defaultProps = { + } + + _onSwiped(event, x, y, isFlick) { + + } + + render() { + return ( + + ) + } +} +``` diff --git a/docs/components/Text.md b/docs/components/Text.md index 151c345b..03505a8e 100644 --- a/docs/components/Text.md +++ b/docs/components/Text.md @@ -1,18 +1,55 @@ -# Text spec +# Text -Text layout and styles. +`Text` is component for displaying text. It supports style, basic touch +handling, and inherits typographic styles from ancestor elements. In a +divergence from React Native, components other than `Text` can be children of a +`Text` component. -#### PropTypes +The `Text` is unique relative to layout: child elements use text layout +(`inline-block`) 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. -All other props are transferred directly to the `component`. +## Props -+ `component`: `func` or `string` (default `'div'`) -+ `style`: `TextStylePropTypes` +**children** any -#### TextStylePropTypes +Child content -+ ViewStylePropTypes -+ TypographicPropTypes +**component** function, string + +Default is `span`. + +**numberOfLines** number + +Truncates the text with an ellipsis after this many lines. + +**onPress** function + +This function is called on press. + +**style** style + ++ `backgroundColor` ++ `color` ++ `direction` ++ `fontFamily` ++ `fontSize` ++ `fontStyle` ++ `fontWeight` ++ `letterSpacing` ++ `lineHeight` ++ `margin` ++ `padding` ++ `textAlign` ++ `textDecoration` ++ `textTransform` ++ `whiteSpace` ++ `wordWrap` + +**testID** string + +Used to locate this view in end-to-end tests. ## Examples diff --git a/docs/components/TextInput.md b/docs/components/TextInput.md index 7dbd296e..f5a12d44 100644 --- a/docs/components/TextInput.md +++ b/docs/components/TextInput.md @@ -1,15 +1,111 @@ -# TextInput spec +# TextInput -Text input layout and styles. +Accessible single- and multi-line text input via a keyboard. Supports features +such as auto-complete, auto-focus, placeholder text, and event callbacks. -#### PropTypes +Note: some props are exclusive to or excluded from `multiline`. -All other props are transferred directly to the `component`. +## Props -+ `component`: `func` or `string` (default `"div"`) -+ `style`: `TextStylePropTypes` +**autoComplete** bool -#### TextStylePropTypes +Indicates whether the value of the control can be automatically completed by the browser. -+ ViewStylePropTypes -+ TypographicPropTypes +**autoFocus** bool + +If true, focuses the input on `componentDidMount`. Only the first form element +in a document with `autofocus` is focused. Default: `false`. + +**defaultValue** string + +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 `value` prop to keep the controlled state in sync. + +**editable** bool + +If false, text is not editable. Default: `true`. + +**keyboardType** oneOf('default', 'email', 'numeric', 'search', 'tel', 'url') + +Determines which keyboard to open, e.g. `email`. Default: `default`. (Not +available when `multiline` is `true`.) + +**multiline** bool + +If true, the text input can be multiple lines. Default: `false`. + +**onBlur** function + +Callback that is called when the text input is blurred. + +**onChange** function + +Callback that is called when the text input's text changes. + +**onChangeText** function + +Callback that is called when the text input's text changes. Changed text is +passed as an argument to the callback handler. + +**onFocus** function + +Callback that is called when the text input is focused. + +**placeholder** string + +The string that will be rendered before text input has been entered. + +**placeholderTextColor** string + +The text color of the placeholder string. + +**secureTextEntry** bool + +If true, the text input obscures the text entered so that sensitive text like +passwords stay secure. Default: `false`. (Not available when `multiline` is `true`.) + +**style** style + +[View](docs/components/View) style + ++ `color` ++ `direction` ++ `fontFamily` ++ `fontSize` ++ `fontStyle` ++ `fontWeight` ++ `letterSpacing` ++ `lineHeight` ++ `textAlign` ++ `textDecoration` ++ `textTransform` + +**testID** string + +Used to locate this view in end-to-end tests. + +## Examples + +```js +import React, { TextInput } from 'react-native-web' + +const { Component, PropTypes } = React + +class AppTextInput extends Component { + static propTypes = { + } + + static defaultProps = { + } + + render() { + return ( + + ); + } +} + +const styles = { +} +``` diff --git a/docs/components/Touchable.md b/docs/components/Touchable.md new file mode 100644 index 00000000..b7db960a --- /dev/null +++ b/docs/components/Touchable.md @@ -0,0 +1,59 @@ +# Touchable + +## Props + +**activeHighlight** string + +Sets the color of the background highlight when `onPressIn` is called. The +highlight is removed when `onPressOut` is called. Default: `transparent`. + +**activeOpacity** number + +Sets the opacity of the child view when `onPressIn` is called. The opacity is +reset when `onPressOut` is called. Default: `1`. + +**component** function or string + +The backing component. Default: `div`. + +**delayLongPress** number + +Delay in ms, from `onPressIn`, before `onLongPress` is called. Default: `1000`. + +**delayPressIn** number (TODO) + +Delay in ms, from the start of the touch, before `onPressIn` is called. Default: `0`. + +**delayPressOut** number (TODO) + +Delay in ms, from the release of the touch, before `onPressOut` is called. Default: `0`. + +**onLongPress** function + +**onPress** function + +**onPressIn** function + +**onPressOut** function + +## Examples + +```js +import React, { Touchable } from 'react-native-web' + +const { Component, PropTypes } = React; + +class Example extends Component { + static propTypes = { + } + + static defaultProps = { + } + + render() { + return ( + + ) + } +} +``` diff --git a/docs/components/View.md b/docs/components/View.md index 9422cd6d..4347e85f 100644 --- a/docs/components/View.md +++ b/docs/components/View.md @@ -1,66 +1,141 @@ -# View spec +# View -`View` is a flexbox container and the fundamental building block for UI. It is -designed to be nested inside other `View`'s and to have 0-to-many children of -any type. +`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. -## PropTypes +## Props -All other props are transferred directly to the `element`. +**accessibilityLabel** string -+ `component`: `func` or `string` (default `'div'`) -+ `pointerEvents`: `oneOf('all', 'box-only', 'box-none', 'none')` -+ `style`: `ViewStylePropTypes` +Overrides the text that's read by the screen reader when the user interacts +with the element. This is implemented using `aria-label`. -## ViewStylePropTypes +**component** function, string -+ BackgroundPropTypes -+ BorderThemePropTypes -+ LayoutPropTypes -+ `boxShadow`: `string` -+ `color`: `string` -+ `opacity`: `number` +Default is `div`. -## ViewDefaultStyle +**pointerEvents** oneOf('auto', 'box-only', 'box-none', 'none') -Implements the default styles from -[facebook/css-layout](https://github.com/facebook/css-layout). +We deviate from the CSS spec by supporting additional `pointerEvents` modes, +therefore `pointerEvents` is excluded from `style`. -1. All the flex elements are oriented from top-to-bottom, left-to-right and do - not shrink. This is how things are laid out using the default CSS settings - and what you'd expect. +`box-none` is the equivalent of: -2. The most convenient way to express the relation between width and other - box-model properties. +```css +.box-none { pointer-events: none } +.box-none * { pointer-events: auto } +``` -3. Everything is `display:flex` by default. All the behaviors of `block` and - `inline-block` can be expressed in term of flex but not the opposite. +`box-only` is the equivalent of: -4. Everything is `position:relative`. This makes `position:absolute` target the - direct parent and not some parent which is either relative or absolute. If - you want to position an element relative to something else, you should move - it in the DOM instead of relying of CSS. It also makes `top`, `left`, - `right`, `bottom` do something when not specifying `position:absolute`. +```css +.box-only { pointer-events: auto } +.box-only * { pointer-events: none } +``` + +**style** style + ++ `alignContent` ++ `alignItems` ++ `alignSelf` ++ `backfaceVisibility` ++ `backgroundAttachment` ++ `backgroundClip` ++ `backgroundColor` ++ `backgroundImage` ++ `backgroundOrigin` ++ `backgroundPosition` ++ `backgroundRepeat` ++ `backgroundSize` ++ `borderColor` ++ `borderRadius` ++ `borderStyle` ++ `borderWidth` ++ `bottom` ++ `boxShadow` ++ `boxSizing` ++ `flexBasis` ++ `flexDirection` ++ `flexGrow` ++ `flexShrink` ++ `flexWrap` ++ `height` ++ `justifyContent` ++ `left` ++ `margin` ++ `maxHeight` ++ `maxWidth` ++ `minHeight` ++ `minWidth` ++ `opacity` ++ `order` ++ `overflow` ++ `overflowX` ++ `overflowY` ++ `padding` ++ `position` ++ `right` ++ `top` ++ `transform` ++ `userSelect` ++ `visibility` ++ `width` ++ `zIndex` + +Default: ```js -const ViewDefaultStyle = { - alignItems: 'stretch', // 1 +{ + alignItems: 'stretch', borderWidth: 0, borderStyle: 'solid', - boxSizing: 'border-box', // 2 - display: 'flex', // 3 - flexBasis: 'auto', // 1 - flexDirection: 'column', // 1 - flexShrink: 0, // 1 - listStyle: 'none', + boxSizing: 'border-box', + display: 'flex', + flexBasis: 'auto', + flexDirection: 'column', + flexShrink: 0, margin: 0, padding: 0, - position: 'relative' // 4 + position: 'relative' }; ``` +(See [facebook/css-layout](https://github.com/facebook/css-layout)). + +**testID** string + +Used to locate this view in end-to-end tests. + ## Examples ```js -// TODO +import React, { View } from 'react-native-web' + +const { Component, PropTypes } = React + +class Example extends Component { + render() { + return ( + + { + ['1', '2', '3', '4', '5'].map((value, i) => { + return + }) + } + + ); + } +} + +const styles = { + row: { + flexDirection: 'row' + }, + cell: { + flexGrow: 1 + } +} + +export default Example ``` diff --git a/docs/react-native-web-style/style-props.md b/docs/react-native-web-style/style-props.md deleted file mode 100644 index cf88300e..00000000 --- a/docs/react-native-web-style/style-props.md +++ /dev/null @@ -1,89 +0,0 @@ -## StyleProp spec - -### Background - -+ `backgroundColor`: `string` -+ `backgroundImage`: `string` -+ `backgroundPosition`: `string` -+ `backgroundRepeat`: `string` -+ `backgroundSize`: `string` - -### BorderTheme - -+ `borderColor`: `string` -+ `borderTopColor`: `string` -+ `borderRightColor`: `string` -+ `borderBottomColor`: `string` -+ `borderLeftColor`: `string` -+ `borderStyle`: `string` -+ `borderRadius`: `number` or `string` -+ `borderTopLeftRadius`: `number` or `string` -+ `borderTopRightRadius`: `number` or `string` -+ `borderBottomLeftRadius`: `number` or `string` -+ `borderBottomRightRadius`: `number` or `string` - -### BoxModel - -+ `borderWidth`: `number` or `string` -+ `borderTopWidth`: `number` or `string` -+ `borderRightWidth`: `number` or `string` -+ `borderBottomWidth`: `number` or `string` -+ `borderLeftWidth`: `number` or `string` -+ `boxSizing`: `oneOf('border-box', 'content-box')` -+ `display`: `oneOf('block', 'flex', 'inline', 'inline-block', 'inline-flex')` -+ `height`: `number` or `string` -+ `margin`: `number` or `string` -+ `marginTop`: `number` or `string` -+ `marginRight`: `number` or `string` -+ `marginBottom`: `number` or `string` -+ `marginLeft`: `number` or `string` -+ `padding`: `number` or `string` -+ `paddingTop`: `number` or `string` -+ `paddingRight`: `number` or `string` -+ `paddingBottom`: `number` or `string` -+ `paddingLeft`: `number` or `string` -+ `width`: `number` or `string` - -### Flexbox - -* `alignContent`: `oneOf('center', 'flex-end', 'flex-start', 'stretch', 'space-around', 'space-between')` -* `alignItems`: `oneOf('baseline', 'center', 'flex-end', 'flex-start', 'stretch')` -* `alignSelf`: `oneOf('auto', 'baseline', 'center', 'flex-end', 'flex-start', 'stretch')` -* `flex`: `string` -* `flexBasis`: `string` -* `flexDirection`: `oneOf('column', 'column-reverse', 'row', 'row-reverse')` -* `flexGrow`: `number` -* `flexShrink`: `number` -* `flexWrap`: `oneOf('nowrap', 'wrap', 'wrap-reverse')` -* `justifyContent`: `oneOf('center', 'flex-end', 'flex-start', 'space-around', 'space-between')` -* `order`: `number` - -### Layout - -* BoxModel -* Flexbox -* Position - -### Position - -* `position`: `oneOf('absolute', 'fixed', 'relative')` -* `bottom`: `number` or `string` -* `left`: `number` or `string` -* `right`: `number` or `string` -* `top`: `number` or `string` -* `zIndex`: `number` - -### Typographic - -* `direction`: `oneOf('auto', 'ltr', 'rtl')` -* `fontFamily`: `string` -* `fontSize`: `string` -* `fontWeight`: `oneOf('100', '200', '300', '400', '500', '600', '700', '800', '900', 'bold', 'normal')` -* `fontStyle`: `oneOf('normal', 'italic')` -* `letterSpacing`: `string` -* `lineHeight`: `number` or `string` -* `textAlign`: `oneOf('auto', 'left', 'right', 'center')` -* `textDecoration`: `oneOf('none', 'underline')` -* `textTransform`: `oneOf('capitalize', 'lowercase', 'none', 'uppercase')` -* `wordWrap`: `oneOf('break-word', 'normal')` - diff --git a/docs/react-native-web-style/styling.md b/docs/style.md similarity index 100% rename from docs/react-native-web-style/styling.md rename to docs/style.md