Skip to content

Commit

Permalink
refactor(slider): add flip-marker prop and improve slots
Browse files Browse the repository at this point in the history
  • Loading branch information
qmhc committed Nov 1, 2023
1 parent 9ba017f commit 07c24b8
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 108 deletions.
8 changes: 7 additions & 1 deletion components/slider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@ export { sliderProps } from './props'
export type SliderExposed = ComponentPublicInstance & InstanceType<typeof Slider>

export type { SliderProps, SliderCProps } from './props'
export type { SliderCommonSlot, SliderMarker, SliderRawMarkers } from './symbol'
export type {
SliderMarker,
SliderRawMarkers,
SliderSlotParams,
SliderTriggerParams,
SliderMarkerSlotParams
} from './symbol'
1 change: 1 addition & 0 deletions components/slider/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const sliderProps = buildProps({
markers: [Object, Array] as PropType<SliderRawMarkers>,
markerOnly: booleanProp,
tipHover: booleanProp,
flipMarker: booleanProp,
onChange: eventProp<(value: number | number[]) => void>(),
onInput: eventProp<(value: number | number[]) => void>()
})
Expand Down
21 changes: 3 additions & 18 deletions components/slider/slider-trigger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { useNameHelper } from '@vexip-ui/config'
import { useModifier, useSetTimeout } from '@vexip-ui/hooks'
import type { TooltipExposed } from '@/components/tooltip'
import type { SliderCommonSlot } from './symbol'
defineOptions({ name: 'SliderTrigger' })
Expand Down Expand Up @@ -60,10 +59,7 @@ const props = defineProps({
const emit = defineEmits(['key-minus', 'key-plus'])
defineSlots<{
default: SliderCommonSlot,
tip: SliderCommonSlot
}>()
defineSlots<{ default: () => any, tip: () => any }>()
const nh = useNameHelper('slider')
Expand Down Expand Up @@ -175,23 +171,12 @@ function blur() {
@mouseenter="showTooltip"
@mouseleave="hideTooltip"
>
<slot
:value="value"
:disabled="disabled"
:loading="loading"
:sliding="sliding"
>
<slot>
<div :class="nh.be('handler')"></div>
</slot>
</div>
</template>
<slot
name="tip"
:value="value"
:disabled="disabled"
:loading="loading"
:sliding="sliding"
>
<slot name="tip">
{{ value }}
</slot>
</Tooltip>
Expand Down
91 changes: 64 additions & 27 deletions components/slider/slider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useSetTimeout } from '@vexip-ui/hooks'
import { decimalLength, throttle, toFixed } from '@vexip-ui/utils'
import { sliderProps } from './props'
import type { SliderCommonSlot, SliderMarker } from './symbol'
import type { SliderMarker, SliderMarkerSlot, SliderTriggerSlot } from './symbol'
const enum TriggerType {
START = 0,
Expand Down Expand Up @@ -44,16 +44,17 @@ const props = useProps('slider', _props, {
range: false,
markers: null,
markerOnly: false,
tipHover: false
tipHover: false,
flipMarker: false
})
const emit = defineEmits(['update:value'])
defineSlots<{
trigger: SliderCommonSlot,
tip: SliderCommonSlot,
point: (params: { marker: SliderMarker, value: number, inRange: boolean }) => any,
marker: (params: { marker: SliderMarker, value: number, inRange: boolean }) => any
trigger: SliderTriggerSlot,
tip: SliderTriggerSlot,
point: SliderMarkerSlot,
marker: SliderMarkerSlot
}>()
const nh = useNameHelper('slider')
Expand Down Expand Up @@ -97,6 +98,7 @@ const markerList = computed(() => {
return list.sort((prev, next) => prev.value - next.value)
})
const hasMarkerLabel = computed(() => !!markerList.value.find(({ marker }) => marker.label))
const className = computed(() => {
return {
[nh.b()]: true,
Expand All @@ -108,7 +110,8 @@ const className = computed(() => {
[nh.bm('disabled')]: props.disabled,
[nh.bm('loading')]: props.loading && props.loadingLock,
[nh.bm('reverse')]: props.reverse,
[nh.bm('with-marker')]: markerList.value.length
[nh.bm('with-marker')]: hasMarkerLabel.value,
[nh.bm('flip-marker')]: props.flipMarker
}
})
const stepDigit = computed(() => decimalLength(props.step))
Expand All @@ -132,12 +135,12 @@ const fillerStyle = computed(() => {
return {
transform: `
translate${vertical ? 'Y' : 'X'}(${reverse ? '-' : ''}${offset}%)
translateZ(0)
scale${vertical ? 'Y' : 'X'}(${
Math.abs(triggerPercent.value[0] - triggerPercent.value[1]) / 100
})
`,
translate${vertical ? 'Y' : 'X'}(${reverse ? '-' : ''}${offset}%)
translateZ(0)
scale${vertical ? 'Y' : 'X'}(${
Math.abs(triggerPercent.value[0] - triggerPercent.value[1]) / 100
})
`,
transformOrigin: `${vertical ? 50 : reverse ? 100 : 0}% ${vertical ? (reverse ? 100 : 0) : 50}%`
}
})
Expand Down Expand Up @@ -481,9 +484,13 @@ function blur() {
>
<slot
name="point"
:values="truthValue"
:sliding="sliding"
:marker="marker"
:value="value"
:marker-value="value"
:in-range="isValueInRange(value)"
:disabled="props.disabled"
:loading="props.loading"
>
<span :class="nh.be('dot')"></span>
</slot>
Expand All @@ -498,9 +505,13 @@ function blur() {
>
<slot
name="marker"
:values="truthValue"
:sliding="sliding"
:marker="marker"
:value="value"
:marker-value="value"
:in-range="isValueInRange(value)"
:disabled="props.disabled"
:loading="props.loading"
>
{{ marker.label }}
</slot>
Expand All @@ -526,12 +537,25 @@ function blur() {
@key-plus="handlePlus(0, $event)"
@key-minus="handleMinus(0, $event)"
>
<template #default="payload">
<slot v-if="$slots.trigger" name="trigger" v-bind="payload"></slot>
</template>
<template #tip="payload">
<slot name="tip" v-bind="payload">
{{ payload.value.toFixed(stepDigit) }}
<slot
v-if="$slots.trigger"
name="trigger"
type="start"
:value="truthValue[0]"
:sliding="sliding[0]"
:disabled="props.disabled"
:loading="props.loading"
></slot>
<template #tip>
<slot
name="tip"
type="start"
:value="truthValue[0]"
:sliding="sliding[0]"
:disabled="props.disabled"
:loading="props.loading"
>
{{ truthValue[0] }}
</slot>
</template>
</SliderTrigger>
Expand All @@ -552,12 +576,25 @@ function blur() {
@key-plus="handlePlus(1, $event)"
@key-minus="handleMinus(1, $event)"
>
<template #default="payload">
<slot v-if="$slots.trigger" name="trigger" v-bind="payload"></slot>
</template>
<template #tip="payload">
<slot name="tip" v-bind="payload">
{{ payload.value.toFixed(stepDigit) }}
<slot
v-if="$slots.trigger"
name="trigger"
type="end"
:value="truthValue[1]"
:sliding="sliding[1]"
:disabled="props.disabled"
:loading="props.loading"
></slot>
<template #tip>
<slot
name="tip"
type="end"
:value="truthValue[1]"
:sliding="sliding[1]"
:disabled="props.disabled"
:loading="props.loading"
>
{{ truthValue[1] }}
</slot>
</template>
</SliderTrigger>
Expand Down
31 changes: 22 additions & 9 deletions components/slider/symbol.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
import type { ClassType, StyleType } from '@vexip-ui/config'

export interface SliderSlotParams {
value: number,
disabled: boolean,
loading: boolean,
sliding: boolean
}

export type SliderCommonSlot = (params: SliderSlotParams) => any

export interface SliderMarker {
label?: string,
class?: ClassType,
Expand All @@ -19,3 +10,25 @@ export interface SliderMarker {
export type SliderRawMarkers =
| Record<string | number, string | SliderMarker>
| Array<number | (SliderMarker & { value: number })>

export interface SliderSlotParams {
disabled: boolean,
loading: boolean
}

export interface SliderTriggerParams extends SliderSlotParams {
type: 'start' | 'end',
value: number,
sliding: boolean
}

export interface SliderMarkerSlotParams extends SliderSlotParams {
values: number[],
sliding: boolean[],
markerValue: number,
marker: SliderMarker,
inRange: boolean
}

export type SliderTriggerSlot = (params: SliderTriggerParams) => any
export type SliderMarkerSlot = (params: SliderMarkerSlotParams) => any
47 changes: 36 additions & 11 deletions docs/demos/slider/markers/demo.en-US.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,62 @@
<template>
<p>
Disabled:
<Switch v-model:value="disabled"></Switch>
<Switch v-model:value="state.disabled"></Switch>
</p>
<p>
Reverse:
<Switch v-model:value="state.reverse"></Switch>
</p>
<p>
Flip Marker:
<Switch v-model:value="state.flipMarker"></Switch>
</p>
<p>
With Label:
<Switch v-model:value="withLabel"></Switch>
</p>
<Space vertical style="max-width: 400px; margin-bottom: 20px">
<Slider :value="56" :disabled="disabled" :markers="markers"></Slider>
<Slider v-bind="state" :value="56" :markers="markers"></Slider>
<Slider
:value="[28, 56]"
v-bind="state"
:value="[18, 76]"
:min="-50"
:max="150"
range
:disabled="disabled"
:markers="markers"
></Slider>
</Space>
<Space :size="[24, 16]" :disabled="disabled" style="height: 200px; margin-bottom: 20px">
<Space :size="[24, 16]" style="height: 200px; margin-bottom: 20px">
<Slider
v-bind="state"
:value="56"
vertical
:disabled="disabled"
:markers="markers"
></Slider>
<Slider
:value="[28, 56]"
v-bind="state"
:value="[18, 76]"
:min="-50"
:max="150"
vertical
range
:disabled="disabled"
:markers="markers"
></Slider>
</Space>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { computed, reactive, ref } from 'vue'
const disabled = ref(false)
const state = reactive({
disabled: false,
reverse: false,
flipMarker: false
})
const markers = ref({
const withLabel = ref(true)
const labelMarkers = {
0: '0°C',
42: '42°C',
68: {
Expand All @@ -49,5 +69,10 @@ const markers = ref({
},
label: '100°C'
}
}
const noLabelMarkers = [0, 42, 68, 100]
const markers = computed(() => {
return withLabel.value ? labelMarkers : noLabelMarkers
})
</script>
Loading

0 comments on commit 07c24b8

Please sign in to comment.