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