feat(components): [el-slider] slider add size prop (#5091)

* feat: slider add size

* feat: update

* feat: update

* feat: update
This commit is contained in:
kooriookami 2022-01-07 15:44:43 +08:00 committed by GitHub
parent fb76382dd1
commit b33fed911b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 137 additions and 117 deletions

View File

@ -12,7 +12,7 @@ Drag the slider within a fixed range.
display: flex; display: flex;
align-items: center; align-items: center;
.el-slider { .el-slider {
flex: 1; margin-top: 0;
margin-left: 12px; margin-left: 12px;
} }
.demonstration { .demonstration {
@ -23,6 +23,7 @@ Drag the slider within a fixed range.
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
margin-bottom: 0;
& + .el-slider { & + .el-slider {
flex: 0 0 70%; flex: 0 0 70%;
} }
@ -60,6 +61,14 @@ slider/slider-with-input-box
::: :::
## Sizes
:::demo
slider/sizes
:::
## Range selection ## Range selection
Selecting a range of values is supported. Selecting a range of values is supported.
@ -88,26 +97,27 @@ slider/show-marks
## Attributes ## Attributes
| Attribute | Description | Type | Accepted Values | Default | | Attribute | Description | Type | Accepted Values | Default |
| --------------------- | --------------------------------------------------------------------------------------------------------- | --------------- | ---------------------- | ------- | | --------------------- | --------------------------------------------------------------------------------------------------------- | --------------- | ----------------------- | ------- |
| model-value / v-model | binding value | number | — | 0 | | model-value / v-model | binding value | number | — | 0 |
| min | minimum value | number | — | 0 | | min | minimum value | number | — | 0 |
| max | maximum value | number | — | 100 | | max | maximum value | number | — | 100 |
| disabled | whether Slider is disabled | boolean | — | false | | disabled | whether Slider is disabled | boolean | — | false |
| step | step size | number | — | 1 | | step | step size | number | — | 1 |
| show-input | whether to display an input box, works when `range` is false | boolean | — | false | | show-input | whether to display an input box, works when `range` is false | boolean | — | false |
| show-input-controls | whether to display control buttons when `show-input` is true | boolean | — | true | | show-input-controls | whether to display control buttons when `show-input` is true | boolean | — | true |
| input-size | size of the input box | string | large / default /small | default | | size | size of the slider | string | large / default / small | default |
| show-stops | whether to display breakpoints | boolean | — | false | | input-size | size of the input box, when set `size`, the default is the value of `size` | string | large / default / small | default |
| show-tooltip | whether to display tooltip value | boolean | — | true | | show-stops | whether to display breakpoints | boolean | — | false |
| format-tooltip | format to display tooltip value | function(value) | — | — | | show-tooltip | whether to display tooltip value | boolean | — | true |
| range | whether to select a range | boolean | — | false | | format-tooltip | format to display tooltip value | function(value) | — | — |
| vertical | vertical mode | boolean | — | false | | range | whether to select a range | boolean | — | false |
| height | Slider height, required in vertical mode | string | — | — | | vertical | vertical mode | boolean | — | false |
| label | label for screen reader | string | — | — | | height | Slider height, required in vertical mode | string | — | — |
| debounce | debounce delay when typing, in milliseconds, works when `show-input` is true | number | — | 300 | | label | label for screen reader | string | — | — |
| tooltip-class | custom class name for the tooltip | string | — | — | | debounce | debounce delay when typing, in milliseconds, works when `show-input` is true | number | — | 300 |
| marks | marks type of key must be `number` and must in closed interval `[min, max]`, each mark can custom style | object | — | — | | tooltip-class | custom class name for the tooltip | string | — | — |
| marks | marks type of key must be `number` and must in closed interval `[min, max]`, each mark can custom style | object | — | — |
## Events ## Events

View File

@ -0,0 +1,21 @@
<template>
<el-slider v-model="value" show-input size="large"></el-slider>
<el-slider v-model="value" show-input></el-slider>
<el-slider v-model="value" show-input size="small"></el-slider>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref(0)
</script>
<style scoped>
.el-slider {
margin-top: 20px;
}
.el-slider:first-child {
margin-top: 0;
}
</style>

View File

@ -33,6 +33,24 @@ describe('Slider', () => {
}, 10) }, 10)
}) })
it('sizes', () => {
const wrapper = mount({
template: `
<div>
<slider v-model="value" size="small">
</slider>
</div>
`,
components: { Slider },
data() {
return {
value: 0,
}
},
})
expect(wrapper.find('.el-slider--small').exists()).toBe(true)
})
it('show tooltip', () => { it('show tooltip', () => {
const wrapper = mount({ const wrapper = mount({
template: ` template: `

View File

@ -1,29 +1,13 @@
<template> <template>
<div <div
ref="sliderWrapper" ref="sliderWrapper"
class="el-slider" :class="sliderKls"
:class="{ 'is-vertical': vertical, 'el-slider--with-input': showInput }"
role="slider" role="slider"
:aria-valuemin="min" :aria-valuemin="min"
:aria-valuemax="max" :aria-valuemax="max"
:aria-orientation="vertical ? 'vertical' : 'horizontal'" :aria-orientation="vertical ? 'vertical' : 'horizontal'"
:aria-disabled="sliderDisabled" :aria-disabled="sliderDisabled"
> >
<el-input-number
v-if="showInput && !range"
ref="input"
:model-value="firstValue"
class="el-slider__input"
:step="step"
:disabled="sliderDisabled"
:controls="showInputControls"
:min="min"
:max="max"
:debounce="debounce"
:size="inputSize"
@update:model-value="setFirstValue"
@change="emitChange"
/>
<div <div
ref="slider" ref="slider"
class="el-slider__runway" class="el-slider__runway"
@ -74,6 +58,21 @@
</div> </div>
</template> </template>
</div> </div>
<el-input-number
v-if="showInput && !range"
ref="input"
:model-value="firstValue"
class="el-slider__input"
:step="step"
:disabled="sliderDisabled"
:controls="showInputControls"
:min="min"
:max="max"
:debounce="debounce"
:size="sliderInputSize"
@update:model-value="setFirstValue"
@change="emitChange"
/>
</div> </div>
</template> </template>
@ -98,6 +97,8 @@ import {
} from '@element-plus/utils/constants' } from '@element-plus/utils/constants'
import { off, on } from '@element-plus/utils/dom' import { off, on } from '@element-plus/utils/dom'
import { throwError } from '@element-plus/utils/error' import { throwError } from '@element-plus/utils/error'
import { isValidComponentSize } from '@element-plus/utils/validators'
import { useSize } from '@element-plus/hooks'
import SliderButton from './button.vue' import SliderButton from './button.vue'
import SliderMarker from './marker.vue' import SliderMarker from './marker.vue'
import { useMarks } from './useMarks' import { useMarks } from './useMarks'
@ -141,9 +142,13 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
size: {
type: String as PropType<ComponentSize>,
validator: isValidComponentSize,
},
inputSize: { inputSize: {
type: String as PropType<ComponentSize>, type: String as PropType<ComponentSize>,
default: 'small', validator: isValidComponentSize,
}, },
showStops: { showStops: {
type: Boolean, type: Boolean,
@ -223,6 +228,19 @@ export default defineComponent({
maxValue maxValue
) )
const sliderWrapperSize = useSize()
const sliderInputSize = computed(
() => props.inputSize || sliderWrapperSize.value
)
const prefix = 'el-slider'
const sliderKls = computed(() => [
prefix,
`${prefix}--${sliderWrapperSize.value}`,
props.vertical ? 'is-vertical' : '',
props.showInput ? 'el-slider--with-input' : '',
])
const markList = useMarks(props) const markList = useMarks(props)
useWatch(props, initData, minValue, maxValue, emit, elFormItem) useWatch(props, initData, minValue, maxValue, emit, elFormItem)
@ -277,6 +295,9 @@ export default defineComponent({
markList, markList,
sliderWrapper, sliderWrapper,
sliderWrapperSize,
sliderInputSize,
sliderKls,
} }
}, },
}) })

View File

@ -904,7 +904,6 @@ $slider: map.merge(
'runway-bg-color': var(--el-border-color-light), 'runway-bg-color': var(--el-border-color-light),
'stop-bg-color': var(--el-color-white), 'stop-bg-color': var(--el-color-white),
'disable-color': var(--el-text-color-placeholder), 'disable-color': var(--el-text-color-placeholder),
'margin': 16px 0,
'border-radius': 3px, 'border-radius': 3px,
'height': 6px, 'height': 6px,
'button-size': 20px, 'button-size': 20px,

View File

@ -5,25 +5,36 @@
@use 'mixins/var' as *; @use 'mixins/var' as *;
@use 'common/var' as *; @use 'common/var' as *;
$slider-height: () !default;
$slider-height: map.merge(
(
'large': 40px,
'default': 32px,
'small': 24px,
),
$slider-height
);
@include b(slider) { @include b(slider) {
@include set-component-css-var('slider', $slider); @include set-component-css-var('slider', $slider);
} }
@include b(slider) { @include b(slider) {
@include utils-clearfix; width: 100%;
height: map.get($slider-height, 'default');
display: flex;
align-items: center;
@include e(runway) { @include e(runway) {
width: 100%; flex: 1;
height: var(--el-slider-height); height: var(--el-slider-height);
margin: var(--el-slider-margin);
background-color: var(--el-slider-runway-bg-color); background-color: var(--el-slider-runway-bg-color);
border-radius: var(--el-slider-border-radius); border-radius: var(--el-slider-border-radius);
position: relative; position: relative;
cursor: pointer; cursor: pointer;
vertical-align: middle;
&.show-input { &.show-input {
margin-right: 160px; margin-right: 30px;
width: auto; width: auto;
} }
@ -69,17 +80,8 @@
} }
@include e(input) { @include e(input) {
float: right; flex-shrink: 0;
margin-top: 3px;
width: 130px; width: 130px;
&.#{$namespace}-input-number--large {
margin-top: -2px;
}
&.#{$namespace}-input-number--small {
margin-top: 5px;
}
} }
@include e(bar) { @include e(bar) {
@ -168,6 +170,9 @@
@include when(vertical) { @include when(vertical) {
position: relative; position: relative;
height: 100%;
flex: 0;
.#{$namespace}-slider__runway { .#{$namespace}-slider__runway {
width: var(--el-slider-height); width: var(--el-slider-height);
height: 100%; height: 100%;
@ -186,68 +191,6 @@
.#{$namespace}-slider__stop { .#{$namespace}-slider__stop {
transform: translateY(50%); transform: translateY(50%);
} }
&.#{$namespace}-slider--with-input {
padding-bottom: #{map.get($input-height, 'default') + 22px};
.#{$namespace}-slider__input {
overflow: visible;
float: none;
position: absolute;
bottom: 22px;
width: 36px;
margin-top: 15px;
.#{$namespace}-input__inner {
text-align: center;
padding-left: 5px;
padding-right: 5px;
}
.#{$namespace}-input-number__decrease,
.#{$namespace}-input-number__increase {
top: map.get($input-height, 'small');
margin-top: -1px;
border: var(--el-input-border, map.get($input, 'border'));
line-height: 20px;
box-sizing: border-box;
transition: var(--el-transition-border);
}
.#{$namespace}-input-number__decrease {
width: 18px;
right: 18px;
border-bottom-left-radius: var(
--el-input-border-radius,
map.get($input, 'border-radius')
);
}
.#{$namespace}-input-number__increase {
width: 19px;
border-bottom-right-radius: var(
--el-input-border-radius,
map.get($input, 'border-radius')
);
& ~ .#{$namespace}-input .#{$namespace}-input__inner {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
&:hover {
.#{$namespace}-input-number__decrease,
.#{$namespace}-input-number__increase {
border-color: var(
--el-input-hover-border,
map.get($input, 'hover-border')
);
}
}
&:active {
.#{$namespace}-input-number__decrease,
.#{$namespace}-input-number__increase {
border-color: var(
--el-input-focus-border,
map.get($input, 'focus-border')
);
}
}
}
}
@include e(marks-text) { @include e(marks-text) {
margin-top: 0; margin-top: 0;
@ -255,4 +198,12 @@
transform: translateY(50%); transform: translateY(50%);
} }
} }
@each $size in (large, small) {
@include m($size) {
height: map.get($slider-height, $size);
@include e(runway) {
}
}
}
} }