Big Updates from Fri Mar 6

- [ReactNative] Oss RCTSlider | Tadeu Zagallo
- [ReactNative] Oss RCTSwitch | Tadeu Zagallo
- [ReactNative] Remove ImageSourcePropType | Christopher Chedeau
- [ReactNative] s/Image.sourcePropType/Image.propTypes.source/ | Christopher Chedeau
- [ReactNative] s/Text.stylePropType/Text.propTypes.style/ | Christopher Chedeau
- [ReactNative] s/View.stylePropType/View.propTypes.style/ | Christopher Chedeau
- [ReactNative] Remove nativePropTypes | Christopher Chedeau
- [ReactNative] Inline ScrollViewPropTypes | Christopher Chedeau
- [ReactNative] Unify ScrollView.android and ScrollView.ios | Christopher Chedeau
- [ReactNative] Move around and reformat comments for the documentation | Christopher Chedeau
- Improved Geolocation API | Nick Lockwood
- [React Native] Move copyProperties and mergeHelpers to github dir | Ben Alpert
- Fixed some misspellings that are propagating through our code | Skotch Vail
- [ReactNative] OSS DatePicker | Spencer Ahrens
- [React Native] Update core modules for React 0.13 | Ben Alpert
- [React Native] Update React to v0.13.0-rc2 | Ben Alpert
- [react-packager] onchange endpoint that informs of changes | Amjad Masad
- [react-packager] dev option needs to default to true for backwards compat | Amjad Masad
This commit is contained in:
Christopher Chedeau
2015-03-09 16:18:15 -07:00
parent 05ec075c94
commit cb9b1f7b29
50 changed files with 1998 additions and 653 deletions

View File

@@ -15,7 +15,6 @@ var View = require('View');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var keyMirror = require('keyMirror');
var keyOf = require('keyOf');
var merge = require('merge');
var SpinnerSize = keyMirror({

View File

@@ -0,0 +1,155 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule DatePickerIOS
*
* This is a controlled component version of RKDatePickerIOS
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var RKDatePickerIOSConsts = require('NativeModules').RKUIManager.RCTDatePicker.Constants;
var StyleSheet = require('StyleSheet');
var View = require('View');
var createReactIOSNativeComponentClass =
require('createReactIOSNativeComponentClass');
var merge = require('merge');
var DATEPICKER = 'datepicker';
/**
* Use `DatePickerIOS` to render a date/time picker (selector) on iOS. This is
* a controlled component, so you must hook in to the `onDateChange` callback
* and update the `date` prop in order for the component to update, otherwise
* the user's change will be reverted immediately to reflect `props.date` as the
* source of truth.
*/
var DatePickerIOS = React.createClass({
mixins: [NativeMethodsMixin],
propTypes: {
/**
* The currently selected date.
*/
date: PropTypes.instanceOf(Date).isRequired,
/**
* Date change handler.
*
* This is called when the user changes the date or time in the UI.
* The first and only argument is a Date object representing the new
* date and time.
*/
onDateChange: PropTypes.func.isRequired,
/**
* Maximum date.
*
* Restricts the range of possible date/time values.
*/
maximumDate: PropTypes.instanceOf(Date),
/**
* Minimum date.
*
* Restricts the range of possible date/time values.
*/
minimumDate: PropTypes.instanceOf(Date),
/**
* The date picker mode.
*
* Valid modes on iOS are: 'date', 'time', 'datetime'.
*/
mode: PropTypes.oneOf(Object.keys(RKDatePickerIOSConsts.DatePickerModes)),
/**
* The interval at which minutes can be selected.
*/
minuteInterval: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]),
/**
* Timezone offset in seconds.
*
* By default, the date picker will use the device's timezone. With this
* parameter, it is possible to force a certain timezone offset. For
* instance, to show times in Pacific Standard Time, pass -7 * 60.
*/
timeZoneOffsetInMinutes: PropTypes.number,
},
getDefaultProps: function() {
return {
mode: 'datetime',
};
},
_onChange: function(event) {
var nativeTimeStamp = event.nativeEvent.timestamp;
this.props.onDateChange && this.props.onDateChange(
new Date(nativeTimeStamp)
);
this.props.onChange && this.props.onChange(event);
// We expect the onChange* handlers to be in charge of updating our `date`
// prop. That way they can also disallow/undo/mutate the selection of
// certain values. In other words, the embedder of this component should
// be the source of truth, not the native component.
var propsTimeStamp = this.props.date.getTime();
if (nativeTimeStamp !== propsTimeStamp) {
this.refs[DATEPICKER].setNativeProps({
date: propsTimeStamp,
});
}
},
render: function() {
var props = this.props;
return (
<View style={props.style}>
<RKDatePickerIOS
ref={DATEPICKER}
style={styles.rkDatePickerIOS}
date={props.date.getTime()}
maximumDate={
props.maximumDate ? props.maximumDate.getTime() : undefined
}
minimumDate={
props.minimumDate ? props.minimumDate.getTime() : undefined
}
mode={RKDatePickerIOSConsts.DatePickerModes[props.mode]}
minuteInterval={props.minuteInterval}
timeZoneOffsetInMinutes={props.timeZoneOffsetInMinutes}
onChange={this._onChange}
/>
</View>
);
}
});
var styles = StyleSheet.create({
rkDatePickerIOS: {
height: RKDatePickerIOSConsts.ComponentHeight,
width: RKDatePickerIOSConsts.ComponentWidth,
},
});
var rkDatePickerIOSAttributes = merge(ReactIOSViewAttributes.UIView, {
date: true,
maximumDate: true,
minimumDate: true,
mode: true,
minuteInterval: true,
timeZoneOffsetInMinutes: true,
});
var RKDatePickerIOS = createReactIOSNativeComponentClass({
validAttributes: rkDatePickerIOSAttributes,
uiViewClassName: 'RCTDatePicker',
});
module.exports = DatePickerIOS;

