-
Notifications
You must be signed in to change notification settings - Fork 3
/
slider.ts
147 lines (125 loc) · 4.14 KB
/
slider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { html } from 'lit';
import { property } from 'lit/decorators.js';
import { Constructor } from '../common/mixins/constructor.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { IgcSliderBaseComponent } from './slider-base.js';
export interface IgcSliderEventMap {
/**
* Emitted when a value is changed via thumb drag or keyboard interaction.
*/
igcInput: CustomEvent<number>;
/**
* Emitted when a value change is committed on a thumb drag end or keyboard interaction.
*/
igcChange: CustomEvent<number>;
}
/**
* A slider component used to select numeric value within a range.
*
* @element igc-slider
*
* @fires igcInput - Emitted when a value is changed via thumb drag or keyboard interaction.
* @fires igcChange - Emitted when a value change is committed on a thumb drag end or keyboard interaction.
*
* @csspart base - The base wrapper of the slider.
* @csspart ticks - The ticks container.
* @csspart tick-group - The tick group container.
* @csspart tick - The tick element.
* @csspart tick-label - The tick label element.
* @csspart tick-label-inner - The inner element of the tick label.
* @csspart thumbs - The thumbs container.
* @csspart thumb - The thumb element.
* @csspart thumb-label - The thumb tooltip label container.
* @csspart thumb-label-inner - The thumb tooltip label inner element.
* @csspart track - The track container.
* @csspart steps - The track steps element.
* @csspart inactive - The inactive element of the track.
* @csspart fill - The filled part of the track.
*/
export default class IgcSliderComponent extends EventEmitterMixin<
IgcSliderEventMap,
Constructor<IgcSliderBaseComponent>
>(IgcSliderBaseComponent) {
public static readonly tagName = 'igc-slider';
private _value = 0;
private _ariaLabel!: string;
public set value(val: number) {
const oldVal = this._value;
this._value = this.validateValue(val);
this.requestUpdate('value', oldVal);
}
/**
* The current value of the slider.
* @attr
*/
@property({ type: Number })
public get value() {
return this._value;
}
public override set ariaLabel(value: string) {
const oldVal = this._ariaLabel;
this._ariaLabel = value;
if (this.hasAttribute('aria-label')) {
this.removeAttribute('aria-label');
}
this.requestUpdate('ariaLabel', oldVal);
}
/**
* The aria label of the slider thumb.
* @attr
*/
@property({ attribute: 'aria-label' })
public override get ariaLabel() {
return this._ariaLabel;
}
protected override get activeValue(): number {
return this.value;
}
protected override normalizeValue(): void {
this._value = this.validateValue(this._value);
}
protected override getTrackStyle() {
const position = this.valueToFraction(this.value);
const filledTrackStyle = {
width: `${position * 100}%`,
};
return filledTrackStyle;
}
protected override updateValue(increment: number) {
const oldValue = this.value;
this.value = (this.value as number) + increment;
if (oldValue === this.value) {
return false;
}
this.emitInputEvent();
return true;
}
protected override emitInputEvent() {
this.emitEvent('igcInput', { detail: this.value });
}
protected override emitChangeEvent() {
this.emitEvent('igcChange', { detail: this.value });
}
/**
* Increments the value of the slider by `stepIncrement * step`, where `stepIncrement` defaults to 1.
* @param stepIncrement Optional step increment. If no parameter is passed, it defaults to 1.
*/
public stepUp(stepIncrement = 1) {
this.value = this.value + stepIncrement * this.step;
}
/**
* Decrements the value of the slider by `stepDecrement * step`, where `stepDecrement` defaults to 1.
* @param stepDecrement Optional step decrement. If no parameter is passed, it defaults to 1.
*/
public stepDown(stepDecrement = 1) {
this.value = this.value - stepDecrement * this.step;
}
protected override renderThumbs() {
return html`${this.renderThumb(this.value, this.ariaLabel)}`;
}
}
declare global {
interface HTMLElementTagNameMap {
'igc-slider': IgcSliderComponent;
}
}