This repository has been archived by the owner on May 14, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* add LegendInterval and LegendCategorical * update tests * hot fix * add Slider * hot fix * add new Slider test * fix test * update Slider, add Slider tests. * Edits after the code review * add new test * fix Readme * Edits after the code review * Edits after the code review
- Loading branch information
1 parent
a23c0d9
commit c5b20b1
Showing
12 changed files
with
391 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import styled from 'react-emotion'; | ||
|
||
export default styled.div` | ||
position: relative; | ||
margin: auto; | ||
text-align: center; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import styled from 'react-emotion'; | ||
|
||
export default styled.input` | ||
width: 100%; | ||
height: 34px; | ||
-webkit-appearance: none; | ||
&::-webkit-slider-runnable-track { | ||
height: 2px; | ||
background: #000000; | ||
border: none; | ||
border-radius: 1px; | ||
} | ||
&::-webkit-slider-thumb { | ||
-webkit-appearance: none; | ||
border: none; | ||
height: 28px; | ||
width: 28px; | ||
background-color: #ffffff; | ||
border: solid 2px #000000; | ||
border-radius: 50%; | ||
margin-top: -14px; | ||
&:hover { | ||
cursor: pointer; | ||
} | ||
} | ||
// Firefox | ||
&:focus { | ||
outline: none; | ||
} | ||
&::-moz-range-track { | ||
height: 2px; | ||
background: #000000; | ||
border: none; | ||
border-radius: 1px; | ||
} | ||
&::-moz-range-thumb { | ||
-webkit-appearance: none; | ||
border: none; | ||
height: 28px; | ||
width: 28px; | ||
background-color: #ffffff; | ||
border: solid 2px #000000; | ||
border-radius: 50%; | ||
margin-top: -14px; | ||
&:hover { | ||
cursor: pointer; | ||
} | ||
} | ||
// IE | ||
/*hide the outline behind the border*/ | ||
&:-moz-focusring{ | ||
outline: 1px solid white; | ||
outline-offset: -1px; | ||
} | ||
&:focus::-moz-range-track { | ||
background: transparent; | ||
} | ||
&::-ms-track { | ||
height: 2px; | ||
background: #000000; | ||
border: none; | ||
border-radius: 1px; | ||
} | ||
&::-ms-fill-lower { | ||
background: #777; | ||
border-radius: 10px; | ||
} | ||
&::-ms-fill-upper { | ||
background: #ddd; | ||
border-radius: 10px; | ||
} | ||
&::-ms-thumb { | ||
height: 28px; | ||
width: 28px; | ||
background-color: #ffffff; | ||
border: solid 2px #000000; | ||
border-radius: 50%; | ||
margin-top: -14px; | ||
&:hover { | ||
cursor: pointer; | ||
} | ||
} | ||
&:focus::-ms-fill-lower { | ||
background: #888; | ||
} | ||
&:focus::-ms-fill-upper { | ||
background: #ccc; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import styled from 'react-emotion'; | ||
|
||
export default styled.div` | ||
display: block; | ||
border: 0; | ||
width: 100%; | ||
height: 100%; | ||
text-align: center; | ||
outline: none; | ||
cursor: pointer; | ||
&:first-child { | ||
position: relative; | ||
text-align: left; | ||
span { | ||
position: absolute; | ||
transform: translateX(-50%); | ||
} | ||
} | ||
&:last-child { | ||
position: relative; | ||
text-align: right; | ||
span { | ||
position: absolute; | ||
transform: translateX(-50%); | ||
} | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
Slider | ||
|
||
```js | ||
const options = [ | ||
{ value: 'one', label: 'One' }, | ||
{ value: 'two', label: 'Two' }, | ||
{ value: 'three', label: 'Three' } | ||
]; | ||
|
||
initialState = { value: options[0].value }; | ||
|
||
const onChange = (value) => { | ||
setState({ value }) | ||
}; | ||
|
||
<div> | ||
Current value: {state.value} | ||
<Slider | ||
onChange={onChange} | ||
options={options} | ||
value={state.value} | ||
/> | ||
</div> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import styled from 'react-emotion'; | ||
|
||
export default styled.div` | ||
display: flex; | ||
font-size: 14px; | ||
font-weight: 500; | ||
justify-content: space-between; | ||
padding: 0 12px 0 15px; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import React, { PureComponent } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
// Style | ||
import Container from './Container'; | ||
import Scale from './Scale'; | ||
import Label from './Label'; | ||
import Input from './Input'; | ||
|
||
/** | ||
* @component | ||
*/ | ||
class Slider extends PureComponent { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.state = { | ||
index: 0 | ||
}; | ||
|
||
this.onChange = this.onChange.bind(this); | ||
this.onChangeEnd = this.onChangeEnd.bind(this); | ||
this.onScaleClick = this.onScaleClick.bind(this); | ||
this._renderOption = this._renderOption.bind(this); | ||
} | ||
|
||
componentWillMount() { | ||
const { options, value } = this.props; | ||
|
||
if (!options.length) { | ||
throw new Error('options is empty'); | ||
} | ||
|
||
const index = options.findIndex(o => o.value === value); | ||
this.setState({ index }); | ||
} | ||
|
||
onChange(event) { | ||
this.setState({ index: event.target.value }); | ||
const index = Math.round(event.target.value); | ||
const { value } = this.props.options[index]; | ||
|
||
if (value !== this.props.value) { | ||
this.props.onChange(value); | ||
} | ||
} | ||
|
||
onChangeEnd(event) { | ||
const index = Math.round(event.target.value); | ||
this.setState({ index }); | ||
} | ||
|
||
onScaleClick(index) { | ||
this.setState({ index }); | ||
const { value } = this.props.options[index]; | ||
this.props.onChange(value); | ||
} | ||
|
||
_renderOption(option, index) { | ||
return ( | ||
<Label | ||
key={option.value} | ||
role="button" | ||
onClick={this.onScaleClick.bind(null, index)} | ||
> | ||
<span>{option.label}</span> | ||
</Label> | ||
); | ||
} | ||
|
||
render() { | ||
const { options } = this.props; | ||
|
||
return ( | ||
<Container> | ||
<Input | ||
type="range" | ||
value={this.state.index} | ||
onChange={this.onChange} | ||
onMouseUp={this.onChangeEnd} | ||
max={options.length - 1} | ||
step={0.01} | ||
/> | ||
<Scale length={options.length}> | ||
{options.map(this._renderOption)} | ||
</Scale> | ||
</Container> | ||
); | ||
} | ||
} | ||
|
||
Slider.propTypes = { | ||
options: PropTypes.arrayOf(PropTypes.shape({ | ||
value: PropTypes.node.isRequired, | ||
label: PropTypes.node | ||
})).isRequired, | ||
value: PropTypes.node, | ||
onChange: PropTypes.func.isRequired | ||
}; | ||
|
||
Slider.defaultProps = { | ||
value: PropTypes.null | ||
}; | ||
|
||
export default Slider; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
import toJson from 'enzyme-to-json'; | ||
import Slider from '../Slider'; | ||
import Input from '../Slider/Input'; | ||
|
||
const options = [ | ||
{ value: 'one', label: 'One' }, | ||
{ value: 'two', label: 'Two' }, | ||
{ value: 'three', label: 'Three' } | ||
]; | ||
|
||
const onChange = value => value; | ||
|
||
test('Slider does not crash', () => { | ||
const wrapper = shallow(<Slider onChange={onChange} options={options} />); | ||
expect(toJson(wrapper)).toMatchSnapshot(); | ||
}); | ||
|
||
test('Slider with an empty array', () => { | ||
expect(() => shallow(<Slider onChange={onChange} options={[]} />)) | ||
.toThrowError('options is empty'); | ||
}); | ||
|
||
test('Slider simulate onChange', () => { | ||
const wrapper = shallow(<Slider | ||
onChange={onChange} | ||
options={options} | ||
value={options[0].value} | ||
/>); | ||
const rangeInput = wrapper.find(Input).first(); | ||
expect(wrapper.state('index')).toEqual(0); | ||
rangeInput.simulate('change', { target: { value: 1 } }); | ||
expect(wrapper.state('index')).toEqual(1); | ||
}); | ||
|
||
test('Slider simulate onChangeEnd', () => { | ||
const wrapper = shallow(<Slider | ||
onChange={onChange} | ||
options={options} | ||
value={options[0].value} | ||
/>); | ||
const rangeInput = wrapper.find(Input).first(); | ||
expect(wrapper.state('index')).toEqual(0); | ||
rangeInput.simulate('change', { target: { value: 0.8 } }); | ||
rangeInput.simulate('mouseUp', { target: { value: 0.8 } }); | ||
expect(wrapper.state('index')).toEqual(1); | ||
}); | ||
|
||
test('Slider simulate onClickScale', () => { | ||
const wrapper = shallow(<Slider | ||
onChange={onChange} | ||
options={options} | ||
value={options[0].value} | ||
/>); | ||
const scaleButton = wrapper.find('[role="button"]').last(); | ||
expect(wrapper.state('index')).toEqual(0); | ||
scaleButton.simulate('click'); | ||
expect(wrapper.state('index')).toEqual(2); | ||
}); |
Oops, something went wrong.