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