Range 区段选择器
如果项目中使用的是 1.x 版本的基础组件(@alifd/next),请在左侧导航顶部切换组件版本。
安装方法
- 在命令行中执行以下命令
npm install @icedesign/base@latest -S
开发指南
区间选择
何时使用
滑块控件(Sliders,简称滑块)可以让我们通过在连续或间断的区间内滑动锚点来选择一个合适的数值。区间最小值放在左边,对应的,最大值放在右边。滑块(Sliders)可以在滑动条的左右两端设定图标来反映数值的强度。这种交互特性使得它在设置诸如音量、亮度、色彩饱和度等需要反映强度等级的选项时成为一种极好的选择。
使用注意
onChange是和value进行配置做受控处理的。onChange在滑动过程中不会触发,滑动停止后会触发。
onProcess不建议内部做setState 进行受控,因为会频繁触发,整个滑动过程中会一直触发。
API
区段选择器
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
prefix | 样式类名的品牌前缀 | String | 'next-' |
className | 自定义类名 | String | - |
style | 自定义内敛样式 | Object | - |
slider | 滑块个数可选值:'single'(单个)'double'(两个) | Enum | 'single' |
min | 最小值 | Number | 0 |
max | 最大值 | Number | 100 |
step | 步长,取值必须大于 0,并且可被 (max - min) 整除。 | Number | 1 |
value | 设置当前取值。当 slider 为 single 时,使用 Number ,否则用 [Number, Number] | Number/Array<Number> | - |
defaultValue | 设置初始取值。当 slider 为 single 时,使用 Number ,否则用 [Number, Number] | Number/Array<Number> | - |
marks | 刻度数值显示逻辑(false 代表不显示,array 枚举显示的值,number 代表按 number 平分,object 表示按 key 划分,value 值显示) | Boolean/Number/Array<Number>/Object | false |
disabled | 值为 true 时,滑块为禁用状态 | Boolean | false |
onChange | 当 Range 的值发生改变后,会触发 onChange 事件,并把改变后的值作为参数传入, 如果设置了value, 要配合此函数做受控使用签名:Function(value: String/number) => void参数:value: {String/number} null | Function | () => { } |
onProcess | 滑块拖动的时候触发的事件,不建议在这里setState, 一般情况下不需要用, 滑动时有特殊需求时使用签名:Function(value: String/number) => void参数:value: {String/number} null | Function | () => { } |
hasTip | 是否显示tip | Boolean | true |
tipFormatter | tip文件自定义处理签名:Function() => void | Function | (value) => { return value; } |
reverse | 选中态反转 | Boolean | false |
代码示例
基本滑块,当 slider
为 double
时,渲染为双滑块。当 disabled
为 true
时,滑块处于不可用状态。
查看源码在线预览
import { Range } from "@icedesign/base";
const style = {
marginBottom: "15px"
};
ReactDOM.render(
<div style={{ width: "400px", margin: "50px" }}>
<h4>单滑块-左向右</h4>
<Range defaultValue={30} style={style} hasTip={false} />
<h4>单滑块-右向左</h4>
<Range defaultValue={30} style={style} reverse hasTip={false} />
<h4>双滑块-从外到里</h4>
<Range slider={"double"} defaultValue={[20, 40]} style={style} />
<h4>双滑块-从里到外</h4>
<Range slider={"double"} defaultValue={[20, 40]} style={style} reverse />
<h4>Disabled</h4>
<Range defaultValue={30} disabled style={style} />
<h4>Disabled</h4>
<Range slider={"double"} defaultValue={[20, 40]} disabled style={style} />
</div>,
mountNode
);
onChange,onProcess事件
查看源码在线预览
import { Range } from "@icedesign/base";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 128,
doubleValue: [10, 30]
};
}
//受控使用, onChange,移动结束时,如果startValue和endValue不等,会触发这个事件
onChange(value) {
console.log("onChange value:", value);
this.setState({ value });
}
//mouseDown以及onMove的时候,如果startValue和endValue不等,会触发这个事件,不建议在这里做setState.
onProcess(value) {
this.setState({ value });
console.log("onProcess: ", value);
}
onChangeDouble(value) {
this.setState({
doubleValue: value
});
}
render() {
return (
<div style={{ width: "400px", margin: "50px" }}>
<p>范围 0 ~ 1024</p>
<div style={{ width: "400px", marginTop: "50px" }}>
<Range
value={this.state.value}
onChange={this.onChange.bind(this)}
onProcess={this.onProcess.bind(this)}
min={0}
max={1024}
marks={[0, 1024]}
/>
</div>
<p>设了value受控后的,不设置onChange的状态</p>
<div style={{ width: "400px", marginTop: "50px" }}>
<Range
defaultValue={256}
value={300}
onProcess={this.onProcess.bind(this)}
min={0}
max={1024}
marks={[0, 1024]}
/>
</div>
<p>double slider controlled</p>
<div style={{ width: "400px", marginTop: "50px" }}>
<Range
slider="double"
value={this.state.doubleValue}
onChange={this.onChangeDouble.bind(this)}
onProcess={this.onProcess.bind(this)}
min={0}
max={1024}
marks={[0, 1024]}
/>
</div>
</div>
);
}
}
ReactDOM.render(<App />, mountNode);
与number-picker结合,外部控制,与Icon结合设置边界Icon
查看源码在线预览
import { Range, NumberPicker, Grid, Icon } from "@icedesign/base";
const { Row, Col } = Grid;
class Demo extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
valueInt: 3,
valueDec: 0.05,
valueIcon: 1,
preIconClass: "",
afterIconClass: ""
};
}
onChangeInt(value) {
console.log(value);
this.setState(
Object.assign({}, this.state, {
valueInt: value
})
);
}
onChangeDec(value) {
this.setState(
Object.assign({}, this.state, {
valueDec: value
})
);
}
onIconRangeProcess(value) {
let mid = 50;
this.setState(
Object.assign({}, this.state, {
valueIcon: value,
preIconClass: value < mid ? "myicon-highlight" : "",
afterIconClass: value >= mid ? "myicon-highlight" : ""
})
);
}
render() {
return (
<div style={{ width: "400px", margin: "50px" }}>
<h2>numberPicker联动</h2>
<Row>
<Col span="12" style={{ marginTop: "10px" }}>
<Range
value={this.state.valueInt}
min={0}
max={20}
step={1}
onChange={this.onChangeInt.bind(this)}
/>
</Col>
<Col span="12">
<NumberPicker
value={this.state.valueInt}
min={0}
max={1024}
step={1}
onChange={this.onChangeInt.bind(this)}
/>
</Col>
</Row>
<br />
<Row>
<Col span="12" style={{ marginTop: "10px" }}>
<Range
value={this.state.valueDec}
min={0}
max={1}
step={0.01}
onChange={this.onChangeDec.bind(this)}
/>
</Col>
<Col span="12">
<NumberPicker
value={this.state.valueDec}
min={0}
max={1}
step={0.01}
onChange={this.onChangeDec.bind(this)}
/>
</Col>
</Row>
<h2>与Icon结合使用</h2>
<div className="iconWrapper">
<Icon className={"myicon " + this.state.preIconClass} type="cry" />
<Range
min={1}
max={100}
onChange={this.onIconRangeProcess.bind(this)}
value={this.state.valueIcon}
/>
<Icon
className={"myicon " + this.state.afterIconClass}
type="smile"
/>
</div>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
.iconWrapper {
position: relative;
padding: 0px 40px;
}
.iconWrapper .myicon {
position: absolute;
top: -3px;
width: 16px;
height: 16px;
line-height: 1;
font-size: 16px;
color: #ccc;
}
.iconWrapper .myicon:first-child {
left: 0;
}
.iconWrapper .myicon:last-child {
right: 0;
}
.myicon.myicon-highlight {
color: #666;
}
通过 scales
与 marks
属性设置刻度及标识。
查看源码在线预览
import { Range } from "@icedesign/base";
const style = {
marginBottom: "40px",
marginTop: "40px"
};
ReactDOM.render(
<div style={{ width: "400px", margin: "50px" }}>
<p>设置首尾</p>
<Range defaultValue={0} marks={[0, 100]} style={style} />
<Range
slider={"double"}
defaultValue={[20, 40]}
scales={[0, 100]}
marks={[0, 100]}
style={style}
/>
<Range defaultValue={30} style={style} />
<p>平分</p>
<Range defaultValue={30} marks={5} style={style} />
<Range
slider={"double"}
defaultValue={[20, 40]}
scales={10}
marks={10}
style={style}
/>
<Range
disabled
slider={"double"}
defaultValue={[20, 40]}
scales={10}
marks={10}
style={style}
/>
<p>自由刻度</p>
<Range defaultValue={30} marks={[0, 26, 37, 100]} style={style} />
<Range
slider={"double"}
defaultValue={[20, 40]}
marks={[0, 26, 37, 100]}
style={style}
hasTip={false}
/>
<Range
defaultValue={30}
marks={{ 0: "0°C", 26: "26°C", 37: "37°C", 100: "100°C" }}
style={style}
/>
</div>,
mountNode
);
可以通过 min
与 max
设置范围边界。通过 step
(被 max - min 整除) 设置移动的最小步频。min默认为0,max默认为100.
查看源码在线预览
import { Range } from "@icedesign/base";
const style = {
marginBottom: "40px",
marginTop: "40px"
};
ReactDOM.render(
<div style={{ width: "400px", margin: "50px" }}>
<p>范围 0 ~ 1024</p>
<Range
defaultValue={128}
min={0}
max={1024}
marks={[0, 1024]}
style={style}
/>
<p>范围 0 ~ 1024,一次移动 128</p>
<Range
defaultValue={512}
min={0}
max={1024}
step={128}
marks={[0, 1024]}
style={style}
/>
</div>,
mountNode
);
设置reverse为true, 选中态会反转。
查看源码在线预览
import { Range } from "@icedesign/base";
const style = {
marginBottom: "15px"
};
ReactDOM.render(
<div style={{ width: "400px", margin: "50px" }}>
<Range defaultValue={30} style={style} hasTip={false} />
<Range defaultValue={30} style={style} reverse hasTip={false} />
<Range slider={"double"} defaultValue={[20, 40]} style={style} />
<Range slider={"double"} defaultValue={[20, 40]} style={style} reverse />
<Range defaultValue={30} disabled style={style} />
<Range defaultValue={30} disabled style={style} reverse />
<Range slider={"double"} defaultValue={[20, 40]} disabled style={style} />
<Range
slider={"double"}
defaultValue={[20, 40]}
disabled
style={style}
reverse
/>
</div>,
mountNode
);
tipFormatter 示例
查看源码在线预览
import { Range } from "@icedesign/base";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 128
};
}
//onChange,移动结束时,如果startValue和endValue不等,会触发这个事件
onChange(value) {
console.log("onChange value:", value);
}
//mouseDown以及onMove的时候,如果startValue和endValue不等,会触发这个事件.如果是受控组件,改变state要写在这个事件里
onProcess(value) {
console.log("onProcess");
this.setState({ value });
}
formatter(value) {
return "$" + value;
}
render() {
return (
<div style={{ width: "400px", margin: "50px" }}>
<p>范围 0 ~ 1024</p>
<div style={{ width: "400px", marginTop: "50px" }}>
<Range
defaultValue={256}
tipFormatter={this.formatter.bind(this)}
value={this.state.value}
onChange={this.onChange.bind(this)}
onProcess={this.onProcess.bind(this)}
min={0}
max={1024}
marks={[0, 1024]}
/>
</div>
</div>
);
}
}
ReactDOM.render(<App />, mountNode);