├── .gitignore ├── README.md ├── bower.json ├── example ├── demo.gif └── index.html ├── package.json ├── react-segmented-control.css └── react-segmented-control.js /.gitignore: -------------------------------------------------------------------------------- 1 | # https://git-scm.com/docs/gitignore 2 | # https://help.github.com/articles/ignoring-files 3 | # Example .gitignore files: https://github.com/github/gitignore 4 | /bower_components/ 5 | /node_modules/ 6 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-segmented-control 2 | 3 | > Simple [React](http://facebook.github.io/react/index.html) component for a segmented control. 4 | 5 | ### [Demo](https://enki-com.github.io/react-segmented-control) 6 | 7 | [![Demo](https://cdn.rawgit.com/enki-com/react-segmented-control/master/example/demo.gif "Demo")](https://github.com/enki-com/react-segmented-control/blob/master/example/index.html) 8 | 9 | ## Install 10 | 11 | ```bash 12 | npm install react-segmented-control --save 13 | ``` 14 | 15 | or 16 | 17 | ```bash 18 | bower install react-segmented-control --save 19 | ``` 20 | 21 | ## Example 22 | 23 | Controlled usage: 24 | 25 | ```javascript 26 | var SegmentedControl = require('react-segmented-control'); 27 | 28 | var App = React.createClass({ 29 | 30 | getInitialState() { 31 | return { 32 | color: 'red' 33 | }; 34 | }, 35 | render() { 36 | return ( 37 |
38 | 42 | Red 43 | Blue 44 | 45 |
46 |
47 | ); 48 | }, 49 | 50 | colorUpdated(value) { 51 | this.setState({color: value}); 52 | } 53 | }); 54 | ``` 55 | 56 | ## API 57 | 58 | ### Props 59 | 60 | All props are optional except `name`. 61 | 62 | ##### className 63 | 64 | Class of the Component (in addition of `segmented-control`). 65 | 66 | ##### onChange 67 | 68 | Function called when the control is changed (value will be passed as an argument). 69 | 70 | ##### defaultValue or value 71 | 72 | Use defaultValue to specify an initial value. Use value to use this component as a controlled component. 73 | 74 | ##### name 75 | 76 | Name of the input. 77 | 78 | ## Styles 79 | 80 | Look at [react-segmented-control.css](https://github.com/enki-com/react-segmented-control/blob/master/react-segmented-control.css) for an idea on how to style this component. 81 | 82 | --- 83 | 84 | MIT Licensed 85 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-segmented-control", 3 | "main": [ 4 | "react-segmented-control.js", 5 | "react-segmented-control.css" 6 | ], 7 | "version": "0.2.1", 8 | "homepage": "https://github.com/enki-com/react-segmented-control", 9 | "description": "Simple react.js component for a segmented control", 10 | "keywords": [ 11 | "react", 12 | "segmented", 13 | "control", 14 | "component", 15 | "javascript", 16 | "react-component" 17 | ], 18 | "authors": [ 19 | "Mathieu Dutour " 20 | ], 21 | "license": "MIT", 22 | "ignore": [ 23 | "**/.*", 24 | "node_modules", 25 | "bower_components", 26 | "test", 27 | "tests", 28 | "example" 29 | ], 30 | "dependencies": { 31 | "react": "^0.14.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enkidevs/react-segmented-control/44ad984db96d1308211b0ea76765abab2b1f0a17/example/demo.gif -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | react-segmented-control example (without JSX) 5 | 6 | 47 | 48 | 49 |
50 | 51 | 52 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-segmented-control", 3 | "version": "0.2.2", 4 | "description": "Simple react.js component for a segmented control", 5 | "main": "react-segmented-control.js", 6 | "scripts": {}, 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/enki-com/react-segmented-control" 10 | }, 11 | "keywords": [ 12 | "react", 13 | "segmented", 14 | "control", 15 | "component", 16 | "javascript", 17 | "react-component" 18 | ], 19 | "author": "Mathieu Dutour", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/enki-com/react-segmented-control/issues" 23 | }, 24 | "homepage": "https://github.com/enki-com/react-segmented-control" 25 | } 26 | -------------------------------------------------------------------------------- /react-segmented-control.css: -------------------------------------------------------------------------------- 1 | .segmented-control { 2 | } 3 | .segmented-control input { 4 | display: none; 5 | } 6 | .segmented-control .label { 7 | text-align: center; 8 | transition: all 0.2s ease-out; 9 | } 10 | .segmented-control .label label { 11 | display: block; 12 | width: 100%; 13 | height: 100%; 14 | padding: 1em; 15 | cursor: pointer; 16 | } 17 | -------------------------------------------------------------------------------- /react-segmented-control.js: -------------------------------------------------------------------------------- 1 | ;(function (root, factory) { 2 | if (typeof module !== "undefined" && module.exports) { 3 | module.exports = factory(require("react")); 4 | } else if (typeof define === "function" && define.amd) { 5 | define(["react"], factory); 6 | } else { 7 | root.SegmentedControl = factory(root.React); 8 | } 9 | })(this, function (React) { 10 | "use strict"; 11 | 12 | var SegmentedControl = React.createClass({displayName: "SegmentedControl", 13 | propTypes: { 14 | className: React.PropTypes.string, 15 | onChange: React.PropTypes.func, 16 | defaultValue: React.PropTypes.string, 17 | value: React.PropTypes.string, 18 | name: React.PropTypes.string.isRequired 19 | }, 20 | 21 | getInitialState: function() { 22 | return { 23 | selected: this.props.value || this.props.defaultValue || 0 24 | }; 25 | }, 26 | 27 | render: function() { 28 | return ( 29 | React.createElement("div", 30 | {className: 'segmented-control ' + this.props.className}, 31 | this.props.children.map(function(child, index) { 32 | var selected = (child.props || {}).value === this.state.selected || 33 | index === this.state.selected; 34 | return ( 35 | React.createElement("div", { 36 | className: 'label' + (selected ? ' selected' : ''), 37 | key: "sc-" + this.props.name + index}, 38 | React.createElement("input", { 39 | type: "radio", 40 | name: "sc-" + this.props.name, 41 | id: "sc-" + this.props.name + index, 42 | value: (child.props || {}).value || index, 43 | checked: selected, 44 | onChange: this.handleChange}), 45 | React.createElement("label", { 46 | htmlFor: "sc-" + this.props.name + index}, 47 | child) 48 | ) 49 | ); 50 | }.bind(this)), 51 | React.createElement("div", {className: "clearFix"}) 52 | ) 53 | ); 54 | }, 55 | 56 | handleChange: function(e) { 57 | var index = e.currentTarget.value; 58 | this.setState({ 59 | selected: index 60 | }, function() { 61 | if (this.props.onChange) { 62 | this.props.onChange(index); 63 | } 64 | }.bind(this)); 65 | }, 66 | 67 | componentDidMount: function() { 68 | if (!this.props.defaultValue && this.props.onChange) { 69 | this.props.onChange(this.state.selected); 70 | } 71 | }, 72 | 73 | componentWillReceiveProps: function(nextProps) { 74 | if (nextProps.value || nextProps.defaultValue !== this.props.defaultValue) { 75 | this.setState({selected: nextProps.value || nextProps.defaultValue}); 76 | } 77 | } 78 | }); 79 | 80 | return SegmentedControl; 81 | }); 82 | --------------------------------------------------------------------------------