react-radio-group
Advanced tools
Comparing version 1.1.0 to 2.0.0
83
index.js
@@ -1,80 +0,3 @@ | ||
/** | ||
* @jsx React.DOM | ||
*/ | ||
var React = require('react'); | ||
var RadioGroup = React.createClass({displayName: 'RadioGroup', | ||
getInitialState: function() { | ||
// check the first block of comment in `setCheckedRadio` | ||
return {defaultValue: this.props.defaultValue}; | ||
}, | ||
componentDidMount: function() { | ||
this.setRadioNames(); | ||
this.setCheckedRadio(); | ||
}, | ||
componentDidUpdate: function() { | ||
this.setRadioNames(); | ||
this.setCheckedRadio(); | ||
}, | ||
render: function() { | ||
return ( | ||
React.createElement("div", React.__spread({}, this.props, {onChange: this.props.onChange}), | ||
this.props.children | ||
) | ||
); | ||
}, | ||
setRadioNames: function() { | ||
// stay DRY and don't put the same `name` on all radios manually. Put it on | ||
// the tag and it'll be done here | ||
var $radios = this.getRadios(); | ||
for (var i = 0, length = $radios.length; i < length; i++) { | ||
$radios[i].setAttribute('name', this.props.name); | ||
} | ||
}, | ||
getRadios: function() { | ||
return this.getDOMNode().querySelectorAll('input[type="radio"]'); | ||
}, | ||
setCheckedRadio: function() { | ||
var $radios = this.getRadios(); | ||
// if `value` is passed from parent, always use that value. This is similar | ||
// to React's controlled component. If `defaultValue` is used instead, | ||
// subsequent updates to defaultValue are ignored. Note: when `defaultValue` | ||
// and `value` are both passed, the latter takes precedence, just like in | ||
// a controlled component | ||
var destinationValue = this.props.value != null | ||
? this.props.value | ||
: this.state.defaultValue; | ||
for (var i = 0, length = $radios.length; i < length; i++) { | ||
var $radio = $radios[i]; | ||
// intentionally use implicit conversion for those who accidentally used, | ||
// say, `valueToChange` of 1 (integer) to compare it with `value` of "1" | ||
// (auto conversion to valid html value from React) | ||
if ($radio.value == destinationValue) { | ||
$radio.checked = true; | ||
} | ||
} | ||
}, | ||
getCheckedValue: function() { | ||
var $radios = this.getRadios(); | ||
for (var i = 0, length = $radios.length; i < length; i++) { | ||
if ($radios[i].checked) { | ||
return $radios[i].value; | ||
} | ||
} | ||
return null; | ||
} | ||
}); | ||
module.exports = RadioGroup; | ||
// /lib contains the transpiled code. It's ignored by git but picked up by | ||
// npm publish. See package.json's "prerelease" and "build" scripts | ||
module.exports = require('./lib/'); |
@@ -1,77 +0,36 @@ | ||
/** | ||
* @jsx React.DOM | ||
*/ | ||
'use strict'; | ||
var React = require('react'); | ||
let React = require('react'); | ||
let p = React.PropTypes; | ||
var RadioGroup = React.createClass({ | ||
getInitialState: function() { | ||
// check the first block of comment in `setCheckedRadio` | ||
return {defaultValue: this.props.defaultValue}; | ||
}, | ||
function radio(name, selectedValue, onChange) { | ||
return React.createClass({ | ||
render: function() { | ||
return ( | ||
<input | ||
{...this.props} | ||
type="radio" | ||
name={name} | ||
checked={this.props.value === selectedValue} | ||
onChange={onChange.bind(null, this.props.value)} /> | ||
); | ||
} | ||
}); | ||
} | ||
componentDidMount: function() { | ||
this.setRadioNames(); | ||
this.setCheckedRadio(); | ||
let RadioGroup = React.createClass({ | ||
propTypes: { | ||
name: p.string, | ||
selectedValue: p.oneOfType([p.string, p.number]), | ||
onChange: p.func, | ||
children: p.func, | ||
}, | ||
componentDidUpdate: function() { | ||
this.setRadioNames(); | ||
this.setCheckedRadio(); | ||
}, | ||
render: function() { | ||
let {name, selectedValue, onChange, children} = this.props; | ||
return ( | ||
<div {...this.props} onChange={this.props.onChange}> | ||
{this.props.children} | ||
<div> | ||
{children && children(radio(name, selectedValue, onChange))} | ||
</div> | ||
); | ||
}, | ||
setRadioNames: function() { | ||
// stay DRY and don't put the same `name` on all radios manually. Put it on | ||
// the tag and it'll be done here | ||
var $radios = this.getRadios(); | ||
for (var i = 0, length = $radios.length; i < length; i++) { | ||
$radios[i].setAttribute('name', this.props.name); | ||
} | ||
}, | ||
getRadios: function() { | ||
return this.getDOMNode().querySelectorAll('input[type="radio"]'); | ||
}, | ||
setCheckedRadio: function() { | ||
var $radios = this.getRadios(); | ||
// if `value` is passed from parent, always use that value. This is similar | ||
// to React's controlled component. If `defaultValue` is used instead, | ||
// subsequent updates to defaultValue are ignored. Note: when `defaultValue` | ||
// and `value` are both passed, the latter takes precedence, just like in | ||
// a controlled component | ||
var destinationValue = this.props.value != null | ||
? this.props.value | ||
: this.state.defaultValue; | ||
for (var i = 0, length = $radios.length; i < length; i++) { | ||
var $radio = $radios[i]; | ||
// intentionally use implicit conversion for those who accidentally used, | ||
// say, `valueToChange` of 1 (integer) to compare it with `value` of "1" | ||
// (auto conversion to valid html value from React) | ||
if ($radio.value == destinationValue) { | ||
$radio.checked = true; | ||
} | ||
} | ||
}, | ||
getCheckedValue: function() { | ||
var $radios = this.getRadios(); | ||
for (var i = 0, length = $radios.length; i < length; i++) { | ||
if ($radios[i].checked) { | ||
return $radios[i].value; | ||
} | ||
} | ||
return null; | ||
} | ||
@@ -78,0 +37,0 @@ }); |
{ | ||
"name": "react-radio-group", | ||
"version": "1.1.0", | ||
"description": "A group of radio buttons for React", | ||
"version": "2.0.0", | ||
"description": "Better radio buttons.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"LOL EVERYTHING IS FINE\"", | ||
"prepublish": "jsx index.jsx > index.js" | ||
"example": "npm run build && webpack -d", | ||
"build": "babel index.jsx --out-dir=lib", | ||
"prerelease": "npm run build" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/jergason/react-radio-group.git" | ||
"url": "https://github.com/chenglou/react-radio-group.git" | ||
}, | ||
"keywords": [ | ||
"facebook", | ||
"react", | ||
"radio-buttons", | ||
"radio", | ||
"radio-group", | ||
"component", | ||
"browser" | ||
"react-component" | ||
], | ||
"author": "Jamison Dance <jergason@gmail.com> (http://jamisondance.com)", | ||
"license": "ISC", | ||
"devDependencies": { | ||
"babel": "^5.5.8", | ||
"babel-core": "^5.2.17", | ||
"babel-loader": "^5.0.0", | ||
"webpack": "^1.8.11" | ||
}, | ||
"author": "chenglou <chenglou92@gmail.com>", | ||
"contributors": [{ | ||
"name": "Jamison Dance", | ||
"email": "jergason@gmail.com", | ||
"url": "http://jamisondance.com" | ||
}], | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/jergason/react-radio-group/issues" | ||
"url": "https://github.com/chenglou/react-radio-group/issues" | ||
}, | ||
"homepage": "https://github.com/jergason/react-radio-group" | ||
} | ||
"homepage": "https://github.com/chenglou/react-radio-group", | ||
"peerDependencies": { | ||
"react": ">=0.13.0" | ||
} | ||
} |
122
README.md
# [React](http://facebook.github.io/react/)-radio-group | ||
This is a fork of | ||
[https://github.com/chenglou/react-radio-group](https://github.com/chenglou/react-radio-group) | ||
updated to work with npm and commonjs. | ||
``` | ||
npm install react-radio-group | ||
``` | ||
This is your average radios group: | ||
This is your average radio buttons group: | ||
```html | ||
```js | ||
<form> | ||
@@ -17,96 +17,36 @@ <input type="radio" name="fruit" value="apple" />Apple | ||
Repetitive, hard to manipulate and easily desynchronized. | ||
Lift up `name`, give the group an initial checked value, and optionally remove the form tag: | ||
A few problems: | ||
- Repetitive fields (`name`, `type`, `checked`, `onChange`). | ||
- Hard to set the checked value. You need to put e.g. `checked={'apple' === this.state.selectedFruitName}` on every input. | ||
- Hard to retrieve the selected value. | ||
```html | ||
<RadioGroup name="fruit" value="orange"> | ||
<input type="radio" value="apple" />Apple | ||
<input type="radio" value="orange" />Orange | ||
<input type="radio" value="watermelon" />Watermelon | ||
Here's a better version (full example [here](https://github.com/chenglou/react-radio-group/blob/5019ce724e4bb8c9aca35c11c20f7800995c2bcb/example/example.jsx)) | ||
```js | ||
<RadioGroup name="fruit" selectedValue={this.state.selectedValue} onChange={this.handleChange}> | ||
{Radio => ( | ||
<div> | ||
<Radio value="apple" />Apple | ||
<Radio value="orange" />Orange | ||
<Radio value="watermelon" />Watermelon | ||
</div> | ||
)} | ||
</RadioGroup> | ||
``` | ||
Listen for changes, get the new value as intuitively as possible: | ||
Repetitive fields are either lifted onto the `RadioGroup` wrapper or already implicitly set on the `Radio` component, which is a simple wrapper around the radio `input`. | ||
```html | ||
<RadioGroup name="fruit" value="orange" ref="fruitsGroup" onChange={this.handleChange}> | ||
// further... | ||
## Formal API | ||
#### <RadioGroup /> | ||
Exposes [4 optional props](https://github.com/chenglou/react-radio-group/blob/7a9b0fb4c82dd70d09e01ca6dcc64a1194d7219d/index.jsx#L23-L26): | ||
- `name: String`: what you'd normally put on the radio inputs themselves. | ||
- `selectedValue: String | Number`: the currently selected value. This will be used to compare against the values on the `Radio` components to select the right one. | ||
- `onChange: Function`: will be passed the newly selected value. | ||
- `children: Function`: will be passed a `Radio` component (a thin wrapper around `input`) some fields like `type`, `name` and `checked` already set. | ||
this.refs.fruitsGroup.getCheckedValue(); // => whatever's currently checked | ||
// handleChange is also passed the native onChange event, whose value | ||
// resides in event.target.value (see example below) | ||
``` | ||
#### <Radio /> | ||
(Since you're getting that as the argument of your children function, you could have named it anything you wanted really.) Any prop you pass onto it will be transferred to the actual `input` under the hood. | ||
That's it for the API! See below for a complete example. | ||
## Install | ||
```sh | ||
bower install react-radio-group | ||
``` | ||
Simply drop the script somewhere on your page (after React of course): | ||
```html | ||
<script src="path/to/react-radio-group.js"></script> | ||
``` | ||
## Example | ||
Demo's almost as long as the whole [source code](https://github.com/chenglou/react-radiogroup/blob/master/react-radiogroup.jsx). | ||
```html | ||
/** | ||
* @jsx React.DOM | ||
*/ | ||
var Demo = React.createClass({ | ||
getInitialState: function() { | ||
return {value: 'celery'}; | ||
}, | ||
componentDidMount: function() { | ||
// change the selected radio to "Potato" in one second | ||
setTimeout(function() { | ||
this.setState({value: 'potato'}); | ||
}.bind(this), 1000); | ||
}, | ||
render: function() { | ||
// the radios can be arbitrarily deep. They will always be fetched and | ||
// attached the `name` attribute correctly. `value` is optional | ||
return ( | ||
<RadioGroup | ||
name="veggy" | ||
value={this.state.value} | ||
ref="veggiesGroup" | ||
onChange={this.handleChange} | ||
> | ||
<div> | ||
<label> | ||
<input type="radio" value="celery"/>Celery | ||
</label> | ||
<label> | ||
<input type="radio" value="potato"/>Potato | ||
</label> | ||
<label> | ||
<input type="radio" value="broccoli"/>Broccoli | ||
</label> | ||
</div> | ||
</RadioGroup> | ||
); | ||
}, | ||
handleChange: function(event) { | ||
// will return the currently selected radio's value, or null if none | ||
// alternatively, use the passed parameter `event` | ||
var selectedVeggy = this.refs.veggiesGroup.getCheckedValue(); | ||
var sameVeggy = event.target.value; | ||
} | ||
}); | ||
React.renderComponent(<Demo/>, document.body); | ||
``` | ||
## License | ||
MIT. | ||
[MIT](./LICENSE) |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
9
6926
1
4
90
52
2