7
7
*/
8
8
9
9
import {
10
+ BooleanInput ,
11
+ coerceBooleanProperty ,
12
+ coerceNumberProperty ,
13
+ NumberInput
14
+ } from '@angular/cdk/coercion' ;
15
+ import { Platform } from '@angular/cdk/platform' ;
16
+ import { DOCUMENT } from '@angular/common' ;
17
+ import {
18
+ AfterViewInit ,
10
19
ChangeDetectionStrategy ,
20
+ ChangeDetectorRef ,
11
21
Component ,
22
+ ContentChildren ,
23
+ ElementRef ,
24
+ Inject ,
25
+ Input ,
26
+ OnDestroy ,
27
+ QueryList ,
28
+ ViewChild ,
29
+ ViewChildren ,
12
30
ViewEncapsulation ,
13
31
} from '@angular/core' ;
14
- import { MDCSliderFoundation } from '@material/slider' ;
32
+ import { MDCSliderFoundation , Thumb , TickMark } from '@material/slider' ;
15
33
import { SliderAdapter } from './slider-adapter' ;
34
+ import { MatSliderThumb } from './slider-thumb' ;
16
35
17
36
/**
18
37
* Allows users to select from a range of values by moving the slider thumb. It is similar in
@@ -22,13 +41,207 @@ import {SliderAdapter} from './slider-adapter';
22
41
selector : 'mat-slider' ,
23
42
templateUrl : 'slider.html' ,
24
43
styleUrls : [ 'slider.css' ] ,
44
+ host : {
45
+ 'class' : 'mat-mdc-slider mdc-slider' ,
46
+ '[class.mdc-slider--range]' : '_isRange()' ,
47
+ '[class.mdc-slider--disabled]' : 'disabled' ,
48
+ '[class.mdc-slider--discrete]' : 'discrete' ,
49
+ '[class.mdc-slider--tick-marks]' : 'showTickMarks' ,
50
+ } ,
51
+ exportAs : 'matSlider' ,
25
52
changeDetection : ChangeDetectionStrategy . OnPush ,
26
53
encapsulation : ViewEncapsulation . None ,
27
54
} )
28
- export class MatSlider {
55
+ export class MatSlider implements AfterViewInit , OnDestroy {
56
+ /** The slider thumb(s). */
57
+ @ViewChildren ( 'thumb' ) _thumbs : QueryList < ElementRef < HTMLElement > > ;
29
58
30
- /** Instance of the MDC slider foundation for this slider. */
59
+ /** The slider thumb knob(s) */
60
+ @ViewChildren ( 'knob' ) _knobs : QueryList < ElementRef < HTMLElement > > ;
61
+
62
+ /** The active section of the slider track. */
63
+ @ViewChild ( 'trackActive' ) _trackActive : ElementRef < HTMLElement > ;
64
+
65
+ /** The sliders hidden range input(s). */
66
+ @ContentChildren ( MatSliderThumb , { descendants : false } ) _inputs : QueryList < MatSliderThumb > ;
67
+
68
+ /** Whether the slider is disabled. */
69
+ @Input ( )
70
+ get disabled ( ) : boolean { return this . _disabled ; }
71
+ set disabled ( v : boolean ) {
72
+ this . _disabled = coerceBooleanProperty ( v ) ;
73
+
74
+ // If we want to disable the slider after the foundation has been initialized,
75
+ // we need to inform the foundation by calling `setDisabled`. Also, we can't call
76
+ // this before initializing the foundation because it will throw errors.
77
+ if ( this . _initialized ) {
78
+ this . _foundation . setDisabled ( v ) ;
79
+ }
80
+ }
81
+ private _disabled : boolean = false ;
82
+
83
+ /** Whether the slider displays a numeric value label upon pressing the thumb. */
84
+ @Input ( )
85
+ get discrete ( ) : boolean { return this . _discrete ; }
86
+ set discrete ( v : boolean ) { this . _discrete = coerceBooleanProperty ( v ) ; }
87
+ private _discrete : boolean = false ;
88
+
89
+ /** Whether the slider displays tick marks along the slider track. */
90
+ @Input ( )
91
+ get showTickMarks ( ) : boolean { return this . _showTickMarks ; }
92
+ set showTickMarks ( v : boolean ) {
93
+ this . _showTickMarks = coerceBooleanProperty ( v ) ;
94
+ }
95
+ private _showTickMarks : boolean = false ;
96
+
97
+ /** The minimum value that the slider can have. */
98
+ @Input ( )
99
+ get min ( ) : number { return this . _min ; }
100
+ set min ( v : number ) { this . _min = coerceNumberProperty ( v , this . _min ) ; }
101
+ private _min = 0 ;
31
102
32
- // tslint:disable-next-line:no-unused-variable
103
+ /** The maximum value that the slider can have. */
104
+ @Input ( )
105
+ get max ( ) : number { return this . _max ; }
106
+ set max ( v : number ) { this . _max = coerceNumberProperty ( v , this . _max ) ; }
107
+ private _max = 100 ;
108
+
109
+ /** The values at which the thumb will snap. */
110
+ @Input ( )
111
+ get step ( ) : number { return this . _step ; }
112
+ set step ( v : number ) { this . _step = coerceNumberProperty ( v , this . _step ) ; }
113
+ private _step : number = 1 ;
114
+
115
+ /**
116
+ * Function that will be used to format the value before it is displayed
117
+ * in the thumb label. Can be used to format very large number in order
118
+ * for them to fit into the slider thumb.
119
+ */
120
+ @Input ( ) displayWith : ( ( value : number ) => string ) | null ;
121
+
122
+ /** Instance of the MDC slider foundation for this slider. */
33
123
private _foundation = new MDCSliderFoundation ( new SliderAdapter ( ) ) ;
124
+
125
+ /** Whether the foundation has been initialized. */
126
+ _initialized : boolean = false ;
127
+
128
+ /** The string representation of the start thumbs value. */
129
+ _startValueIndicatorText : string ;
130
+
131
+ /** The string representation of the end thumbs value. */
132
+ _endValueIndicatorText : string ;
133
+
134
+ /** The injected document if available or fallback to the global document reference. */
135
+ _document : Document ;
136
+
137
+ /**
138
+ * The defaultView of the injected document if
139
+ * available or fallback to global window reference.
140
+ */
141
+ _window : Window ;
142
+
143
+ /** The hosts native HTML element. */
144
+ _hostElement : HTMLElement ;
145
+
146
+ /** Used to keep track of & render the active & inactive tick marks on the slider track. */
147
+ _tickMarks : TickMark [ ] ;
148
+
149
+ constructor (
150
+ readonly _cdr : ChangeDetectorRef ,
151
+ private readonly _elementRef : ElementRef < HTMLElement > ,
152
+ private readonly _platform : Platform ,
153
+ @Inject ( DOCUMENT ) document : any ) {
154
+ this . _document = document ;
155
+ this . _window = this . _document . defaultView || window ;
156
+ this . _hostElement = this . _elementRef . nativeElement ;
157
+ }
158
+
159
+ ngAfterViewInit ( ) {
160
+ this . _foundation . init ( ) ;
161
+ if ( this . _platform . isBrowser ) {
162
+ this . _foundation . layout ( ) ;
163
+ }
164
+ this . _initialized = true ;
165
+ }
166
+
167
+ ngOnDestroy ( ) {
168
+ if ( this . _platform . isBrowser ) {
169
+ this . _foundation . destroy ( ) ;
170
+ }
171
+ }
172
+
173
+ /** Gets the current value of given slider thumb. */
174
+ _getValue ( thumb : Thumb ) : number {
175
+ return thumb === Thumb . START
176
+ ? this . _foundation . getValueStart ( )
177
+ : this . _foundation . getValue ( ) ;
178
+ }
179
+
180
+ /** Sets the value of a slider thumb. */
181
+ _setValue ( value : number , thumb : Thumb ) : void {
182
+ thumb === Thumb . START
183
+ ? this . _foundation . setValueStart ( value )
184
+ : this . _foundation . setValue ( value ) ;
185
+ }
186
+
187
+ /** Whether this is a ranged slider. */
188
+ _isRange ( ) : boolean {
189
+ return this . _inputs . length === 2 ;
190
+ }
191
+
192
+ /** Gets the slider thumb input of the given thumb. */
193
+ _getInput ( thumb : Thumb ) : MatSliderThumb {
194
+ return thumb === Thumb . END ? this . _inputs . get ( this . _inputs . length - 1 ) ! : this . _inputs . get ( 0 ) ! ;
195
+ }
196
+
197
+ /** Gets the slider thumb HTML input element of the given thumb. */
198
+ _getInputElement ( thumb : Thumb ) : HTMLInputElement {
199
+ return this . _getInput ( thumb ) . _elementRef . nativeElement ;
200
+ }
201
+
202
+ /** Gets the slider thumb HTML element of the given thumb. */
203
+ _getThumbElement ( thumb : Thumb ) : HTMLElement {
204
+ const thumbs = this . _thumbs . toArray ( ) . map ( e => e . nativeElement ) ;
205
+ return thumb === Thumb . END ? thumbs [ thumbs . length - 1 ] : thumbs [ 0 ] ;
206
+ }
207
+
208
+ /** Gets the slider knob HTML element of the given thumb. */
209
+ _getKnobElement ( thumb : Thumb ) : HTMLElement {
210
+ const knobs = this . _knobs . toArray ( ) . map ( e => e . nativeElement ) ;
211
+ return thumb === Thumb . END ? knobs [ knobs . length - 1 ] : knobs [ 0 ] ;
212
+ }
213
+
214
+ /**
215
+ * Gets the text representation of the given value.
216
+ *
217
+ * Uses the `displayWith` function if one has been provided. Otherwise, it just returns the
218
+ * current numeric value as a string.
219
+ */
220
+ _getValueIndicatorText ( value : number ) : string {
221
+ return this . displayWith ? this . displayWith ( value ) : value . toString ( ) ;
222
+ }
223
+
224
+ /** Gets the text representation of the current value of the given thumb. */
225
+ _getValueIndicatorTextByThumb ( thumb : Thumb ) : string {
226
+ return this . _getValueIndicatorText ( this . _getValue ( thumb ) ) ;
227
+ }
228
+
229
+ /** Determines the class name for a HTML element. */
230
+ _getTickMarkClass ( tickMark : TickMark ) : string {
231
+ return tickMark === TickMark . ACTIVE
232
+ ? 'mdc-slider__tick-mark--active'
233
+ : 'mdc-slider__tick-mark--inactive' ;
234
+ }
235
+
236
+ /** Returns an array of the thumb types that exist on the current slider instance. */
237
+ _getThumbTypes ( ) : Thumb [ ] {
238
+ return this . _isRange ( ) ? [ Thumb . START , Thumb . END ] : [ Thumb . END ] ;
239
+ }
240
+
241
+ static ngAcceptInputType_disabled : BooleanInput ;
242
+ static ngAcceptInputType_discrete : BooleanInput ;
243
+ static ngAcceptInputType_showTickMarks : BooleanInput ;
244
+ static ngAcceptInputType_min : NumberInput ;
245
+ static ngAcceptInputType_max : NumberInput ;
246
+ static ngAcceptInputType_step : NumberInput ;
34
247
}
0 commit comments