@@ -1544,6 +1544,77 @@ describe('MatSlider', () => {
15441544 expect ( endInput . value ) . toBe ( 80 ) ;
15451545 } ) ) ;
15461546 } ) ;
1547+
1548+ describe ( 'slider with tick marks' , ( ) => {
1549+ let fixture : ComponentFixture < SliderWithTickMarks > ;
1550+ let slider : MatSlider ;
1551+ let sliderEl : HTMLElement ;
1552+ let input : MatSliderThumb ;
1553+
1554+ function getTickMarkEls ( ) {
1555+ const activeClass = '.mdc-slider__tick-mark--active' ;
1556+ const inactiveClass = '.mdc-slider__tick-mark--inactive' ;
1557+ const active = sliderEl . querySelectorAll ( activeClass ) ;
1558+ const inactive = sliderEl . querySelectorAll ( inactiveClass ) ;
1559+ const ticks = sliderEl . querySelectorAll ( `${ activeClass } ,${ inactiveClass } ` ) ;
1560+ return { ticks, active, inactive} ;
1561+ }
1562+
1563+ beforeEach ( waitForAsync ( ( ) => {
1564+ fixture = createComponent ( SliderWithTickMarks ) ;
1565+ fixture . detectChanges ( ) ;
1566+ const sliderDebugElement = fixture . debugElement . query ( By . directive ( MatSlider ) ) ;
1567+ slider = sliderDebugElement . componentInstance ;
1568+ sliderEl = sliderDebugElement . nativeElement ;
1569+ input = slider . _getInput ( _MatThumb . END ) as MatSliderThumb ;
1570+ } ) ) ;
1571+
1572+ it ( 'should have tick marks' , ( ) => {
1573+ expect ( slider . _tickMarks . length ) . toBeTruthy ( ) ;
1574+ } ) ;
1575+
1576+ it ( 'should have the correct number of ticks' , ( ) => {
1577+ expect ( slider . _tickMarks . length ) . toBe ( 101 ) ;
1578+
1579+ slider . max = 10 ;
1580+ expect ( slider . _tickMarks . length ) . toBe ( 11 ) ;
1581+
1582+ slider . step = 2 ;
1583+ expect ( slider . _tickMarks . length ) . toBe ( 6 ) ;
1584+
1585+ slider . min = 8 ;
1586+ expect ( slider . _tickMarks . length ) . toBe ( 2 ) ;
1587+ } ) ;
1588+
1589+ it ( 'should position the tick marks correctly' , ( ) => {
1590+ const { ticks} = getTickMarkEls ( ) ;
1591+
1592+ // 2.94 because the slider is 300px, there is 3px padding
1593+ // on each side of the tick mark track, and there are 100
1594+ // spaces between the 101 ticks. So the math is:
1595+ // (300 - 6) / 100 = 2.94
1596+ const spacing = 2.94 ;
1597+ const delta = 0.0001 ; // Floating point imprecision
1598+
1599+ let x = 18 ; // Where the first tick happens to start at.
1600+
1601+ for ( let i = 0 ; i < ticks . length ; i ++ ) {
1602+ const tickX = ticks [ i ] . getBoundingClientRect ( ) . x ;
1603+ expect ( tickX ) . toBeGreaterThan ( x - delta ) ;
1604+ expect ( tickX ) . toBeLessThan ( x + delta ) ;
1605+ x = tickX + spacing ;
1606+ }
1607+ } ) ;
1608+
1609+ // TODO(wagnermaciel): Add this test once this is fixed.
1610+ // it('should render the correct number of active & inactive ticks', () => {});
1611+
1612+ // TODO(wagnermaciel): Add this test once this is fixed.
1613+ // it('should position the tick marks correctly with a misaligned step', () => {});
1614+
1615+ // TODO(wagnermaciel): Add this test once this is fixed.
1616+ // it('should position the tick marks correctly with a misaligned step (rtl)', () => {});
1617+ } ) ;
15471618} ) ;
15481619
15491620const SLIDER_STYLES = [ '.mat-mdc-slider { width: 300px; }' ] ;
@@ -1835,6 +1906,19 @@ class RangeSliderWithTwoWayBinding {
18351906 endValue = 100 ;
18361907}
18371908
1909+ @Component ( {
1910+ template : `
1911+ <mat-slider [showTickMarks]="true">
1912+ <input matSliderThumb>
1913+ </mat-slider>
1914+ ` ,
1915+ styles : SLIDER_STYLES ,
1916+ standalone : false ,
1917+ } )
1918+ class SliderWithTickMarks {
1919+ @ViewChild ( MatSlider ) slider : MatSlider ;
1920+ }
1921+
18381922/** Clicks on the MatSlider at the coordinates corresponding to the given value. */
18391923function setValueByClick (
18401924 slider : MatSlider ,
0 commit comments