mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-04-12 14:40:47 +08:00
feat(slider): add render function support for marks
prop (#6008)
* feat(`n-slider`): add render function support for `marks` prop * chore: update `marks` prop type to support render function --------- Co-authored-by: 07akioni <07akioni2@gmail.com>
This commit is contained in:
parent
e03f00ab87
commit
b0439c8a15
@ -17,6 +17,7 @@
|
||||
- `n-date-picker` adds `clear` `now` `confirm` slot, closes [#6013](https://github.com/tusen-ai/naive-ui/issues/6013).
|
||||
- `n-upload` adds `on-retry` prop, closes [#6031](https://github.com/tusen-ai/naive-ui/issues/6031)
|
||||
- Adds `n-highlight` component.
|
||||
- `n-slider` `marks` prop to support render function, closes [#5967](https://github.com/tusen-ai/naive-ui/issues/5967)
|
||||
|
||||
## 2.39.0
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
- `n-date-picker` 新增 `clear` `now` `confirm` 插槽,关闭 [#6013](https://github.com/tusen-ai/naive-ui/issues/6013)
|
||||
- `n-upload` 新增 `on-retry`属性,关闭 [#6031](https://github.com/tusen-ai/naive-ui/issues/6031)
|
||||
- 新增 `n-highlight` 组件
|
||||
- `n-slider` `marks` 支持渲染函数,关闭 [#5967](https://github.com/tusen-ai/naive-ui/issues/5967)
|
||||
|
||||
## 2.39.0
|
||||
|
||||
|
53
src/slider/demos/enUS/custom-marks.demo.vue
Normal file
53
src/slider/demos/enUS/custom-marks.demo.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<markdown>
|
||||
# Custom Mark
|
||||
|
||||
You can use `marks` prop to customize handle button.
|
||||
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-space style="height: 300px; justify-content: space-evenly">
|
||||
<n-slider v-model:value="value" :marks="marks" vertical range />
|
||||
<n-slider v-model:value="value" :marks="customMarks" vertical range />
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, h } from 'vue'
|
||||
import Temperature16Regular from '@vicons/fluent/Temperature16Regular'
|
||||
import { NIcon } from '../../../icon'
|
||||
import { NFlex } from '../../../flex'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const renderMark = (value: number, color: string) => {
|
||||
return h(
|
||||
NFlex,
|
||||
{ style: { width: '120px' } },
|
||||
{
|
||||
default: () => [
|
||||
h(NIcon, { size: 24, color, component: Temperature16Regular }),
|
||||
h('span', { style: { color } }, `${value}°C`)
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
value: ref([20, 70]),
|
||||
marks: {
|
||||
0: '0°C',
|
||||
20: '20°C',
|
||||
60: '60°C',
|
||||
100: '100°C'
|
||||
},
|
||||
customMarks: {
|
||||
0: () => renderMark(0, '#0048BA'),
|
||||
20: () => renderMark(20, '#00BFFF'),
|
||||
60: () => renderMark(60, '#FFA500'),
|
||||
100: () => renderMark(100, '#FF4500')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -17,6 +17,7 @@ vertical.vue
|
||||
show-tooltip.vue
|
||||
multiple-debug.vue
|
||||
custom-thumb.vue
|
||||
custom-marks.vue
|
||||
```
|
||||
|
||||
## API
|
||||
@ -29,7 +30,7 @@ custom-thumb.vue
|
||||
| disabled | `boolean` | `false` | Whether the slider is disabled. | |
|
||||
| format-tooltip | `(value: number) => string \| number` | `undefined` | Format tooltip. | |
|
||||
| keyboard | `boolean` | `true` | Whether the slider can be controlled keyboard. | 2.33.0 |
|
||||
| marks | `{ [markValue: number]: string }` | `undefined` | Marks of the slider. | |
|
||||
| marks | `{ [markValue: number]: string \| (() => VNodeChild) }` | `undefined` | Marks of the slider, Render function since NEXT_VERSION. | |
|
||||
| max | `number` | `100` | Max value of the slider. | |
|
||||
| min | `number` | `0` | Min value of the slider. | |
|
||||
| placement | `'top-start' \| 'top' \| 'top-end' \| 'right-start' \| 'right' \| 'right-end' \| 'bottom-start' \| 'bottom' \| 'bottom-end' \| 'left-start' \| 'left' \| 'left-end'` | `undefined` | Tooltip's placement | 2.25.0 |
|
||||
|
53
src/slider/demos/zhCN/custom-marks.demo.vue
Normal file
53
src/slider/demos/zhCN/custom-marks.demo.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<markdown>
|
||||
# 自定义标记
|
||||
|
||||
可以使用 `marks` 插槽自定义刻度。
|
||||
|
||||
</markdown>
|
||||
|
||||
<template>
|
||||
<n-space style="height: 300px; justify-content: space-evenly">
|
||||
<n-slider v-model:value="value" :marks="marks" vertical range />
|
||||
<n-slider v-model:value="value" :marks="customMarks" vertical range />
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, h } from 'vue'
|
||||
import Temperature16Regular from '@vicons/fluent/Temperature16Regular'
|
||||
import { NIcon } from '../../../icon'
|
||||
import { NFlex } from '../../../flex'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const renderMark = (value: number, color: string) => {
|
||||
return h(
|
||||
NFlex,
|
||||
{ style: { width: '120px' } },
|
||||
{
|
||||
default: () => [
|
||||
h(NIcon, { size: 24, color, component: Temperature16Regular }),
|
||||
h('span', { style: { color } }, `${value}°C`)
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
value: ref([20, 70]),
|
||||
marks: {
|
||||
0: '0°C',
|
||||
20: '20°C',
|
||||
60: '60°C',
|
||||
100: '100°C'
|
||||
},
|
||||
customMarks: {
|
||||
0: () => renderMark(0, '#0048BA'),
|
||||
20: () => renderMark(20, '#00BFFF'),
|
||||
60: () => renderMark(60, '#FFA500'),
|
||||
100: () => renderMark(100, '#FF4500')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -17,6 +17,7 @@ vertical.vue
|
||||
show-tooltip.vue
|
||||
multiple-debug.vue
|
||||
custom-thumb.vue
|
||||
custom-marks.vue
|
||||
keyboard-debug.vue
|
||||
```
|
||||
|
||||
@ -30,7 +31,7 @@ keyboard-debug.vue
|
||||
| disabled | `boolean` | `false` | 是否禁用 | |
|
||||
| format-tooltip | `(value: number) => string \| number` | `undefined` | 格式化 tooltip | |
|
||||
| keyboard | `boolean` | `true` | 是否可键盘控制 | 2.33.0 |
|
||||
| marks | `{ [markValue: number]: string }` | `undefined` | Slider 上的标记 | |
|
||||
| marks | `{ [markValue: number]: string \| (() => VNodeChild) }` | `undefined` | Slider 上的标记,NEXT_VERSION 支持 render 函数 | |
|
||||
| max | `number` | `100` | 最大值 | |
|
||||
| min | `number` | `0` | 最小值 | |
|
||||
| placement | `'top-start' \| 'top' \| 'top-end' \| 'right-start' \| 'right' \| 'right-end' \| 'bottom-start' \| 'bottom' \| 'bottom-end' \| 'left-start' \| 'left' \| 'left-end'` | `undefined` | Tooltip 的弹出位置 | 2.25.0 |
|
||||
|
@ -2,6 +2,7 @@ import {
|
||||
type CSSProperties,
|
||||
type ComponentPublicInstance,
|
||||
type PropType,
|
||||
type VNodeChild,
|
||||
Transition,
|
||||
computed,
|
||||
defineComponent,
|
||||
@ -56,7 +57,7 @@ export const sliderProps = {
|
||||
type: [Number, Array] as PropType<number | number[]>,
|
||||
default: 0
|
||||
},
|
||||
marks: Object as PropType<Record<string, string>>,
|
||||
marks: Object as PropType<Record<string, string | (() => VNodeChild)>>,
|
||||
disabled: {
|
||||
type: Boolean as PropType<boolean | undefined>,
|
||||
default: undefined
|
||||
@ -205,7 +206,8 @@ export default defineComponent({
|
||||
const markInfosRef = computed(() => {
|
||||
const mergedMarks: Array<{
|
||||
active: boolean
|
||||
label: string
|
||||
label: string | (() => VNodeChild)
|
||||
key: number
|
||||
style: CSSProperties
|
||||
}> = []
|
||||
const { marks } = props
|
||||
@ -226,6 +228,7 @@ export default defineComponent({
|
||||
const num = Number(key)
|
||||
mergedMarks.push({
|
||||
active: isActive(num),
|
||||
key: num,
|
||||
label: marks[key],
|
||||
style: {
|
||||
[styleDirection]: `${valueToPercentage(num)}%`
|
||||
@ -718,7 +721,7 @@ export default defineComponent({
|
||||
>
|
||||
{this.markInfos.map(mark => (
|
||||
<div
|
||||
key={mark.label}
|
||||
key={mark.key}
|
||||
class={[
|
||||
`${mergedClsPrefix}-slider-dot`,
|
||||
{
|
||||
@ -843,11 +846,11 @@ export default defineComponent({
|
||||
<div class={`${mergedClsPrefix}-slider-marks`}>
|
||||
{this.markInfos.map(mark => (
|
||||
<div
|
||||
key={mark.label}
|
||||
key={mark.key}
|
||||
class={`${mergedClsPrefix}-slider-mark`}
|
||||
style={mark.style}
|
||||
>
|
||||
{mark.label}
|
||||
{typeof mark.label === 'function' ? mark.label() : mark.label}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user