diff --git a/docs/en-US/component/slider.md b/docs/en-US/component/slider.md index ae46a83c36..7f539bde43 100644 --- a/docs/en-US/component/slider.md +++ b/docs/en-US/component/slider.md @@ -12,7 +12,7 @@ Drag the slider within a fixed range. display: flex; align-items: center; .el-slider { - flex: 1; + margin-top: 0; margin-left: 12px; } .demonstration { @@ -23,6 +23,7 @@ Drag the slider within a fixed range. overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + margin-bottom: 0; & + .el-slider { flex: 0 0 70%; } @@ -60,6 +61,14 @@ slider/slider-with-input-box ::: +## Sizes + +:::demo + +slider/sizes + +::: + ## Range selection Selecting a range of values is supported. @@ -88,26 +97,27 @@ slider/show-marks ## Attributes -| Attribute | Description | Type | Accepted Values | Default | -| --------------------- | --------------------------------------------------------------------------------------------------------- | --------------- | ---------------------- | ------- | -| model-value / v-model | binding value | number | — | 0 | -| min | minimum value | number | — | 0 | -| max | maximum value | number | — | 100 | -| disabled | whether Slider is disabled | boolean | — | false | -| step | step size | number | — | 1 | -| 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 | -| input-size | size of the input box | string | large / default /small | default | -| show-stops | whether to display breakpoints | boolean | — | false | -| show-tooltip | whether to display tooltip value | boolean | — | true | -| format-tooltip | format to display tooltip value | function(value) | — | — | -| range | whether to select a range | boolean | — | false | -| vertical | vertical mode | boolean | — | false | -| height | Slider height, required in vertical mode | string | — | — | -| label | label for screen reader | string | — | — | -| debounce | debounce delay when typing, in milliseconds, works when `show-input` is true | number | — | 300 | -| 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 | — | — | +| Attribute | Description | Type | Accepted Values | Default | +| --------------------- | --------------------------------------------------------------------------------------------------------- | --------------- | ----------------------- | ------- | +| model-value / v-model | binding value | number | — | 0 | +| min | minimum value | number | — | 0 | +| max | maximum value | number | — | 100 | +| disabled | whether Slider is disabled | boolean | — | false | +| step | step size | number | — | 1 | +| 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 | +| size | size of the slider | string | large / default / small | default | +| input-size | size of the input box, when set `size`, the default is the value of `size` | string | large / default / small | default | +| show-stops | whether to display breakpoints | boolean | — | false | +| show-tooltip | whether to display tooltip value | boolean | — | true | +| format-tooltip | format to display tooltip value | function(value) | — | — | +| range | whether to select a range | boolean | — | false | +| vertical | vertical mode | boolean | — | false | +| height | Slider height, required in vertical mode | string | — | — | +| label | label for screen reader | string | — | — | +| debounce | debounce delay when typing, in milliseconds, works when `show-input` is true | number | — | 300 | +| 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 diff --git a/docs/examples/slider/sizes.vue b/docs/examples/slider/sizes.vue new file mode 100644 index 0000000000..ecfd31705b --- /dev/null +++ b/docs/examples/slider/sizes.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/packages/components/slider/__tests__/slider.spec.ts b/packages/components/slider/__tests__/slider.spec.ts index 948110cc7a..249c05c366 100644 --- a/packages/components/slider/__tests__/slider.spec.ts +++ b/packages/components/slider/__tests__/slider.spec.ts @@ -33,6 +33,24 @@ describe('Slider', () => { }, 10) }) + it('sizes', () => { + const wrapper = mount({ + template: ` +
+ + +
+ `, + components: { Slider }, + data() { + return { + value: 0, + } + }, + }) + expect(wrapper.find('.el-slider--small').exists()).toBe(true) + }) + it('show tooltip', () => { const wrapper = mount({ template: ` diff --git a/packages/components/slider/src/index.vue b/packages/components/slider/src/index.vue index 60a3add79b..62e15591f9 100644 --- a/packages/components/slider/src/index.vue +++ b/packages/components/slider/src/index.vue @@ -1,29 +1,13 @@ + @@ -98,6 +97,8 @@ import { } from '@element-plus/utils/constants' import { off, on } from '@element-plus/utils/dom' 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 SliderMarker from './marker.vue' import { useMarks } from './useMarks' @@ -141,9 +142,13 @@ export default defineComponent({ type: Boolean, default: true, }, + size: { + type: String as PropType, + validator: isValidComponentSize, + }, inputSize: { type: String as PropType, - default: 'small', + validator: isValidComponentSize, }, showStops: { type: Boolean, @@ -223,6 +228,19 @@ export default defineComponent({ 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) useWatch(props, initData, minValue, maxValue, emit, elFormItem) @@ -277,6 +295,9 @@ export default defineComponent({ markList, sliderWrapper, + sliderWrapperSize, + sliderInputSize, + sliderKls, } }, }) diff --git a/packages/theme-chalk/src/common/var.scss b/packages/theme-chalk/src/common/var.scss index a95e12f3c9..72eb152ed9 100644 --- a/packages/theme-chalk/src/common/var.scss +++ b/packages/theme-chalk/src/common/var.scss @@ -904,7 +904,6 @@ $slider: map.merge( 'runway-bg-color': var(--el-border-color-light), 'stop-bg-color': var(--el-color-white), 'disable-color': var(--el-text-color-placeholder), - 'margin': 16px 0, 'border-radius': 3px, 'height': 6px, 'button-size': 20px, diff --git a/packages/theme-chalk/src/slider.scss b/packages/theme-chalk/src/slider.scss index 7a122f8fc9..aeafa15b8c 100644 --- a/packages/theme-chalk/src/slider.scss +++ b/packages/theme-chalk/src/slider.scss @@ -5,25 +5,36 @@ @use 'mixins/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 set-component-css-var('slider', $slider); } @include b(slider) { - @include utils-clearfix; + width: 100%; + height: map.get($slider-height, 'default'); + display: flex; + align-items: center; @include e(runway) { - width: 100%; + flex: 1; height: var(--el-slider-height); - margin: var(--el-slider-margin); background-color: var(--el-slider-runway-bg-color); border-radius: var(--el-slider-border-radius); position: relative; cursor: pointer; - vertical-align: middle; &.show-input { - margin-right: 160px; + margin-right: 30px; width: auto; } @@ -69,17 +80,8 @@ } @include e(input) { - float: right; - margin-top: 3px; + flex-shrink: 0; width: 130px; - - &.#{$namespace}-input-number--large { - margin-top: -2px; - } - - &.#{$namespace}-input-number--small { - margin-top: 5px; - } } @include e(bar) { @@ -168,6 +170,9 @@ @include when(vertical) { position: relative; + height: 100%; + flex: 0; + .#{$namespace}-slider__runway { width: var(--el-slider-height); height: 100%; @@ -186,68 +191,6 @@ .#{$namespace}-slider__stop { 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) { margin-top: 0; @@ -255,4 +198,12 @@ transform: translateY(50%); } } + + @each $size in (large, small) { + @include m($size) { + height: map.get($slider-height, $size); + @include e(runway) { + } + } + } }