mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-30 13:16:34 +08:00
feat(2.x/slider): add dual thumb mode for slider (#7176)
* feat(slider): add dual thumb mode for slider * fix: test error
This commit is contained in:
parent
2c38469591
commit
9b32a13bef
@ -34,6 +34,32 @@ export default {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Dual thumb
|
||||||
|
|
||||||
|
Add `range` attribute to open dual thumb mode
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-slider v-model="value" range @change="onChange" />
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Toast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// value must be an Array
|
||||||
|
value: [10, 50],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange(value) {
|
||||||
|
Toast('current value:' + value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### Range
|
### Range
|
||||||
|
|
||||||
```html
|
```html
|
||||||
@ -63,9 +89,7 @@ export default {
|
|||||||
```html
|
```html
|
||||||
<van-slider v-model="value" active-color="#ee0a24">
|
<van-slider v-model="value" active-color="#ee0a24">
|
||||||
<template #button>
|
<template #button>
|
||||||
<div class="custom-button">
|
<div class="custom-button">{{ value }}</div>
|
||||||
{{ value }}
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</van-slider>
|
</van-slider>
|
||||||
|
|
||||||
@ -90,15 +114,44 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Vertical, Dual thumb mode
|
||||||
|
|
||||||
|
Add `range` and `vertical` attributes at the same time, and make sure that the value of `value` is an array
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div :style="{ height: '120px' }">
|
||||||
|
<van-slider v-model="value" range vertical @change="onChange" />
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Toast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// value must be an array
|
||||||
|
value: [10, 50],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange(value) {
|
||||||
|
Toast('Current value:' + value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
### Props
|
### Props
|
||||||
|
|
||||||
| Attribute | Description | Type | Default |
|
| Attribute | Description | Type | Default |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| value | Current value | _number_ | `0` |
|
| value | Current value | _number \| array_ | `0` |
|
||||||
| max | Max value | _number \| string_ | `100` |
|
| max | Max value | _number \| string_ | `100` |
|
||||||
| min | Min value | _number \| string_ | `0` |
|
| min | Min value | _number \| string_ | `0` |
|
||||||
|
| range | Dual thumb mode | _boolean_ | `false` |
|
||||||
| step | Step size | _number \| string_ | `1` |
|
| step | Step size | _number \| string_ | `1` |
|
||||||
| bar-height | Height of bar | _number \| string_ | `2px` |
|
| bar-height | Height of bar | _number \| string_ | `2px` |
|
||||||
| button-size `v2.4.5` | Button size | _number \| string_ | `24px` |
|
| button-size `v2.4.5` | Button size | _number \| string_ | `24px` |
|
||||||
|
@ -34,6 +34,32 @@ export default {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 双滑块
|
||||||
|
|
||||||
|
添加`range`属性就可以开启双滑块模式,确保`value`的值是一个数组
|
||||||
|
|
||||||
|
```html
|
||||||
|
<van-slider v-model="value" range @change="onChange" />
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Toast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 双滑块模式时,值必须是数组
|
||||||
|
value: [10, 50],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange(value) {
|
||||||
|
Toast('当前值:' + value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### 指定选择范围
|
### 指定选择范围
|
||||||
|
|
||||||
```html
|
```html
|
||||||
@ -63,9 +89,7 @@ export default {
|
|||||||
```html
|
```html
|
||||||
<van-slider v-model="value" active-color="#ee0a24">
|
<van-slider v-model="value" active-color="#ee0a24">
|
||||||
<template #button>
|
<template #button>
|
||||||
<div class="custom-button">
|
<div class="custom-button">{{ value }}</div>
|
||||||
{{ value }}
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</van-slider>
|
</van-slider>
|
||||||
|
|
||||||
@ -87,20 +111,49 @@ export default {
|
|||||||
Slider 垂直展示时,高度为 100% 父元素高度
|
Slider 垂直展示时,高度为 100% 父元素高度
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<div :style="{ height: '100px' }">
|
<div :style="{ height: '120px' }">
|
||||||
<van-slider v-model="value" vertical />
|
<van-slider v-model="value" vertical />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 垂直方向,双滑块
|
||||||
|
|
||||||
|
同时添加`range`和`vertical`属性,并确保`value`的值是一个数组
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div :style="{ height: '120px' }">
|
||||||
|
<van-slider v-model="value" range vertical @change="onChange" />
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Toast } from 'vant';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 双滑块模式时,值必须是数组
|
||||||
|
value: [10, 50],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange(value) {
|
||||||
|
Toast('当前值:' + value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
### Props
|
### Props
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 |
|
| 参数 | 说明 | 类型 | 默认值 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| value | 当前进度百分比 | _number_ | `0` |
|
| value | 当前进度百分比 | _number \| array_ | `0` |
|
||||||
| max | 最大值 | _number \| string_ | `100` |
|
| max | 最大值 | _number \| string_ | `100` |
|
||||||
| min | 最小值 | _number \| string_ | `0` |
|
| min | 最小值 | _number \| string_ | `0` |
|
||||||
|
| range | 双滑块模式 | _boolean_ | `false` |
|
||||||
| step | 步长 | _number \| string_ | `1` |
|
| step | 步长 | _number \| string_ | `1` |
|
||||||
| bar-height | 进度条高度,默认单位为`px` | _number \| string_ | `2px` |
|
| bar-height | 进度条高度,默认单位为`px` | _number \| string_ | `2px` |
|
||||||
| button-size `v2.4.5` | 滑块按钮大小,默认单位为`px` | _number \| string_ | `24px` |
|
| button-size `v2.4.5` | 滑块按钮大小,默认单位为`px` | _number \| string_ | `24px` |
|
||||||
|
@ -5,20 +5,24 @@
|
|||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="t('title2')">
|
<demo-block :title="t('title2')">
|
||||||
<van-slider v-model="value2" :min="-50" :max="50" @change="onChange" />
|
<van-slider range v-model="value2" @change="onChange" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="t('title3')">
|
<demo-block :title="t('title3')">
|
||||||
<van-slider v-model="value3" disabled />
|
<van-slider v-model="value3" :min="-50" :max="50" @change="onChange" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="t('title4')">
|
<demo-block :title="t('title4')">
|
||||||
<van-slider v-model="value4" :step="10" @change="onChange" />
|
<van-slider v-model="value4" disabled />
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block :title="t('title5')">
|
||||||
|
<van-slider v-model="value5" :step="10" @change="onChange" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="t('customStyle')">
|
<demo-block :title="t('customStyle')">
|
||||||
<van-slider
|
<van-slider
|
||||||
v-model="value5"
|
v-model="value6"
|
||||||
bar-height="4px"
|
bar-height="4px"
|
||||||
active-color="#ee0a24"
|
active-color="#ee0a24"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
@ -26,16 +30,22 @@
|
|||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block :title="t('customButton')">
|
<demo-block :title="t('customButton')">
|
||||||
<van-slider v-model="value6" active-color="#ee0a24">
|
<van-slider v-model="value7" active-color="#ee0a24">
|
||||||
<template #button>
|
<template #button>
|
||||||
<div class="custom-button">{{ value6 }}</div>
|
<div class="custom-button">{{ value7 }}</div>
|
||||||
</template>
|
</template>
|
||||||
</van-slider>
|
</van-slider>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block v-if="!isWeapp" :title="t('vertical')">
|
<demo-block v-if="!isWeapp" :title="t('vertical')">
|
||||||
<div :style="{ height: '120px', paddingLeft: '30px' }">
|
<div :style="{ height: '120px', paddingLeft: '30px' }">
|
||||||
<van-slider v-model="value7" vertical @change="onChange" />
|
<van-slider v-model="value8" vertical @change="onChange" />
|
||||||
|
</div>
|
||||||
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block v-if="!isWeapp" :title="t('vertical2')">
|
||||||
|
<div :style="{ height: '120px', paddingLeft: '30px' }">
|
||||||
|
<van-slider v-model="value9" range vertical @change="onChange" />
|
||||||
</div>
|
</div>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
</demo-section>
|
</demo-section>
|
||||||
@ -46,38 +56,42 @@ export default {
|
|||||||
i18n: {
|
i18n: {
|
||||||
'zh-CN': {
|
'zh-CN': {
|
||||||
title1: '基础用法',
|
title1: '基础用法',
|
||||||
title2: '指定选择范围',
|
title2: '双滑块',
|
||||||
title3: '禁用',
|
title3: '指定选择范围',
|
||||||
title4: '指定步长',
|
title4: '禁用',
|
||||||
|
title5: '指定步长',
|
||||||
customStyle: '自定义样式',
|
customStyle: '自定义样式',
|
||||||
customButton: '自定义按钮',
|
customButton: '自定义按钮',
|
||||||
text: '当前值:',
|
text: '当前值:',
|
||||||
vertical: '垂直方向',
|
vertical: '垂直方向',
|
||||||
|
vertical2: '垂直方向,双滑块',
|
||||||
},
|
},
|
||||||
'en-US': {
|
'en-US': {
|
||||||
title1: 'Basic Usage',
|
title1: 'Basic Usage',
|
||||||
title2: 'Range',
|
title2: 'Dual thumb mode',
|
||||||
title3: 'Disabled',
|
title3: 'Range',
|
||||||
title4: 'Step size',
|
title4: 'Disabled',
|
||||||
|
title5: 'Step size',
|
||||||
customStyle: 'Custom Style',
|
customStyle: 'Custom Style',
|
||||||
customButton: 'Custom Button',
|
customButton: 'Custom Button',
|
||||||
text: 'Current value: ',
|
text: 'Current value: ',
|
||||||
vertical: 'Vertical',
|
vertical: 'Vertical',
|
||||||
|
vertical2: 'Vertical, Dual thumb mode',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
value1: 50,
|
value1: 50,
|
||||||
value2: 0,
|
value2: [20, 60],
|
||||||
value3: 50,
|
value3: 0,
|
||||||
value4: 50,
|
value4: 50,
|
||||||
value5: 50,
|
value5: 50,
|
||||||
value6: 50,
|
value6: 50,
|
||||||
value7: 50,
|
value7: 50,
|
||||||
|
value8: 50,
|
||||||
|
value9: [20, 60],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onChange(value) {
|
onChange(value) {
|
||||||
this.$toast(this.t('text') + value);
|
this.$toast(this.t('text') + value);
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
import { createNamespace, addUnit } from '../utils';
|
import { createNamespace, addUnit } from '../utils';
|
||||||
|
import { deepClone } from '../utils/deep-clone';
|
||||||
import { preventDefault } from '../utils/dom/event';
|
import { preventDefault } from '../utils/dom/event';
|
||||||
import { TouchMixin } from '../mixins/touch';
|
import { TouchMixin } from '../mixins/touch';
|
||||||
import { FieldMixin } from '../mixins/field';
|
import { FieldMixin } from '../mixins/field';
|
||||||
|
|
||||||
const [createComponent, bem] = createNamespace('slider');
|
const [createComponent, bem] = createNamespace('slider');
|
||||||
|
|
||||||
|
const isSameValue = (newValue, oldValue) => {
|
||||||
|
return JSON.stringify(newValue) === JSON.stringify(oldValue);
|
||||||
|
};
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
mixins: [TouchMixin, FieldMixin],
|
mixins: [TouchMixin, FieldMixin],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
vertical: Boolean,
|
vertical: Boolean,
|
||||||
|
range: Boolean,
|
||||||
barHeight: [Number, String],
|
barHeight: [Number, String],
|
||||||
buttonSize: [Number, String],
|
buttonSize: [Number, String],
|
||||||
activeColor: String,
|
activeColor: String,
|
||||||
@ -28,7 +34,7 @@ export default createComponent({
|
|||||||
default: 1,
|
default: 1,
|
||||||
},
|
},
|
||||||
value: {
|
value: {
|
||||||
type: Number,
|
type: [Number, Array],
|
||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -40,7 +46,7 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
range() {
|
scope() {
|
||||||
return this.max - this.min;
|
return this.max - this.min;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -61,7 +67,12 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
if (this.range) {
|
||||||
|
this.bindTouchEvent(this.$refs.wrapper0);
|
||||||
|
this.bindTouchEvent(this.$refs.wrapper1);
|
||||||
|
} else {
|
||||||
this.bindTouchEvent(this.$refs.wrapper);
|
this.bindTouchEvent(this.$refs.wrapper);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@ -71,7 +82,12 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.touchStart(event);
|
this.touchStart(event);
|
||||||
|
this.currentValue = this.value;
|
||||||
|
if (this.range) {
|
||||||
|
this.startValue = this.value.map(this.format);
|
||||||
|
} else {
|
||||||
this.startValue = this.format(this.value);
|
this.startValue = this.format(this.value);
|
||||||
|
}
|
||||||
this.dragStatus = 'start';
|
this.dragStatus = 'start';
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -91,10 +107,14 @@ export default createComponent({
|
|||||||
const rect = this.$el.getBoundingClientRect();
|
const rect = this.$el.getBoundingClientRect();
|
||||||
const delta = this.vertical ? this.deltaY : this.deltaX;
|
const delta = this.vertical ? this.deltaY : this.deltaX;
|
||||||
const total = this.vertical ? rect.height : rect.width;
|
const total = this.vertical ? rect.height : rect.width;
|
||||||
const diff = (delta / total) * this.range;
|
const diff = (delta / total) * this.scope;
|
||||||
|
|
||||||
this.newValue = this.startValue + diff;
|
if (this.range) {
|
||||||
this.updateValue(this.newValue);
|
this.currentValue[this.index] = this.startValue[this.index] + diff;
|
||||||
|
} else {
|
||||||
|
this.currentValue = this.startValue + diff;
|
||||||
|
}
|
||||||
|
this.updateValue(this.currentValue);
|
||||||
},
|
},
|
||||||
|
|
||||||
onTouchEnd() {
|
onTouchEnd() {
|
||||||
@ -103,7 +123,7 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.dragStatus === 'draging') {
|
if (this.dragStatus === 'draging') {
|
||||||
this.updateValue(this.newValue, true);
|
this.updateValue(this.currentValue, true);
|
||||||
this.$emit('drag-end');
|
this.$emit('drag-end');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,20 +140,44 @@ export default createComponent({
|
|||||||
? event.clientY - rect.top
|
? event.clientY - rect.top
|
||||||
: event.clientX - rect.left;
|
: event.clientX - rect.left;
|
||||||
const total = this.vertical ? rect.height : rect.width;
|
const total = this.vertical ? rect.height : rect.width;
|
||||||
const value = +this.min + (delta / total) * this.range;
|
let value = +this.min + (delta / total) * this.scope;
|
||||||
|
|
||||||
|
if (this.range) {
|
||||||
|
let [left, right] = this.value;
|
||||||
|
const middle = (left + right) / 2;
|
||||||
|
if (value <= middle) {
|
||||||
|
left = value;
|
||||||
|
} else {
|
||||||
|
right = value;
|
||||||
|
}
|
||||||
|
value = [left, right];
|
||||||
|
}
|
||||||
|
|
||||||
this.startValue = this.value;
|
this.startValue = this.value;
|
||||||
this.updateValue(value, true);
|
this.updateValue(value, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateValue(value, end) {
|
// 处理两个滑块重叠之后的情况
|
||||||
value = this.format(value);
|
handleOverlap(value) {
|
||||||
|
if (value[0] > value[1]) {
|
||||||
|
value = deepClone(value);
|
||||||
|
return value.reverse();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
if (value !== this.value) {
|
updateValue(value, end) {
|
||||||
|
if (this.range) {
|
||||||
|
value = this.handleOverlap(value).map(this.format);
|
||||||
|
} else {
|
||||||
|
value = this.format(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSameValue(value, this.value)) {
|
||||||
this.$emit('input', value);
|
this.$emit('input', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end && value !== this.startValue) {
|
if (end && !isSameValue(value, this.startValue)) {
|
||||||
this.$emit('change', value);
|
this.$emit('change', value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -156,8 +200,28 @@ export default createComponent({
|
|||||||
[crossAxis]: addUnit(this.barHeight),
|
[crossAxis]: addUnit(this.barHeight),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 计算选中条的长度百分比
|
||||||
|
const calcMainAxis = () => {
|
||||||
|
const { value, min, range, scope } = this;
|
||||||
|
if (range) {
|
||||||
|
return `${((value[1] - value[0]) * 100) / scope}%`;
|
||||||
|
}
|
||||||
|
return `${((value - min) * 100) / scope}%`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 计算选中条的开始位置的偏移量
|
||||||
|
const calcOffset = () => {
|
||||||
|
const { value, min, range, scope } = this;
|
||||||
|
if (range) {
|
||||||
|
return `${((value[0] - min) * 100) / scope}%`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
const barStyle = {
|
const barStyle = {
|
||||||
[mainAxis]: `${((this.value - this.min) * 100) / this.range}%`,
|
[mainAxis]: calcMainAxis(),
|
||||||
|
left: this.vertical ? null : calcOffset(),
|
||||||
|
top: this.vertical ? calcOffset() : null,
|
||||||
background: this.activeColor,
|
background: this.activeColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,6 +229,47 @@ export default createComponent({
|
|||||||
barStyle.transition = 'none';
|
barStyle.transition = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderButton = (i) => {
|
||||||
|
const map = ['left', 'right'];
|
||||||
|
const isNumber = typeof i === 'number';
|
||||||
|
const getClassName = () => {
|
||||||
|
if (isNumber) {
|
||||||
|
return `button-wrapper-${map[i]}`;
|
||||||
|
}
|
||||||
|
return `button-wrapper`;
|
||||||
|
};
|
||||||
|
const getRefName = () => {
|
||||||
|
if (isNumber) {
|
||||||
|
return `wrapper${i}`;
|
||||||
|
}
|
||||||
|
return `wrapper`;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={getRefName()}
|
||||||
|
role="slider"
|
||||||
|
tabindex={this.disabled ? -1 : 0}
|
||||||
|
aria-valuemin={this.min}
|
||||||
|
aria-valuenow={this.value}
|
||||||
|
aria-valuemax={this.max}
|
||||||
|
aria-orientation={this.vertical ? 'vertical' : 'horizontal'}
|
||||||
|
class={bem(getClassName())}
|
||||||
|
onTouchstart={() => {
|
||||||
|
if (isNumber) {
|
||||||
|
// 保存当前按钮的索引
|
||||||
|
this.index = i;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
{this.slots('button') || (
|
||||||
|
<div class={bem('button')} style={this.buttonStyle} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={wrapperStyle}
|
style={wrapperStyle}
|
||||||
@ -172,20 +277,7 @@ export default createComponent({
|
|||||||
onClick={this.onClick}
|
onClick={this.onClick}
|
||||||
>
|
>
|
||||||
<div class={bem('bar')} style={barStyle}>
|
<div class={bem('bar')} style={barStyle}>
|
||||||
<div
|
{this.range ? [renderButton(0), renderButton(1)] : renderButton()}
|
||||||
ref="wrapper"
|
|
||||||
role="slider"
|
|
||||||
tabindex={this.disabled ? -1 : 0}
|
|
||||||
aria-valuemin={this.min}
|
|
||||||
aria-valuenow={this.value}
|
|
||||||
aria-valuemax={this.max}
|
|
||||||
aria-orientation={this.vertical ? 'vertical' : 'horizontal'}
|
|
||||||
class={bem('button-wrapper')}
|
|
||||||
>
|
|
||||||
{this.slots('button') || (
|
|
||||||
<div class={bem('button')} style={this.buttonStyle} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: @slider-active-background-color;
|
background-color: @slider-active-background-color;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
transition: width @animation-duration-fast, height @animation-duration-fast;
|
transition: all @animation-duration-fast;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__button {
|
&__button {
|
||||||
@ -34,20 +34,31 @@
|
|||||||
border-radius: @slider-button-border-radius;
|
border-radius: @slider-button-border-radius;
|
||||||
box-shadow: @slider-button-box-shadow;
|
box-shadow: @slider-button-box-shadow;
|
||||||
|
|
||||||
&-wrapper {
|
&-wrapper,
|
||||||
|
&-wrapper-right {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
right: 0;
|
right: 0;
|
||||||
transform: translate3d(50%, -50%, 0);
|
transform: translate3d(50%, -50%, 0);
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-wrapper-left {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
transform: translate3d(-50%, -50%, 0);
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--disabled {
|
&--disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
opacity: @slider-disabled-opacity;
|
opacity: @slider-disabled-opacity;
|
||||||
|
|
||||||
.van-slider__button-wrapper {
|
.van-slider__button-wrapper,
|
||||||
|
.van-slider__button-wrapper-left,
|
||||||
|
.van-slider__button-wrapper-right {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,13 +68,21 @@
|
|||||||
width: @slider-bar-height;
|
width: @slider-bar-height;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.van-slider__button-wrapper {
|
.van-slider__button-wrapper,
|
||||||
|
.van-slider__button-wrapper-right {
|
||||||
top: auto;
|
top: auto;
|
||||||
right: 50%;
|
right: 50%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
transform: translate3d(50%, 50%, 0);
|
transform: translate3d(50%, 50%, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.van-slider__button-wrapper-left {
|
||||||
|
top: 0;
|
||||||
|
right: 50%;
|
||||||
|
left: auto;
|
||||||
|
transform: translate3d(50%, -50%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// use pseudo element to expand click area
|
// use pseudo element to expand click area
|
||||||
&::before {
|
&::before {
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -11,6 +11,18 @@ exports[`renders demo correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="van-slider">
|
||||||
|
<div class="van-slider__bar" style="width: 40%; left: 20%;">
|
||||||
|
<div role="slider" tabindex="0" aria-valuemin="0" aria-valuenow="20,60" aria-valuemax="100" aria-orientation="horizontal" class="van-slider__button-wrapper-left">
|
||||||
|
<div class="van-slider__button"></div>
|
||||||
|
</div>
|
||||||
|
<div role="slider" tabindex="0" aria-valuemin="0" aria-valuenow="20,60" aria-valuemax="100" aria-orientation="horizontal" class="van-slider__button-wrapper-right">
|
||||||
|
<div class="van-slider__button"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="van-slider">
|
<div class="van-slider">
|
||||||
<div class="van-slider__bar" style="width: 50%;">
|
<div class="van-slider__bar" style="width: 50%;">
|
||||||
@ -67,5 +79,19 @@ exports[`renders demo correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style="height: 120px; padding-left: 30px;">
|
||||||
|
<div class="van-slider van-slider--vertical">
|
||||||
|
<div class="van-slider__bar" style="height: 40%; top: 20%;">
|
||||||
|
<div role="slider" tabindex="0" aria-valuemin="0" aria-valuenow="20,60" aria-valuemax="100" aria-orientation="vertical" class="van-slider__button-wrapper-left">
|
||||||
|
<div class="van-slider__button"></div>
|
||||||
|
</div>
|
||||||
|
<div role="slider" tabindex="0" aria-valuemin="0" aria-valuenow="20,60" aria-valuemax="100" aria-orientation="vertical" class="van-slider__button-wrapper-right">
|
||||||
|
<div class="van-slider__button"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user