View File

@@ -19,29 +19,42 @@ var isEmpty = require('isEmpty');
var PropTypes = React.PropTypes;
var DEFAULT_PAGE_SIZE = 1;
var DEFAULT_INITIAL_ROWS = 10;
var DEFAULT_SCROLL_RENDER_AHEAD = 1000;
var DEFAULT_END_REACHED_THRESHOLD = 1000;
var DEFAULT_SCROLL_CALLBACK_THROTTLE = 50;
var RENDER_INTERVAL = 20;
var SCROLLVIEW_REF = 'listviewscroll';
/**
* ListView - A core component designed for efficient display of vertically
* scrolling lists of changing data. The minimal API is to create a
* `ListViewDataSource`, populate it with a simple array of data blobs, and
* `ListView.DataSource`, populate it with a simple array of data blobs, and
* instantiate a `ListView` component with that data source and a `renderRow`
* callback which takes a blob from the data array and returns a renderable
* component. Minimal example:
* component.
*
* getInitialState: function() {
* var ds = new ListViewDataSource({rowHasChanged: (r1, r2) => r1 !== r2});
* return {
* dataSource: ds.cloneWithRows(['row 1', 'row 2']),
* };
* },
* Minimal example:
*
* render: function() {
* return (
* <ListView
* dataSource={this.state.dataSource}
* renderRow={(rowData) => <Text>{rowData}</Text>}
* />
* );
* },
* ```
* getInitialState: function() {
* var ds = new ListViewDataSource({rowHasChanged: (r1, r2) => r1 !== r2});
* return {
* dataSource: ds.cloneWithRows(['row 1', 'row 2']),
* };
* },
*
* render: function() {
* return (
* <ListView
* dataSource={this.state.dataSource}
* renderRow={(rowData) => <Text>{rowData}</Text>}
* />
* );
* },
* ```
*
* ListView also supports more advanced features, including sections with sticky
* section headers, header and footer support, callbacks on reaching the end of
@@ -61,19 +74,8 @@ var PropTypes = React.PropTypes;
* event-loop (customizable with the `pageSize` prop). This breaks up the
* work into smaller chunks to reduce the chance of dropping frames while
* rendering rows.
*
* Check out `ListViewSimpleExample.js`, `ListViewDataSource.js`, and the Movies
* app for more info and example usage.
*/
var DEFAULT_PAGE_SIZE = 1;
var DEFAULT_INITIAL_ROWS = 10;
var DEFAULT_SCROLL_RENDER_AHEAD = 1000;
var DEFAULT_END_REACHED_THRESHOLD = 1000;
var DEFAULT_SCROLL_CALLBACK_THROTTLE = 50;
var RENDER_INTERVAL = 20;
var SCROLLVIEW_REF = 'listviewscroll';
var ListView = React.createClass({
mixins: [ScrollResponder.Mixin, TimerMixin],

View File

@@ -19,80 +19,6 @@ var invariant = require('invariant');
var logError = require('logError');
var merge = require('merge');
/**
* NavigatorIOS wraps UIKit navigation and allows you to add back-swipe
* functionality across your app.
*
* See UIExplorerApp and NavigatorIOSExample for a full example
*
* ======================= NavigatorIOS Routes ================================
* A route is an object used to describe each page in the navigator. The first
* route is provided to NavigatorIOS as `initialRoute`:
*
* ```
* render: function() {
* return (
* <NavigatorIOS
* initialRoute={{
* component: MyView,
* title: 'My View Title',
* passProps: { myProp: 'foo' },
* }}/>
* );
* },
* ```
*
* Now MyView will be rendered by the navigator. It will recieve the route
* object in the `route` prop, a navigator, and all of the props specified in
* `passProps`.
*
* See the initialRoute propType for a complete definition of a route.
*
* ====================== NavigatorIOS Navigator ==============================
* A `navigator` is an object of navigation functions that a view can call. It
* is passed as a prop to any component rendered by NavigatorIOS.
*
* ```
* var MyView = React.createClass({
* _handleBackButtonPress: function() {
* this.props.navigator.pop();
* },
* _handleNextButtonPress: function() {
* this.props.navigator.push(nextRoute);
* },
* ...
* });
* ```
*
* A navigation object contains the following functions:
* - `push(route)` - Navigate forward to a new route
* - `pop()` - Go back one page
* - `popN(n)` - Go back N pages at once. When N=1, behavior matches `pop()`
* - `replace(route)` - Replace the route for the current page and immediately
* load the view for the new route
* - `replacePrevious(route)` - Replace the route/view for the previous page
* - `replacePreviousAndPop(route)` - Replaces the previous route/view and
* transitions back to it
* - `resetTo(route)` - Replaces the top item and popToTop
* - `popToRoute(route)` - Go back to the item for a particular route object
* - `popToTop()` - Go back to the top item
*
* Navigator functions are also available on the NavigatorIOS component:
*
* ```
* var MyView = React.createClass({
* _handleNavigationRequest: function() {
* this.refs.nav.push(otherRoute);
* },
* render: () => (
* <NavigatorIOS
* ref='nav',
* initialRoute={...}/>
* ),
* });
* ```
*
*/
var TRANSITIONER_REF = 'transitionerRef';
var PropTypes = React.PropTypes;
@@ -153,6 +79,83 @@ var NavigatorTransitionerIOS = React.createClass({
* `<NavigatorIOS>` also removes children that will no longer be needed
* (after the pop of a child has been fully completed/animated out).
*/
/**
* NavigatorIOS wraps UIKit navigation and allows you to add back-swipe
* functionality across your app.
*
* #### Routes
* A route is an object used to describe each page in the navigator. The first
* route is provided to NavigatorIOS as `initialRoute`:
*
* ```
* render: function() {
* return (
* <NavigatorIOS
* initialRoute={{
* component: MyView,
* title: 'My View Title',
* passProps: { myProp: 'foo' },
* }}
* />
* );
* },
* ```
*
* Now MyView will be rendered by the navigator. It will recieve the route
* object in the `route` prop, a navigator, and all of the props specified in
* `passProps`.
*
* See the initialRoute propType for a complete definition of a route.
*
* #### Navigator
*
* A `navigator` is an object of navigation functions that a view can call. It
* is passed as a prop to any component rendered by NavigatorIOS.
*
* ```
* var MyView = React.createClass({
* _handleBackButtonPress: function() {
* this.props.navigator.pop();
* },
* _handleNextButtonPress: function() {
* this.props.navigator.push(nextRoute);
* },
* ...
* });
* ```
*
* A navigation object contains the following functions:
*
* - `push(route)` - Navigate forward to a new route
* - `pop()` - Go back one page
* - `popN(n)` - Go back N pages at once. When N=1, behavior matches `pop()`
* - `replace(route)` - Replace the route for the current page and immediately
* load the view for the new route
* - `replacePrevious(route)` - Replace the route/view for the previous page
* - `replacePreviousAndPop(route)` - Replaces the previous route/view and
* transitions back to it
* - `resetTo(route)` - Replaces the top item and popToTop
* - `popToRoute(route)` - Go back to the item for a particular route object
* - `popToTop()` - Go back to the top item
*
* Navigator functions are also available on the NavigatorIOS component:
*
* ```
* var MyView = React.createClass({
* _handleNavigationRequest: function() {
* this.refs.nav.push(otherRoute);
* },
* render: () => (
* <NavigatorIOS
* ref="nav"
* initialRoute={...}
* />
* ),
* });
* ```
*
*/
var NavigatorIOS = React.createClass({
propTypes: {
@@ -199,7 +202,7 @@ var NavigatorIOS = React.createClass({
/**
* Styles for the navigation item containing the component
*/
wrapperStyle: View.stylePropType,
wrapperStyle: View.propTypes.style,
}).isRequired,
@@ -207,7 +210,7 @@ var NavigatorIOS = React.createClass({
* The default wrapper style for components in the navigator.
* A common use case is to set the backgroundColor for every page
*/
itemWrapperStyle: View.stylePropType,
itemWrapperStyle: View.propTypes.style,
/**
* The color used for buttons in the navigation bar

View File

@@ -5,26 +5,27 @@
*/
'use strict';
var ArrayOfPropType = require('ArrayOfPropType');
var EdgeInsetsPropType = require('EdgeInsetsPropType');
var Platform = require('Platform');
var PointPropType = require('PointPropType');
var RCTScrollView = require('NativeModules').RKUIManager.RCTScrollView;
var RCTScrollViewConsts = RCTScrollView.Constants;
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var ReactIOSTagHandles = require('ReactIOSTagHandles');
var RKScrollView = require('NativeModules').RKUIManager.RCTScrollView;
var RKScrollViewConsts = RKScrollView.Constants;
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var RKUIManager = require('NativeModulesDeprecated').RKUIManager;
var ScrollResponder = require('ScrollResponder');
var ScrollViewPropTypes = require('ScrollViewPropTypes');
var StyleSheetPropType = require('StyleSheetPropType');
var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType');
var View = require('View');
var ViewStylePropTypes = require('ViewStylePropTypes');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var deepDiffer = require('deepDiffer');
var flattenStyle = require('flattenStyle');
var insetsDiffer = require('insetsDiffer');
var invariant = require('invariant');
var merge = require('merge');
var nativePropType = require('nativePropType');
var validAttributesFromPropTypes = require('validAttributesFromPropTypes');
var pointsDiffer = require('pointsDiffer');
var PropTypes = React.PropTypes;
@@ -32,13 +33,13 @@ var SCROLLVIEW = 'ScrollView';
var INNERVIEW = 'InnerScrollView';
var keyboardDismissModeConstants = {
'none': RKScrollViewConsts.KeyboardDismissMode.None, // default
'interactive': RKScrollViewConsts.KeyboardDismissMode.Interactive,
'onDrag': RKScrollViewConsts.KeyboardDismissMode.OnDrag,
'none': RCTScrollViewConsts.KeyboardDismissMode.None, // default
'interactive': RCTScrollViewConsts.KeyboardDismissMode.Interactive,
'onDrag': RCTScrollViewConsts.KeyboardDismissMode.OnDrag,
};
/**
* `React` component that wraps platform `RKScrollView` while providing
* Component that wraps platform ScrollView while providing
* integration with touch locking "responder" system.
*
* Doesn't yet support other contained responders from blocking this scroll
@@ -46,28 +47,49 @@ var keyboardDismissModeConstants = {
*/
var ScrollView = React.createClass({
// Only for compatibility with Android which is not yet up to date,
// DO NOT ADD NEW CALL SITES!
statics: {
keyboardDismissMode: {
None: 'none',
Interactive: 'interactive',
OnDrag: 'onDrag',
},
},
propTypes: {
...ScrollViewPropTypes,
automaticallyAdjustContentInsets: PropTypes.bool, // true
contentInset: EdgeInsetsPropType, // zeros
contentOffset: PointPropType, // zeros
onScroll: PropTypes.func,
onScrollAnimationEnd: PropTypes.func,
scrollEnabled: PropTypes.bool, // tre
scrollIndicatorInsets: EdgeInsetsPropType, // zeros
showsHorizontalScrollIndicator: PropTypes.bool,
showsVerticalScrollIndicator: PropTypes.bool,
style: StyleSheetPropType(ViewStylePropTypes),
throttleScrollCallbackMS: PropTypes.number, // null
/**
* When true, the scroll view bounces horizontally when it reaches the end
* even if the content is smaller than the scroll view itself. The default
* value is true when `horizontal={true}` and false otherwise.
*/
alwaysBounceHorizontal: nativePropType(PropTypes.bool),
alwaysBounceHorizontal: PropTypes.bool,
/**
* When true, the scroll view bounces vertically when it reaches the end
* even if the content is smaller than the scroll view itself. The default
* value is false when `horizontal={true}` and true otherwise.
*/
alwaysBounceVertical: nativePropType(PropTypes.bool),
alwaysBounceVertical: PropTypes.bool,
/**
* When true, the scroll view automatically centers the content when the
* content is smaller than the scroll view bounds; when the content is
* larger than the scroll view, this property has no effect. The default
* value is false.
*/
centerContent: nativePropType(PropTypes.bool),
centerContent: PropTypes.bool,
/**
* These styles will be applied to the scroll view content container which
* wraps all of the child views. Example:
@@ -90,7 +112,7 @@ var ScrollView = React.createClass({
* - Normal: 0.998 (the default)
* - Fast: 0.9
*/
decelerationRate: nativePropType(PropTypes.number),
decelerationRate: PropTypes.number,
/**
* When true, the scroll view's children are arranged horizontally in a row
* instead of vertically in a column. The default value is false.
@@ -115,26 +137,26 @@ var ScrollView = React.createClass({
* taps, and the keyboard will not dismiss automatically. The default value
* is false.
*/
keyboardShouldPersistTaps: nativePropType(PropTypes.bool),
keyboardShouldPersistTaps: PropTypes.bool,
/**
* The maximum allowed zoom scale. The default value is 1.0.
*/
maximumZoomScale: nativePropType(PropTypes.number),
maximumZoomScale: PropTypes.number,
/**
* The minimum allowed zoom scale. The default value is 1.0.
*/
minimumZoomScale: nativePropType(PropTypes.number),
minimumZoomScale: PropTypes.number,
/**
* When true, the scroll view stops on multiples of the scroll view's size
* when scrolling. This can be used for horizontal pagination. The default
* value is false.
*/
pagingEnabled: nativePropType(PropTypes.bool),
pagingEnabled: PropTypes.bool,
/**
* When true, the scroll view scrolls to top when the status bar is tapped.
* The default value is true.
*/
scrollsToTop: nativePropType(PropTypes.bool),
scrollsToTop: PropTypes.bool,
/**
* An array of child indices determining which children get docked to the
* top of the screen when scrolling. For example, passing
@@ -142,7 +164,7 @@ var ScrollView = React.createClass({
* top of the scroll view. This property is not supported in conjunction
* with `horizontal={true}`.
*/
stickyHeaderIndices: nativePropType(ArrayOfPropType(PropTypes.number)),
stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number),
/**
* Experimental: When true, offscreen child views (whose `overflow` value is
* `hidden`) are removed from their native backing superview when offscreen.
@@ -153,7 +175,7 @@ var ScrollView = React.createClass({
/**
* The current scale of the scroll view content. The default value is 1.0.
*/
zoomScale: nativePropType(PropTypes.number),
zoomScale: PropTypes.number,
},
mixins: [ScrollResponder.Mixin],
@@ -171,7 +193,11 @@ var ScrollView = React.createClass({
},
scrollTo: function(destY, destX) {
RKUIManager.scrollTo(ReactIOSTagHandles.rootNodeIDToTag[this._rootNodeID], destX, destY);
RKUIManager.scrollTo(
ReactIOSTagHandles.rootNodeIDToTag[this._rootNodeID],
destX || 0,
destY || 0
);
},
render: function() {
@@ -223,36 +249,47 @@ var ScrollView = React.createClass({
this.props.alwaysBounceVertical :
!this.props.horizontal;
var props = merge(
this.props, {
alwaysBounceHorizontal,
alwaysBounceVertical,
keyboardDismissMode: this.props.keyboardDismissMode ?
keyboardDismissModeConstants[this.props.keyboardDismissMode] :
undefined,
style: [styles.base, this.props.style],
onTouchStart: this.scrollResponderHandleTouchStart,
onTouchMove: this.scrollResponderHandleTouchMove,
onTouchEnd: this.scrollResponderHandleTouchEnd,
onScrollBeginDrag: this.scrollResponderHandleScrollBeginDrag,
onScrollEndDrag: this.scrollResponderHandleScrollEndDrag,
onMomentumScrollBegin: this.scrollResponderHandleMomentumScrollBegin,
onMomentumScrollEnd: this.scrollResponderHandleMomentumScrollEnd,
onStartShouldSetResponder: this.scrollResponderHandleStartShouldSetResponder,
onStartShouldSetResponderCapture: this.scrollResponderHandleStartShouldSetResponderCapture,
onScrollShouldSetResponder: this.scrollResponderHandleScrollShouldSetResponder,
onScroll: this.scrollResponderHandleScroll,
onResponderGrant: this.scrollResponderHandleResponderGrant,
onResponderTerminationRequest: this.scrollResponderHandleTerminationRequest,
onResponderTerminate: this.scrollResponderHandleTerminate,
onResponderRelease: this.scrollResponderHandleResponderRelease,
onResponderReject: this.scrollResponderHandleResponderReject,
var props = {
...this.props,
alwaysBounceHorizontal,
alwaysBounceVertical,
keyboardDismissMode: this.props.keyboardDismissMode ?
keyboardDismissModeConstants[this.props.keyboardDismissMode] :
undefined,
style: [styles.base, this.props.style],
onTouchStart: this.scrollResponderHandleTouchStart,
onTouchMove: this.scrollResponderHandleTouchMove,
onTouchEnd: this.scrollResponderHandleTouchEnd,
onScrollBeginDrag: this.scrollResponderHandleScrollBeginDrag,
onScrollEndDrag: this.scrollResponderHandleScrollEndDrag,
onMomentumScrollBegin: this.scrollResponderHandleMomentumScrollBegin,
onMomentumScrollEnd: this.scrollResponderHandleMomentumScrollEnd,
onStartShouldSetResponder: this.scrollResponderHandleStartShouldSetResponder,
onStartShouldSetResponderCapture: this.scrollResponderHandleStartShouldSetResponderCapture,
onScrollShouldSetResponder: this.scrollResponderHandleScrollShouldSetResponder,
onScroll: this.scrollResponderHandleScroll,
onResponderGrant: this.scrollResponderHandleResponderGrant,
onResponderTerminationRequest: this.scrollResponderHandleTerminationRequest,
onResponderTerminate: this.scrollResponderHandleTerminate,
onResponderRelease: this.scrollResponderHandleResponderRelease,
onResponderReject: this.scrollResponderHandleResponderReject,
};
var ScrollViewClass;
if (Platform.OS === 'ios') {
ScrollViewClass = RCTScrollView;
} else if (Platform.OS === 'android') {
if (this.props.horizontal) {
ScrollViewClass = AndroidHorizontalScrollView;
} else {
ScrollViewClass = AndroidScrollView;
}
);
}
return (
<RKScrollView {...props} ref={SCROLLVIEW}>
<ScrollViewClass {...props} ref={SCROLLVIEW}>
{contentContainer}
</RKScrollView>
</ScrollViewClass>
);
}
});
@@ -267,12 +304,46 @@ var styles = StyleSheet.create({
},
});
var RKScrollView = createReactIOSNativeComponentClass({
validAttributes: merge(
ReactIOSViewAttributes.UIView,
validAttributesFromPropTypes(ScrollView.propTypes)
),
uiViewClassName: 'RCTScrollView',
});
var validAttributes = {
...ReactIOSViewAttributes.UIView,
alwaysBounceHorizontal: true,
alwaysBounceVertical: true,
automaticallyAdjustContentInsets: true,
centerContent: true,
contentInset: insetsDiffer,
contentOffset: pointsDiffer,
decelerationRate: true,
horizontal: true,
keyboardDismissMode: true,
keyboardShouldPersistTaps: true,
maximumZoomScale: true,
minimumZoomScale: true,
pagingEnabled: true,
removeClippedSubviews: true,
scrollEnabled: true,
scrollIndicatorInsets: insetsDiffer,
scrollsToTop: true,
showsHorizontalScrollIndicator: true,
showsVerticalScrollIndicator: true,
stickyHeaderIndices: deepDiffer,
throttleScrollCallbackMS: true,
zoomScale: true,
};
if (Platform.OS === 'android') {
var AndroidScrollView = createReactIOSNativeComponentClass({
validAttributes: validAttributes,
uiViewClassName: 'AndroidScrollView',
});
var AndroidHorizontalScrollView = createReactIOSNativeComponentClass({
validAttributes: validAttributes,
uiViewClassName: 'AndroidHorizontalScrollView',
});
} else if (Platform.OS === 'ios') {
var RCTScrollView = createReactIOSNativeComponentClass({
validAttributes: validAttributes,
uiViewClassName: 'RCTScrollView',
});
}
module.exports = ScrollView;

View File

@@ -1,30 +0,0 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule ScrollViewPropTypes
*/
'use strict';
var EdgeInsetsPropType = require('EdgeInsetsPropType');
var PointPropType = require('PointPropType');
var PropTypes = require('ReactPropTypes');
var StyleSheetPropType = require('StyleSheetPropType');
var ViewStylePropTypes = require('ViewStylePropTypes');
var nativePropType = require('nativePropType');
var ScrollViewPropTypes = {
automaticallyAdjustContentInsets: nativePropType(PropTypes.bool), // true
contentInset: nativePropType(EdgeInsetsPropType), // zeroes
contentOffset: nativePropType(PointPropType), // zeroes
onScroll: PropTypes.func,
onScrollAnimationEnd: PropTypes.func,
scrollEnabled: nativePropType(PropTypes.bool), // true
scrollIndicatorInsets: nativePropType(EdgeInsetsPropType), // zeros
showsHorizontalScrollIndicator: nativePropType(PropTypes.bool),
showsVerticalScrollIndicator: nativePropType(PropTypes.bool),
style: StyleSheetPropType(ViewStylePropTypes),
throttleScrollCallbackMS: nativePropType(PropTypes.number), // null
};
module.exports = ScrollViewPropTypes;

View File

@@ -0,0 +1,83 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule Slider
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheet = require('StyleSheet');
var View = require('View');
var createReactIOSNativeComponentClass =
require('createReactIOSNativeComponentClass');
var merge = require('merge');
var Slider = React.createClass({
mixins: [NativeMethodsMixin],
propTypes: {
/**
* Used to style and layout the `Slider`. See `StyleSheet.js` and
* `ViewStylePropTypes.js` for more info.
*/
style: View.propTypes.style,
/**
* Initial value of the slider. The value should be between 0 and 1.
* Default value is 0.
*
* *This is not a controlled component*, e.g. if you don't update
* the value, the component won't be reseted to it's inital value.
*/
value: PropTypes.number,
/**
* Callback continuously called while the user is dragging the slider.
*/
onValueChange: PropTypes.func,
/**
* Callback called when the user finishes changing the value (e.g. when
* the slider is released).
*/
onSlidingComplete: PropTypes.func,
},
_onValueChange: function(event) {
this.props.onChange && this.props.onChange(event);
if (event.nativeEvent.continuous) {
this.props.onValueChange &&
this.props.onValueChange(event.nativeEvent.value);
} else {
this.props.onSlidingComplete && event.nativeEvent.value !== undefined &&
this.props.onSlidingComplete(event.nativeEvent.value);
}
},
render: function() {
return (
<RKSlider
style={[styles.slider, this.props.style]}
value={this.props.value}
onChange={this._onValueChange}
/>
);
}
});
var styles = StyleSheet.create({
slider: {
height: 40,
},
});
var RKSlider = createReactIOSNativeComponentClass({
validAttributes: merge(ReactIOSViewAttributes.UIView, {value: true}),
uiViewClassName: 'RCTSlider',
});
module.exports = Slider;

View File

@@ -0,0 +1,41 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule SwitchIOS
*/
'use strict';
var React = require('React');
var StyleSheet = require('StyleSheet');
var Text = require('Text');
var View = require('View');
var DummySwitchIOS = React.createClass({
render: function() {
return (
<View style={[styles.dummySwitchIOS, this.props.style]}>
<Text style={styles.text}>SwitchIOS is not supported on this platform!</Text>
</View>
);
},
});
var styles = StyleSheet.create({
dummySwitchIOS: {
width: 120,
height: 50,
backgroundColor: '#ffbcbc',
borderWidth: 1,
borderColor: 'red',
alignItems: 'center',
justifyContent: 'center',
},
text: {
color: '#333333',
margin: 5,
fontSize: 10,
}
});
module.exports = DummySwitchIOS;

View File

@@ -0,0 +1,117 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule SwitchIOS
*
* This is a controlled component version of RKSwitch.
*/
'use strict';
var NativeMethodsMixin = require('NativeMethodsMixin');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheet = require('StyleSheet');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var merge = require('merge');
var SWITCH = 'switch';
/**
* Use `SwitchIOS` to render a boolean input on iOS. This is
* a controlled component, so you must hook in to the `onValueChange` callback
* and update the `value` prop in order for the component to update, otherwise
* the user's change will be reverted immediately to reflect `props.value` as the
* source of truth.
*/
var SwitchIOS = React.createClass({
mixins: [NativeMethodsMixin],
propTypes: {
/**
* The value of the switch, if true the switch will be turned on.
* Default value is false.
*/
value: PropTypes.bool,
/**
* If true the user won't be able to toggle the switch.
* Default value is false.
*/
disabled: PropTypes.bool,
/**
* Callback that is called when the user toggles the switch.
*/
onValueChange: PropTypes.func,
/**
* Background color when the switch is turned on.
*/
onTintColor: PropTypes.string,
/**
* Background color for the switch round button.
*/
thumbTintColor: PropTypes.string,
/**
* Background color when the switch is turned off.
*/
tintColor: PropTypes.string,
},
getDefaultProps: function() {
return {
value: false,
disabled: false,
};
},
_onChange: function(event) {
this.props.onChange && this.props.onChange(event);
this.props.onValueChange && this.props.onValueChange(event.nativeEvent.value);
// The underlying switch might have changed, but we're controlled,
// and so want to ensure it represents our value.
this.refs[SWITCH].setNativeProps({on: this.props.value});
},
render: function() {
return (
<RKSwitch
ref={SWITCH}
style={[styles.rkSwitch, this.props.style]}
enabled={!this.props.disabled}
on={this.props.value}
onChange={this._onChange}
onTintColor={this.props.onTintColor}
thumbTintColor={this.props.thumbTintColor}
tintColor={this.props.tintColor}
/>
);
}
});
var styles = StyleSheet.create({
rkSwitch: {
height: 31,
width: 51,
},
});
var rkSwitchAttributes = merge(ReactIOSViewAttributes.UIView, {
onTintColor: true,
tintColor: true,
thumbTintColor: true,
on: true,
enabled: true,
});
var RKSwitch = createReactIOSNativeComponentClass({
validAttributes: rkSwitchAttributes,
uiViewClassName: 'RCTSwitch',
});
module.exports = SwitchIOS;

View File

@@ -18,12 +18,12 @@ var merge = require('merge');
var TabBarItemIOS = React.createClass({
propTypes: {
icon: Image.sourcePropType.isRequired,
icon: Image.propTypes.source.isRequired,
onPress: React.PropTypes.func.isRequired,
selected: React.PropTypes.bool.isRequired,
badgeValue: React.PropTypes.string,
title: React.PropTypes.string,
style: View.stylePropType,
style: View.propTypes.style,
},
getInitialState: function() {

View File

@@ -26,39 +26,6 @@ var getObjectValues = require('getObjectValues');
var invariant = require('invariant');
var merge = require('merge');
/**
* <TextInput> - A foundational component for inputting text into the app via a
* keyboard. Props provide configurability for several features, such as auto-
* correction, auto-capitalization, placeholder text, and different keyboard
* types, such as a numeric keypad.
*
* The simplest use case is to plop down a `TextInput` and subscribe to the
* `onChangeText` events to read the user input. There are also other events, such
* as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple
* example:
*
* <View>
* <TextInput
* style={{height: 40, borderColor: 'gray', borderWidth: 1}}
* onChangeText={(text) => this.setState({input: text})}
* />
* <Text>{'user input: ' + this.state.input}</Text>
* </View>
*
* The `value` prop can be used to set the value of the input in order to make
* the state of the component clear, but <TextInput> does not behave as a true
* controlled component by default because all operations are asynchronous.
* Setting `value` once is like setting the default value, but you can change it
* continuously based on `onChangeText` events as well. If you really want to
* force the component to always revert to the value you are setting, you can
* set `controlled={true}`.
*
* The `multiline` prop is not supported in all releases, and some props are
* multiline only.
*
* More example code in `TextInputExample.js`.
*/
var autoCapitalizeConsts = RKUIManager.UIText.AutocapitalizationType;
var clearButtonModeConsts = RKUIManager.UITextField.clearButtonMode;
@@ -92,6 +59,39 @@ var notMultiline = {
onSubmitEditing: true,
};
/**
* A foundational component for inputting text into the app via a
* keyboard. Props provide configurability for several features, such as auto-
* correction, auto-capitalization, placeholder text, and different keyboard
* types, such as a numeric keypad.
*
* The simplest use case is to plop down a `TextInput` and subscribe to the
* `onChangeText` events to read the user input. There are also other events, such
* as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple
* example:
*
* ```
* <View>
* <TextInput
* style={{height: 40, borderColor: 'gray', borderWidth: 1}}
* onChangeText={(text) => this.setState({input: text})}
* />
* <Text>{'user input: ' + this.state.input}</Text>
* </View>
* ```
*
* The `value` prop can be used to set the value of the input in order to make
* the state of the component clear, but <TextInput> does not behave as a true
* controlled component by default because all operations are asynchronous.
* Setting `value` once is like setting the default value, but you can change it
* continuously based on `onChangeText` events as well. If you really want to
* force the component to always revert to the value you are setting, you can
* set `controlled={true}`.
*
* The `multiline` prop is not supported in all releases, and some props are
* multiline only.
*/
var TextInput = React.createClass({
propTypes: {
/**
@@ -188,7 +188,7 @@ var TextInput = React.createClass({
'always',
]),
style: Text.stylePropType,
style: Text.propTypes.style,
},
/**

View File

@@ -20,35 +20,35 @@ var keyOf = require('keyOf');
var merge = require('merge');
var onlyChild = require('onlyChild');
var DEFAULT_PROPS = {
activeOpacity: 0.8,
underlayColor: 'black',
};
/**
* TouchableHighlight - A wrapper for making views respond properly to touches.
* 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. The
* underlay comes from adding a view to the view hierarchy, which can 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.
*
* Example:
*
* renderButton: function() {
* return (
* <TouchableHighlight onPress={this._onPressButton}>
* <Image
* style={styles.button}
* source={ix('myButton')}
* />
* </View>
* );
* },
*
* More example code in TouchableExample.js, and more in-depth discussion in
* Touchable.js. See also TouchableWithoutFeedback.js.
* ```
* renderButton: function() {
* return (
* <TouchableHighlight onPress={this._onPressButton}>
* <Image
* style={styles.button}
* source={ix('myButton')}
* />
* </View>
* );
* },
* ```
*/
var DEFAULT_PROPS = {
activeOpacity: 0.8,
underlayColor: 'black',
};
var TouchableHighlight = React.createClass({
propTypes: {
...TouchableFeedbackPropType,
@@ -67,7 +67,7 @@ var TouchableHighlight = React.createClass({
* active.
*/
underlayColor: React.PropTypes.string,
style: View.stylePropType,
style: View.propTypes.style,
},
mixins: [NativeMethodsMixin, TimerMixin, Touchable.Mixin],

View File

@@ -17,25 +17,25 @@ var keyOf = require('keyOf');
var onlyChild = require('onlyChild');
/**
* TouchableOpacity - A wrapper for making views respond properly to touches.
* A wrapper for making views respond properly to touches.
* On press down, the opacity of the wrapped view is decreased, dimming it.
* This is done without actually changing the view hierarchy, and in general is
* easy to add to an app without weird side-effects. Example:
* easy to add to an app without weird side-effects.
*
* renderButton: function() {
* return (
* <TouchableOpacity onPress={this._onPressButton}>
* <Image
* style={styles.button}
* source={ix('myButton')}
* />
* </View>
* );
* },
* Example:
*
* More example code in TouchableExample.js, and more in-depth discussion in
* Touchable.js. See also TouchableHighlight.js and
* TouchableWithoutFeedback.js.
* ```
* renderButton: function() {
* return (
* <TouchableOpacity onPress={this._onPressButton}>
* <Image
* style={styles.button}
* source={ix('myButton')}
* />
* </View>
* );
* },
* ```
*/
var TouchableOpacity = React.createClass({

View File

@@ -12,8 +12,13 @@ var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
var StyleSheetPropType = require('StyleSheetPropType');
var ViewStylePropTypes = require('ViewStylePropTypes');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var stylePropType = StyleSheetPropType(ViewStylePropTypes);
/**
* <View> - The most fundamental component for building UI, `View` is a
* The most fundamental component for building UI, `View` is a
* container that supports layout with flexbox, style, some touch handling, and
* accessibility controls, and is designed to be nested inside other views and
* to have 0 to many children of any type. `View` maps directly to the native
@@ -21,11 +26,13 @@ var ViewStylePropTypes = require('ViewStylePropTypes');
* `UIView`, `<div>`, `android.view`, etc. This example creates a `View` that
* wraps two colored boxes and custom component in a row with padding.
*
* <View style={{flexDirection: 'row', height: 100, padding: 20}}>
* <View style={{backgroundColor: 'blue', flex: 0.3}} />
* <View style={{backgroundColor: 'red', flex: 0.5}} />
* <MyCustomComponent {...customProps} />
* </View>
* ```
* <View style={{flexDirection: 'row', height: 100, padding: 20}}>
* <View style={{backgroundColor: 'blue', flex: 0.3}} />
* <View style={{backgroundColor: 'red', flex: 0.5}} />
* <MyCustomComponent {...customProps} />
* </View>
* ```
*
* By default, `View`s have a primary flex direction of 'column', so children
* will stack up vertically by default. `View`s also expand to fill the parent
@@ -39,20 +46,8 @@ var ViewStylePropTypes = require('ViewStylePropTypes');
* `View`s are designed to be used with `StyleSheet`s for clarity and
* performance, although inline styles are also supported. It is common for
* `StyleSheet`s to be combined dynamically. See `StyleSheet.js` for more info.
*
* Check out `ViewExample.js`, `LayoutExample.js`, and other apps for more code
* examples.
*/
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var stylePropType = StyleSheetPropType(ViewStylePropTypes);
var View = React.createClass({
statics: {
stylePropType,
},
mixins: [NativeMethodsMixin],
/**
@@ -141,12 +136,12 @@ var RKView = createReactIOSNativeComponentClass({
validAttributes: ReactIOSViewAttributes.RKView,
uiViewClassName: 'RCTView',
});
RKView.propTypes = View.propTypes;
var ViewToExport = RKView;
if (__DEV__) {
ViewToExport = View;
}
ViewToExport.stylePropType = stylePropType;
module.exports = ViewToExport;