feat(components): [slider] placement (#8561)

* feat(components): [slider] placement

feat: add fallback placements

feat: rename tooltip-placement

refactor: test code

docs: add placement attribute

docs: prettier

* docs: example placement
This commit is contained in:
류한경
2022-07-04 23:35:53 +09:00
committed by GitHub
parent 9f42ce8694
commit 5b817d3008
7 changed files with 98 additions and 26 deletions

View File

@@ -45,6 +45,16 @@ slider/sizes
:::
## Placement
You can custom tooltip placement.
:::demo
slider/placement
:::
## Range selection
Selecting a range of values is supported.
@@ -73,31 +83,32 @@ 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 |
| 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 | — | — |
| range-start-label | when `range` is true, screen reader label for the start of the range | string | — | — |
| range-end-label | when `range` is true, screen reader label for the end of the range | string | — | — |
| format-value-text | format to display the `aria-valuenow` attribute for screen readers | function(value) | — | — |
| 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 | — | — |
| validate-event | whether to trigger form validation | boolean | - | true |
| 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 | — | — |
| range-start-label | when `range` is true, screen reader label for the start of the range | string | — | — |
| range-end-label | when `range` is true, screen reader label for the end of the range | string | — | — |
| format-value-text | format to display the `aria-valuenow` attribute for screen readers | function(value) | — | — |
| debounce | debounce delay when typing, in milliseconds, works when `show-input` is true | number | — | 300 |
| tooltip-class | custom class name for the tooltip | string | — | — |
| placement | position of Tooltip | string | top/top-start/top-end/bottom/bottom-start/bottom-end/left/left-start/left-end/right/right-start/right-end | top |
| marks | marks type of key must be `number` and must in closed interval `[min, max]`, each mark can custom style | object | — | |
| validate-event | whether to trigger form validation | boolean | - | true |
## Events

View File

@@ -0,0 +1,33 @@
<template>
<div class="slider-demo-block">
<el-slider v-model="value1" />
</div>
<div class="slider-demo-block">
<el-slider v-model="value2" placement="bottom" />
</div>
<div class="slider-demo-block">
<el-slider v-model="value3" placement="right" />
</div>
<div class="slider-demo-block">
<el-slider v-model="value4" placement="left" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value1 = ref(0)
const value2 = ref(0)
const value3 = ref(0)
const value4 = ref(0)
</script>
<style scoped>
.slider-demo-block {
display: flex;
align-items: center;
}
.slider-demo-block .el-slider {
margin-top: 0;
margin-left: 12px;
}
</style>

View File

@@ -89,6 +89,19 @@ describe('Slider', () => {
expect(slider.vm.formatValue).toBe('$0')
})
it('placement', async () => {
const TOOLTIP_CLASS = 'custom_tooltip'
const PLACEMENT = 'right'
mount(() => <Slider tooltip-class={TOOLTIP_CLASS} placement={PLACEMENT} />)
await nextTick()
expect(
document.querySelector(`.${TOOLTIP_CLASS}`).dataset.popperPlacement
).toBe(PLACEMENT)
})
describe('drag', () => {
it('horizontal', async () => {
vi.useRealTimers()

View File

@@ -1,3 +1,4 @@
import { placements } from '@popperjs/core'
import { buildProps, isNumber } from '@element-plus/utils'
import { UPDATE_MODEL_EVENT } from '@element-plus/constants'
import type { ExtractPropTypes, Ref } from 'vue'
@@ -10,6 +11,11 @@ export const sliderButtonProps = buildProps({
},
vertical: Boolean,
tooltipClass: String,
placement: {
type: String,
values: placements,
default: 'top',
},
} as const)
export type SliderButtonProps = ExtractPropTypes<typeof sliderButtonProps>

View File

@@ -15,7 +15,8 @@
<el-tooltip
ref="tooltip"
v-model:visible="tooltipVisible"
placement="top"
:placement="placement"
:fallback-placements="['top', 'bottom', 'right', 'left']"
:stop-popper-mouse-event="false"
:popper-class="tooltipClass"
:disabled="!showTooltip"

View File

@@ -1,3 +1,4 @@
import { placements } from '@popperjs/core'
import {
buildProps,
definePropType,
@@ -90,6 +91,11 @@ export const sliderProps = buildProps({
type: String,
default: undefined,
},
placement: {
type: String,
values: placements,
default: 'top',
},
marks: {
type: definePropType<SliderMarks>(Object),
},

View File

@@ -29,6 +29,7 @@
:model-value="firstValue"
:vertical="vertical"
:tooltip-class="tooltipClass"
:placement="placement"
role="slider"
:aria-label="
range || !isLabeledByFormItem ? firstButtonLabel : undefined
@@ -50,6 +51,7 @@
:model-value="secondValue"
:vertical="vertical"
:tooltip-class="tooltipClass"
:placement="placement"
role="slider"
:aria-label="secondButtonLabel"
:aria-valuemin="firstValue"