diff --git a/Examples/UIExplorer/SliderExample.js b/Examples/UIExplorer/SliderExample.js
new file mode 100644
index 000000000..0ff4f6713
--- /dev/null
+++ b/Examples/UIExplorer/SliderExample.js
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * @providesModule SliderExample
+ */
+'use strict';
+
+var React = require('react-native');
+var {
+ Slider,
+ Text,
+ StyleSheet,
+ View,
+} = React;
+
+var SliderExample = React.createClass({
+ getInitialState() {
+ return {
+ value: 0,
+ };
+ },
+
+ render() {
+ return (
+
+
+ {this.state.value}
+
+ this.setState({value: value})} />
+
+ );
+ }
+});
+
+var styles = StyleSheet.create({
+ slider: {
+ height: 10,
+ margin: 10,
+ },
+ text: {
+ fontSize: 14,
+ textAlign: 'center',
+ fontWeight: 'bold',
+ margin: 10,
+ },
+});
+
+exports.title = '';
+exports.description = 'Slider input for numeric values';
+exports.examples = [
+ {
+ title: 'Slider',
+ render() { return ; }
+ }
+];
diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js
index 277517983..e04edcab6 100644
--- a/Examples/UIExplorer/UIExplorerList.js
+++ b/Examples/UIExplorer/UIExplorerList.js
@@ -35,6 +35,7 @@ var EXAMPLES = [
require('./GeolocationExample'),
require('./TabBarExample'),
require('./SwitchExample'),
+ require('./SliderExample'),
];
var UIExplorerList = React.createClass({
diff --git a/Libraries/Components/Slider/Slider.js b/Libraries/Components/Slider/Slider.js
new file mode 100644
index 000000000..80f631c45
--- /dev/null
+++ b/Libraries/Components/Slider/Slider.js
@@ -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 (
+
+ );
+ }
+});
+
+var styles = StyleSheet.create({
+ slider: {
+ height: 40,
+ },
+});
+
+var RKSlider = createReactIOSNativeComponentClass({
+ validAttributes: merge(ReactIOSViewAttributes.UIView, {value: true}),
+ uiViewClassName: 'RCTSlider',
+});
+
+module.exports = Slider;
diff --git a/Libraries/react-native/react-native.js b/Libraries/react-native/react-native.js
index 5aafb28ce..7f7edaf72 100644
--- a/Libraries/react-native/react-native.js
+++ b/Libraries/react-native/react-native.js
@@ -18,6 +18,7 @@ var ReactNative = {
PixelRatio: require('PixelRatio'),
ScrollView: require('ScrollView'),
ActivityIndicatorIOS: require('ActivityIndicatorIOS'),
+ Slider: require('Slider'),
StatusBarIOS: require('StatusBarIOS'),
StyleSheet: require('StyleSheet'),
SwitchIOS: require('SwitchIOS'),
diff --git a/ReactKit/ReactKit.xcodeproj/project.pbxproj b/ReactKit/ReactKit.xcodeproj/project.pbxproj
index dd9a452a0..48cac5ded 100644
--- a/ReactKit/ReactKit.xcodeproj/project.pbxproj
+++ b/ReactKit/ReactKit.xcodeproj/project.pbxproj
@@ -37,6 +37,7 @@
58C571C11AA56C1900CDF9C8 /* RCTDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */; };
14F3620D1AABD06A001CE568 /* RCTSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F362081AABD06A001CE568 /* RCTSwitch.m */; };
14F3620E1AABD06A001CE568 /* RCTSwitchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */; };
+ 14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F484551AABFCE100FDF6B9 /* RCTSliderManager.m */; };
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
830BA4551A8E3BDA00D53203 /* RCTCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BA4541A8E3BDA00D53203 /* RCTCache.m */; };
832348161A77A5AA00B55238 /* Layout.c in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FC71A68125100A75B9A /* Layout.c */; };
@@ -131,6 +132,8 @@
14F362081AABD06A001CE568 /* RCTSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSwitch.m; sourceTree = ""; };
14F362091AABD06A001CE568 /* RCTSwitchManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSwitchManager.h; sourceTree = ""; };
14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSwitchManager.m; sourceTree = ""; };
+ 14F484541AABFCE100FDF6B9 /* RCTSliderManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSliderManager.h; sourceTree = ""; };
+ 14F484551AABFCE100FDF6B9 /* RCTSliderManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSliderManager.m; sourceTree = ""; };
830213F31A654E0800B993E6 /* RCTBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBridgeModule.h; sourceTree = ""; };
830A229C1A66C68A008503DA /* RCTRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootView.h; sourceTree = ""; };
830A229D1A66C68A008503DA /* RCTRootView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootView.m; sourceTree = ""; };
@@ -214,6 +217,8 @@
14F362081AABD06A001CE568 /* RCTSwitch.m */,
14F362091AABD06A001CE568 /* RCTSwitchManager.h */,
14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */,
+ 14F484541AABFCE100FDF6B9 /* RCTSliderManager.h */,
+ 14F484551AABFCE100FDF6B9 /* RCTSliderManager.m */,
13442BF21AA90E0B0037E5B0 /* RCTAnimationType.h */,
58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */,
58C571BF1AA56C1900CDF9C8 /* RCTDatePickerManager.m */,
@@ -421,6 +426,7 @@
13B0801F1A69489C00A75B9A /* RCTTextFieldManager.m in Sources */,
134FCB3D1A6E7F0800051CC8 /* RCTContextExecutor.m in Sources */,
13E067591A70F44B002CDEE1 /* UIView+ReactKit.m in Sources */,
+ 14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */,
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */,
83CBBA521A601E3B00E9B192 /* RCTLog.m in Sources */,
13B0801D1A69489C00A75B9A /* RCTNavItemManager.m in Sources */,
diff --git a/ReactKit/Views/RCTSliderManager.h b/ReactKit/Views/RCTSliderManager.h
new file mode 100644
index 000000000..1088ec569
--- /dev/null
+++ b/ReactKit/Views/RCTSliderManager.h
@@ -0,0 +1,7 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#import "RCTViewManager.h"
+
+@interface RCTSliderManager : RCTViewManager
+
+@end
diff --git a/ReactKit/Views/RCTSliderManager.m b/ReactKit/Views/RCTSliderManager.m
new file mode 100644
index 000000000..8561c0a97
--- /dev/null
+++ b/ReactKit/Views/RCTSliderManager.m
@@ -0,0 +1,43 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#import "RCTSliderManager.h"
+
+#import "RCTBridge.h"
+#import "RCTEventDispatcher.h"
+#import "UIView+ReactKit.h"
+
+@implementation RCTSliderManager
+
+- (UIView *)view
+{
+ UISlider *slider = [[UISlider alloc] init];
+ [slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
+ [slider addTarget:self action:@selector(sliderTouchEnd:) forControlEvents:UIControlEventTouchUpInside];
+ return slider;
+}
+
+- (void)sliderValueChanged:(UISlider *)sender
+{
+ NSDictionary *event = @{
+ @"target": sender.reactTag,
+ @"value": @(sender.value),
+ @"continuous": @YES,
+ };
+
+ [self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:event];
+}
+
+- (void)sliderTouchEnd:(UISlider *)sender
+{
+ NSDictionary *event = @{
+ @"target": sender.reactTag,
+ @"value": @(sender.value),
+ @"continuous": @NO,
+ };
+
+ [self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:event];
+}
+
+RCT_EXPORT_VIEW_PROPERTY(value);
+
+@end