UNPKG

3.21 kBTypeScriptView Raw
1import { Component, Prop, Vue } from 'vue-property-decorator'
2import { Value, Styles, Position, TooltipProp, TooltipFormatter } from './typings'
3
4import './styles/dot.scss'
5
6@Component({ name: 'VueSliderDot' })
7export default class VueSliderDot extends Vue {
8 $refs!: {
9 dot: HTMLDivElement
10 }
11
12 @Prop({ default: 0 })
13 value!: Value
14
15 @Prop() tooltip!: TooltipProp
16
17 @Prop() dotStyle?: Styles
18
19 @Prop() tooltipStyle?: Styles
20
21 @Prop({
22 type: String,
23 validator: (val: string) => ['top', 'right', 'bottom', 'left'].indexOf(val) > -1,
24 required: true,
25 })
26 tooltipPlacement!: Position
27
28 @Prop({ type: [String, Function] })
29 tooltipFormatter?: TooltipFormatter
30
31 @Prop({ type: Boolean, default: false })
32 focus!: boolean
33
34 @Prop({ default: false })
35 disabled!: boolean
36
37 get dotClasses() {
38 return [
39 'vue-slider-dot',
40 {
41 'vue-slider-dot-hover': this.tooltip === 'hover' || this.tooltip === 'active',
42 'vue-slider-dot-disabled': this.disabled,
43 'vue-slider-dot-focus': this.focus,
44 },
45 ]
46 }
47
48 get handleClasses() {
49 return [
50 'vue-slider-dot-handle',
51 {
52 'vue-slider-dot-handle-disabled': this.disabled,
53 'vue-slider-dot-handle-focus': this.focus,
54 },
55 ]
56 }
57
58 get tooltipClasses() {
59 return [
60 'vue-slider-dot-tooltip',
61 [`vue-slider-dot-tooltip-${this.tooltipPlacement}`],
62 {
63 'vue-slider-dot-tooltip-show': this.showTooltip,
64 },
65 ]
66 }
67
68 get tooltipInnerClasses() {
69 return [
70 'vue-slider-dot-tooltip-inner',
71 [`vue-slider-dot-tooltip-inner-${this.tooltipPlacement}`],
72 {
73 'vue-slider-dot-tooltip-inner-disabled': this.disabled,
74 'vue-slider-dot-tooltip-inner-focus': this.focus,
75 },
76 ]
77 }
78
79 get showTooltip(): boolean {
80 switch (this.tooltip) {
81 case 'always':
82 return true
83 case 'none':
84 return false
85 case 'focus':
86 case 'active':
87 return !!this.focus
88 default:
89 return false
90 }
91 }
92
93 get tooltipValue(): Value {
94 if (this.tooltipFormatter) {
95 return typeof this.tooltipFormatter === 'string'
96 ? this.tooltipFormatter.replace(/\{value\}/, String(this.value))
97 : this.tooltipFormatter(this.value)
98 } else {
99 return this.value
100 }
101 }
102
103 dragStart(e: MouseEvent | TouchEvent) {
104 if (this.disabled) {
105 return false
106 }
107
108 this.$emit('drag-start')
109 }
110
111 render() {
112 return (
113 <div
114 ref="dot"
115 class={this.dotClasses}
116 aria-valuetext={
117 typeof this.tooltipValue === 'number' ? this.tooltipValue.toString() : this.tooltipValue
118 }
119 onMousedown={this.dragStart}
120 onTouchstart={this.dragStart}
121 >
122 {this.$slots.dot || <div class={this.handleClasses} style={this.dotStyle} />}
123 {this.tooltip !== 'none' ? (
124 <div class={this.tooltipClasses}>
125 {this.$slots.tooltip || (
126 <div class={this.tooltipInnerClasses} style={this.tooltipStyle}>
127 <span class={'vue-slider-dot-tooltip-text'}>{this.tooltipValue}</span>
128 </div>
129 )}
130 </div>
131 ) : null}
132 </div>
133 )
134 }
135}