mirror of
https://github.com/wassname/slider.git
synced 2026-09-11 12:42:49 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5de9b0dbc | ||
|
|
37d32ae71c | ||
|
|
f339db494b | ||
|
|
c097b8f761 | ||
|
|
10244cf01b | ||
|
|
e8a86b91e2 | ||
|
|
05dafc0f10 | ||
|
|
5dbde43da8 | ||
|
|
0a23a67f31 |
@@ -88,11 +88,17 @@ ReactDOM.render(<Rcslider />, container);
|
|||||||
<td>100</td>
|
<td>100</td>
|
||||||
<td>The maximum value of the slider</td>
|
<td>The maximum value of the slider</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>marks</td>
|
||||||
|
<td>object {number: string}</td>
|
||||||
|
<td>{}</td>
|
||||||
|
<td>Mark on the slider. The key determines the position, and the value determines what will show.</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>step</td>
|
<td>step</td>
|
||||||
<td>number</td>
|
<td>number or `null`</td>
|
||||||
<td>1</td>
|
<td>1</td>
|
||||||
<td>Value to be added or subtracted on each step the slider makes. Must be greater than zero. max - min should be evenly divisible by the step value.</td>
|
<td>Value to be added or subtracted on each step the slider makes. Must be greater than zero. max - min should be evenly divisible by the step value. When `marks` is not an empty object, `step` can be set to `null`, to make marks as steps.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>range</td>
|
<td>range</td>
|
||||||
@@ -112,35 +118,17 @@ ReactDOM.render(<Rcslider />, container);
|
|||||||
<td></td>
|
<td></td>
|
||||||
<td>Set current positions of handles. If range is `false`, the type of `defaultValue` should be `number`. Otherwise, `[number, number]`</td>
|
<td>Set current positions of handles. If range is `false`, the type of `defaultValue` should be `number`. Otherwise, `[number, number]`</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>marks</td>
|
|
||||||
<td>array</td>
|
|
||||||
<td>[]</td>
|
|
||||||
<td>Mark every step for the slider, it will ignore the `step` parameter if it has been defined. Does not work with `range`</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>included</td>
|
<td>included</td>
|
||||||
<td>boolean</td>
|
<td>boolean</td>
|
||||||
<td>true</td>
|
<td>true</td>
|
||||||
<td>If the value is `true`, it means a continuous value interval, otherwise, it is a independent value.</td>
|
<td>If the value is `true`, it means a continuous value interval, otherwise, it is a independent value.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>defaultIndex</td>
|
|
||||||
<td>number</td>
|
|
||||||
<td>0</td>
|
|
||||||
<td>For step or marks slider, determines the initial position of the handle. Does not work with `range`</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>index</td>
|
|
||||||
<td>number</td>
|
|
||||||
<td></td>
|
|
||||||
<td>For step or marks slider, determines current position of the handle. Does not work with `range`</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>disabled</td>
|
<td>disabled</td>
|
||||||
<td>boolean</td>
|
<td>boolean</td>
|
||||||
<td>false</td>
|
<td>false</td>
|
||||||
<td>If true the handles can't be moved.</td>
|
<td>If `true`, handles can't be moved.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>tipTransitionName</td>
|
<td>tipTransitionName</td>
|
||||||
@@ -150,7 +138,7 @@ ReactDOM.render(<Rcslider />, container);
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>tipFormatter</td>
|
<td>tipFormatter</td>
|
||||||
<td>func</td>
|
<td>function</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>Format the value of the tooltip if it shows.</td>
|
<td>Format the value of the tooltip if it shows.</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -158,7 +146,7 @@ ReactDOM.render(<Rcslider />, container);
|
|||||||
<td>dots</td>
|
<td>dots</td>
|
||||||
<td>bool</td>
|
<td>bool</td>
|
||||||
<td>false</td>
|
<td>false</td>
|
||||||
<td>For linear slider, when the `step` value is greater than 1, you can set the `dots` to `true` if you want to render the slider bar with dots.</td>
|
<td>When the `step` value is greater than 1, you can set the `dots` to `true` if you want to render the slider with dots.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
+3
-3
@@ -22,11 +22,11 @@ var log = function(value) {
|
|||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<div>
|
<div>
|
||||||
<div style={style}>
|
<div style={style}>
|
||||||
<p>Slider with marks, `included=true`</p>
|
<p>Slider with marks, `step=null`</p>
|
||||||
<Slider min={-10} marks={marks} onChange={log} defaultValue={20} />
|
<Slider min={-10} marks={marks} step={null} onChange={log} defaultValue={20} />
|
||||||
</div>
|
</div>
|
||||||
<div style={style}>
|
<div style={style}>
|
||||||
<p>Slider with marks and steps, `included=true`</p>
|
<p>Slider with marks and steps</p>
|
||||||
<Slider min={-10} marks={marks} step={10} onChange={log} defaultValue={20} />
|
<Slider min={-10} marks={marks} step={10} onChange={log} defaultValue={20} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rc-slider",
|
"name": "rc-slider",
|
||||||
"version": "3.0.1",
|
"version": "3.1.1",
|
||||||
"description": "slider ui component for react",
|
"description": "slider ui component for react",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { classSet } from 'rc-util';
|
||||||
|
|
||||||
|
function calcPoints(marks, dots, step, min, max) {
|
||||||
|
const points = Object.keys(marks).map(parseFloat);
|
||||||
|
if (dots) {
|
||||||
|
for (let i = min; i <= max; i = i + step) {
|
||||||
|
points.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Dots = ({prefixCls, marks, dots, step, included, lowerBound, upperBound, max, min}) => {
|
||||||
|
const range = max - min;
|
||||||
|
const elements = calcPoints(marks, dots, step, min, max).map((point) => {
|
||||||
|
const offset = (point - min) / range * 100 + '%';
|
||||||
|
const style = { left: offset };
|
||||||
|
|
||||||
|
const isActived = (!included && point === upperBound) ||
|
||||||
|
(included && point <= upperBound && point >= lowerBound);
|
||||||
|
const pointClassName = classSet({
|
||||||
|
[prefixCls + '-dot']: true,
|
||||||
|
[prefixCls + '-dot-active']: isActived,
|
||||||
|
});
|
||||||
|
|
||||||
|
return <span className={pointClassName} style={style} key={point} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
return <div className={prefixCls + '-step'}>{elements}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dots;
|
||||||
+3
-3
@@ -5,7 +5,7 @@ const Marks = ({className, marks, included, upperBound, lowerBound, max, min}) =
|
|||||||
const marksKeys = Object.keys(marks);
|
const marksKeys = Object.keys(marks);
|
||||||
const marksCount = marksKeys.length;
|
const marksCount = marksKeys.length;
|
||||||
const unit = 100 / (marksCount - 1);
|
const unit = 100 / (marksCount - 1);
|
||||||
const markWidth = unit / 2 + '%';
|
const markWidth = unit * 0.9;
|
||||||
|
|
||||||
const range = max - min;
|
const range = max - min;
|
||||||
const elements = marksKeys.map(parseFloat).map((point) => {
|
const elements = marksKeys.map(parseFloat).map((point) => {
|
||||||
@@ -16,8 +16,8 @@ const Marks = ({className, marks, included, upperBound, lowerBound, max, min}) =
|
|||||||
[className + '-text-active']: isActived,
|
[className + '-text-active']: isActived,
|
||||||
});
|
});
|
||||||
|
|
||||||
const style = { width: markWidth };
|
const style = { width: markWidth + '%' };
|
||||||
style.left = (point - min) / range * 100 - unit / 4 + '%';
|
style.left = (point - min) / range * 100 - markWidth / 2 + '%';
|
||||||
|
|
||||||
return (<span className={markClassName} style={style} key={point}>
|
return (<span className={markClassName} style={style} key={point}>
|
||||||
{marks[point]}
|
{marks[point]}
|
||||||
|
|||||||
+33
-47
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import {Dom as DomUtils, classSet} from 'rc-util';
|
import {Dom as DomUtils, classSet} from 'rc-util';
|
||||||
import Track from './Track';
|
import Track from './Track';
|
||||||
import Handle from './Handle';
|
import Handle from './Handle';
|
||||||
import Steps from './Steps';
|
import Dots from './Dots';
|
||||||
import Marks from './Marks';
|
import Marks from './Marks';
|
||||||
|
|
||||||
function noop() {
|
function noop() {
|
||||||
@@ -25,10 +25,6 @@ function pauseEvent(e) {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmpty(collection) {
|
|
||||||
return Object.keys(collection).length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Slider extends React.Component {
|
class Slider extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -191,17 +187,6 @@ class Slider extends React.Component {
|
|||||||
return this.props.range ? [lowerBound, upperBound] : upperBound;
|
return this.props.range ? [lowerBound, upperBound] : upperBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPoints() {
|
|
||||||
const {marks, step, min, max} = this.props;
|
|
||||||
const points = Object.keys(marks);
|
|
||||||
if (isEmpty(marks) || step > 1) {
|
|
||||||
for (let i = min; i <= max; i = i + step) {
|
|
||||||
points.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSliderLength() {
|
getSliderLength() {
|
||||||
const slider = this.refs.slider;
|
const slider = this.refs.slider;
|
||||||
if (!slider) {
|
if (!slider) {
|
||||||
@@ -221,7 +206,7 @@ class Slider extends React.Component {
|
|||||||
trimAlignValue(v) {
|
trimAlignValue(v) {
|
||||||
const state = this.state || {};
|
const state = this.state || {};
|
||||||
const {handle, lowerBound, upperBound} = state;
|
const {handle, lowerBound, upperBound} = state;
|
||||||
const {min, max} = this.props;
|
const {marks, step, min, max} = this.props;
|
||||||
|
|
||||||
let val = v;
|
let val = v;
|
||||||
if (val <= min) {
|
if (val <= min) {
|
||||||
@@ -237,7 +222,12 @@ class Slider extends React.Component {
|
|||||||
val = upperBound;
|
val = upperBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
const points = this.getPoints().map(parseFloat);
|
const points = Object.keys(marks).map(parseFloat);
|
||||||
|
if (step !== null) {
|
||||||
|
const closestStep = Math.round(val / step) * step;
|
||||||
|
points.push(closestStep);
|
||||||
|
}
|
||||||
|
|
||||||
const diffs = points.map((point) => Math.abs(val - point));
|
const diffs = points.map((point) => Math.abs(val - point));
|
||||||
const closestPoint = points[diffs.indexOf(Math.min.apply(Math, diffs))];
|
const closestPoint = points[diffs.indexOf(Math.min.apply(Math, diffs))];
|
||||||
|
|
||||||
@@ -273,7 +263,7 @@ class Slider extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeEventons(type) {
|
removeEvents(type) {
|
||||||
if (type === 'touch') {
|
if (type === 'touch') {
|
||||||
this.onTouchMoveListener.remove();
|
this.onTouchMoveListener.remove();
|
||||||
this.onTouchUpListener.remove();
|
this.onTouchUpListener.remove();
|
||||||
@@ -284,54 +274,50 @@ class Slider extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
end(type) {
|
end(type) {
|
||||||
this.removeEventons(type);
|
this.removeEvents(type);
|
||||||
this.props.onAfterChange(this.getValue());
|
this.props.onAfterChange(this.getValue());
|
||||||
this.setState({handle: null});
|
this.setState({handle: null});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {handle, upperBound, lowerBound} = this.state;
|
const {handle, upperBound, lowerBound} = this.state;
|
||||||
const {className, prefixCls, disabled, dots, included, range,
|
const {className, prefixCls, disabled, dots, included, range, step,
|
||||||
marks, max, min, tipTransitionName, tipFormatter, children} = this.props;
|
marks, max, min, tipTransitionName, tipFormatter, children} = this.props;
|
||||||
const marksCount = Object.keys(marks).length;
|
|
||||||
|
const upperOffset = this.calcOffset(upperBound);
|
||||||
|
const lowerOffset = this.calcOffset(lowerBound);
|
||||||
|
|
||||||
|
const handleClassName = prefixCls + '-handle';
|
||||||
|
const isNoTip = (step === null) && !tipFormatter;
|
||||||
|
|
||||||
|
const upper = (<Handle className={handleClassName}
|
||||||
|
noTip={isNoTip} tipTransitionName={tipTransitionName} tipFormatter={tipFormatter}
|
||||||
|
offset={upperOffset} value={upperBound} dragging={handle === 'upperBound'} />);
|
||||||
|
|
||||||
|
let lower = null;
|
||||||
|
if (range) {
|
||||||
|
lower = (<Handle className={handleClassName}
|
||||||
|
noTip={isNoTip} tipTransitionName={tipTransitionName} tipFormatter={tipFormatter}
|
||||||
|
offset={lowerOffset} value={lowerBound} dragging={handle === 'lowerBound'} />);
|
||||||
|
}
|
||||||
|
|
||||||
const sliderClassName = classSet({
|
const sliderClassName = classSet({
|
||||||
[prefixCls]: true,
|
[prefixCls]: true,
|
||||||
[prefixCls + '-disabled']: disabled,
|
[prefixCls + '-disabled']: disabled,
|
||||||
[className]: !!className,
|
[className]: !!className,
|
||||||
});
|
});
|
||||||
|
|
||||||
const upperOffset = this.calcOffset(upperBound);
|
|
||||||
const lowerOffset = this.calcOffset(lowerBound);
|
|
||||||
|
|
||||||
let track = null;
|
|
||||||
if (included || range) {
|
|
||||||
const trackClassName = prefixCls + '-track';
|
|
||||||
track = <Track className={trackClassName} offset={lowerOffset} length={upperOffset - lowerOffset}/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleClassName = prefixCls + '-handle';
|
|
||||||
const isNoTip = (marksCount > 0) && !tipFormatter;
|
|
||||||
const upper = (<Handle className={handleClassName} tipTransitionName={tipTransitionName} noTip={isNoTip} tipFormatter={tipFormatter}
|
|
||||||
offset={upperOffset} value={upperBound} dragging={handle === 'upperBound'} />);
|
|
||||||
|
|
||||||
let lower = null;
|
|
||||||
if (range) {
|
|
||||||
lower = (<Handle className={handleClassName} tipTransitionName={tipTransitionName} noTip={isNoTip} tipFormatter={tipFormatter}
|
|
||||||
offset={lowerOffset} value={lowerBound} dragging={handle === 'lowerBound'} />);
|
|
||||||
}
|
|
||||||
|
|
||||||
const isIncluded = included || range;
|
const isIncluded = included || range;
|
||||||
return (
|
return (
|
||||||
<div ref="slider" className={sliderClassName}
|
<div ref="slider" className={sliderClassName}
|
||||||
onTouchStart={disabled ? noop : this.onTouchStart.bind(this)}
|
onTouchStart={disabled ? noop : this.onTouchStart.bind(this)}
|
||||||
onMouseDown={disabled ? noop : this.onMouseDown.bind(this)}>
|
onMouseDown={disabled ? noop : this.onMouseDown.bind(this)}>
|
||||||
{track}
|
|
||||||
{upper}
|
{upper}
|
||||||
{lower}
|
{lower}
|
||||||
<Steps prefixCls={prefixCls} points={this.getPoints()} dots={dots}
|
<Track className={prefixCls + '-track'} included={isIncluded}
|
||||||
included={isIncluded} lowerBound={lowerBound}
|
offset={lowerOffset} length={upperOffset - lowerOffset}/>
|
||||||
upperBound={upperBound} max={max} min={min} />
|
<Dots prefixCls={prefixCls} marks={marks} dots={dots} step={step}
|
||||||
|
included={isIncluded} lowerBound={lowerBound}
|
||||||
|
upperBound={upperBound} max={max} min={min} />
|
||||||
<Marks className={prefixCls + '-mark'} marks={marks}
|
<Marks className={prefixCls + '-mark'} marks={marks}
|
||||||
included={isIncluded} lowerBound={lowerBound}
|
included={isIncluded} lowerBound={lowerBound}
|
||||||
upperBound={upperBound} max={max} min={min} />
|
upperBound={upperBound} max={max} min={min} />
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { classSet } from 'rc-util';
|
|
||||||
|
|
||||||
const Steps = ({prefixCls, points, dots, included, lowerBound, upperBound, max, min}) => {
|
|
||||||
const range = max - min;
|
|
||||||
const elements = points.filter((point) => typeof point === 'string' || dots).map(parseFloat)
|
|
||||||
.map((point) => {
|
|
||||||
const offset = (point - min) / range * 100 + '%';
|
|
||||||
const style = { left: offset };
|
|
||||||
|
|
||||||
const isActived = (!included && point === upperBound) ||
|
|
||||||
(included && point <= upperBound && point >= lowerBound);
|
|
||||||
const pointClassName = classSet({
|
|
||||||
[prefixCls + '-dot']: true,
|
|
||||||
[prefixCls + '-dot-active']: isActived,
|
|
||||||
});
|
|
||||||
|
|
||||||
return <span className={pointClassName} style={style} key={point} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
return <div className={prefixCls + '-step'}>{elements}</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Steps;
|
|
||||||
+2
-1
@@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const Track = ({className, offset, length}) => {
|
const Track = ({className, included, offset, length}) => {
|
||||||
const style = {
|
const style = {
|
||||||
left: offset + '%',
|
left: offset + '%',
|
||||||
width: length + '%',
|
width: length + '%',
|
||||||
|
visibility: included ? 'visible' : 'hidden',
|
||||||
};
|
};
|
||||||
return <div className={className} style={style} />;
|
return <div className={className} style={style} />;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user