Skip to content

Commit

Permalink
refactor(kit): Range use Slider inside
Browse files Browse the repository at this point in the history
  • Loading branch information
nsbarsukov committed Mar 29, 2022
1 parent 68d1132 commit 13cfc63
Show file tree
Hide file tree
Showing 35 changed files with 1,167 additions and 186 deletions.
16 changes: 16 additions & 0 deletions projects/core/styles/mixins/slider.less
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,20 @@
tui-input-slider + & {
margin-left: calc(var(--tui-radius-m) / 2 + @first-tick-center);
}

tui-range + & {
@thumb: @thumb-diameters[ @@input-size];
margin-left: @thumb;
margin-right: @thumb;

& > * {
&:first-child {
left: -@thumb;
}

&:last-child {
right: -@thumb;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export const SELECT_PAGE_URL = 'components/select';
export const SLIDER_PAGE_URL = 'components/slider';
export const INPUT_SLIDER_PAGE_URL = 'components/input-slider';
export const INPUT_PAGE_URL = 'components/input';
export const RANGE_PAGE_URL = 'components/range';
239 changes: 239 additions & 0 deletions projects/demo-integrations/cypress/tests/kit/range/range.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
import {RANGE_PAGE_URL} from '../../../support/shared.entities';

const initializeBaseAliases = (exampleId: string) => {
cy.get(`${exampleId} tui-range`).should('be.visible').as('range');
cy.get(`${exampleId} tui-range input[type=range]:first-child`)
.should('be.visible')
.as('leftSlider');
cy.get(`${exampleId} tui-range input[type=range]:last-child`)
.should('be.visible')
.as('rightSlider');
};

describe('Range', () => {
beforeEach(() => {
cy.viewport('macbook-13');
});

describe('examples page', () => {
beforeEach(() => {
cy.goToDemoPage(RANGE_PAGE_URL);
cy.hideHeader();
cy.hideNavigation();
});

describe('change selected range on click', () => {
const EXAMPLE_ID = '#base';

beforeEach(() => {
initializeBaseAliases(EXAMPLE_ID);

cy.get(EXAMPLE_ID).scrollIntoView();
});

it('click on the beginning of the track changes only nearest (left) slider', () => {
cy.get('@range').click('left');
cy.get('@leftSlider').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 6);

cy.get(EXAMPLE_ID).matchImageSnapshot('01-range-click-checks-0-6');
});

it('click on the end of the track changes only nearest (right) slider', () => {
cy.get('@range').click('right');
cy.get('@leftSlider').should('have.value', 4);
cy.get('@rightSlider').should('have.value', 10);

cy.get(EXAMPLE_ID).matchImageSnapshot('02-range-click-checks-4-10');
});

it('click between two thumbs triggers only nearest thumb', () => {
cy.get('@range').click(100, 0);
cy.get('@range').click('right');

cy.get('@leftSlider').should('have.value', 1);
cy.get('@rightSlider').should('have.value', 10);
cy.get(EXAMPLE_ID).matchImageSnapshot('03-range-click-checks-1-10');

cy.get('@range').click('center');
cy.get('@leftSlider').should('have.value', 5);
cy.get('@rightSlider').should('have.value', 10);
cy.get(EXAMPLE_ID).matchImageSnapshot('03-range-click-checks-5-10');
});
});

describe('keyboard interactions', () => {
describe('basic range (from 0 to 1000 with 250 steps). Initial value [0, 250]', () => {
const EXAMPLE_ID = '#segments';

beforeEach(() => {
initializeBaseAliases(EXAMPLE_ID);

cy.get(EXAMPLE_ID).scrollIntoView();
});

const checkValuesAfterPressing = (
key: string,
[leftSliderValue, rightSliderValue]: [number, number],
) => {
cy.get('body').type(`{${key}}`);
cy.get('@leftSlider').should('have.value', leftSliderValue);
cy.get('@rightSlider').should('have.value', rightSliderValue);
cy.get(`${EXAMPLE_ID} output`)
.invoke('text')
.should(
'match',
new RegExp(
`\\s${leftSliderValue},.+${rightSliderValue}\\s`,
'gs',
),
);
};

it('pressing of Arrow Right increases by one step (after focus on right slider)', () => {
cy.get('@leftSlider').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 250);
cy.get('@rightSlider').focus();

checkValuesAfterPressing('rightarrow', [0, 500]);
checkValuesAfterPressing('rightarrow', [0, 750]);
checkValuesAfterPressing('rightarrow', [0, 1000]);
});

it('pressing of Arrow Right increases by one step (after focus on left slider)', () => {
cy.get('@range').click('right');
cy.get('@leftSlider').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 1000);
cy.get('@leftSlider').focus();

checkValuesAfterPressing('rightarrow', [250, 1000]);
checkValuesAfterPressing('rightarrow', [500, 1000]);
checkValuesAfterPressing('rightarrow', [750, 1000]);
checkValuesAfterPressing('rightarrow', [1000, 1000]);
});

it('pressing of Arrow Left decreases by one step (after setting right thumb active via click)', () => {
cy.get('@range').click('right');
cy.get('@leftSlider').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 1000);

checkValuesAfterPressing('leftarrow', [0, 750]);
checkValuesAfterPressing('leftarrow', [0, 500]);
checkValuesAfterPressing('leftarrow', [0, 250]);
checkValuesAfterPressing('leftarrow', [0, 0]);
});

it('cannot set left thumb more than right thumb (by Arrow Right)', () => {
cy.get('@leftSlider').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 250);
cy.get('@leftSlider').focus();

checkValuesAfterPressing('rightarrow', [250, 250]);
checkValuesAfterPressing('rightarrow', [250, 250]);
checkValuesAfterPressing('rightarrow', [250, 250]);
});

it('cannot set right thumb less than left thumb (by ArrowLeft)', () => {
cy.get('@range').click('right');
cy.get('@leftSlider').focus();

cy.get('body').type('{rightarrow}{rightarrow}');
cy.get('@leftSlider').should('have.value', 500);
cy.get('@rightSlider').should('have.value', 1000);

cy.get('@rightSlider').focus();
cy.get('body').type(
'{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}',
);

cy.get('@leftSlider').should('have.value', 500);
cy.get('@rightSlider').should('have.value', 500);

cy.get('@rightSlider').focus();
cy.get('body').type(
'{leftarrow}{leftarrow}{leftarrow}{leftarrow}{leftarrow}',
);

cy.get('@leftSlider').focus();
cy.get('body').type(
'{rightarrow}{rightarrow}{rightarrow}{rightarrow}{rightarrow}',
);

cy.get('@leftSlider').should('have.value', 500);
cy.get('@rightSlider').should('have.value', 500);
});
});

describe('range with keySteps (from 0 to 1M) with 8 steps. Initial value [0, 100_000]', () => {
const EXAMPLE_ID = '#key-steps';

beforeEach(() => {
initializeBaseAliases(EXAMPLE_ID);

cy.get(EXAMPLE_ID).scrollIntoView();
});

const checkValuesAfterPressing = (
key: string,
[leftSliderValue, rightSliderValue]: [number, number],
) => {
cy.get('body').type(`{${key}}`);
cy.get(`${EXAMPLE_ID} output`)
.invoke('text')
.should(
'match',
new RegExp(
`\\s${leftSliderValue},.+${rightSliderValue}\\s`,
'gs',
),
);
};

it('ArrowUp increases value of the focused slider', () => {
cy.get('@rightSlider').focus();

checkValuesAfterPressing('uparrow', [0, 300_000]);
checkValuesAfterPressing('uparrow', [0, 500_000]);
checkValuesAfterPressing('uparrow', [0, 750_000]);
checkValuesAfterPressing('uparrow', [0, 1_000_000]);

cy.get('@leftSlider').focus();

checkValuesAfterPressing('uparrow', [5_000, 1_000_000]);
checkValuesAfterPressing('uparrow', [10_000, 1_000_000]);
checkValuesAfterPressing('uparrow', [55_000, 1_000_000]);
checkValuesAfterPressing('uparrow', [100_000, 1_000_000]);
});

it('ArrowDown decreases value of the focused slider', () => {
cy.get('@rightSlider').focus();

checkValuesAfterPressing('downarrow', [0, 55_000]);
checkValuesAfterPressing('downarrow', [0, 10_000]);
checkValuesAfterPressing('downarrow', [0, 5_000]);
});

it('cannot set position of the LEFT slider MORE THAN position of the RIGHT slider (by ArrowUp)', () => {
cy.get('@leftSlider').focus();
cy.get('body').type('{uparrow}{uparrow}{uparrow}{uparrow}');

checkValuesAfterPressing('uparrow', [100_000, 100_000]);
checkValuesAfterPressing('uparrow', [100_000, 100_000]);
checkValuesAfterPressing('uparrow', [100_000, 100_000]);
});

it('cannot set position of the RIGHT slider LESS THAN position of the LEFT slider (by ArrowDown)', () => {
cy.get('@leftSlider').focus();
cy.get('body').type('{uparrow}');

cy.get('@rightSlider').focus();
cy.get('body').type('{downarrow}{downarrow}{downarrow}');

checkValuesAfterPressing('downarrow', [5_000, 5_000]);
checkValuesAfterPressing('downarrow', [5_000, 5_000]);
checkValuesAfterPressing('downarrow', [5_000, 5_000]);
});
});
});
});
});
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<tui-range [formControl]="control" [max]="10"></tui-range>
<tui-range [formControl]="control" [max]="10" [quantum]="1"></tui-range>
37 changes: 37 additions & 0 deletions projects/demo/src/modules/components/range/examples/2/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<tui-island class="island">
<h3 class="tui-island__title">S-size</h3>

<tui-range
id="s-size-range"
size="s"
class="range"
[max]="100"
[(ngModel)]="smallRangeValue"
></tui-range>

<p class="tui-island__paragraph">
Control value:
<output for="s-size-range">
<code>{{smallRangeValue | json}}</code>
</output>
</p>
</tui-island>

<tui-island class="island">
<h3 class="tui-island__title">M-size</h3>

<tui-range
id="m-size-range"
size="m"
class="range"
[formControl]="bigRangeControl"
[max]="100"
></tui-range>

<p class="tui-island__paragraph">
Control value:
<output for="m-size-range">
<code>{{bigRangeControl.value | json}}</code>
</output>
</p>
</tui-island>
21 changes: 21 additions & 0 deletions projects/demo/src/modules/components/range/examples/2/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@import 'taiga-ui-local';

:host {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
row-gap: 1rem;
}

.island {
box-sizing: border-box;
width: 49%;

@media @mobile {
width: 100%;
}
}

.range {
margin: 2rem 0;
}
17 changes: 17 additions & 0 deletions projects/demo/src/modules/components/range/examples/2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';
import {changeDetection} from '@demo/emulate/change-detection';
import {encapsulation} from '@demo/emulate/encapsulation';

@Component({
selector: 'tui-range-example-2',
templateUrl: './index.html',
styleUrls: ['./index.less'],
changeDetection,
encapsulation,
})
export class TuiRangeExample2 {
smallRangeValue = [0, 40];

readonly bigRangeControl = new FormControl([40, 60]);
}
21 changes: 21 additions & 0 deletions projects/demo/src/modules/components/range/examples/3/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<tui-range
id="range-with-segments"
new
size="m"
class="range"
[max]="1000"
[quantum]="250"
[segments]="4"
[(ngModel)]="value"
></tui-range>

<div class="ticks-labels">
<span *ngFor="let label of labels">${{label}}</span>
</div>

<p class="tui-space_top-12 tui-space_bottom-0">
Control value:
<output for="range-with-segments">
<code>{{value | json}}</code>
</output>
</p>
18 changes: 18 additions & 0 deletions projects/demo/src/modules/components/range/examples/3/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@import 'taiga-ui-local';

.range {
z-index: 1;

/* (Optionally) expand clickable area as you wish */
&:after {
content: '';
position: absolute;
top: -0.5rem;
bottom: -1.5rem;
width: 100%;
}
}

.ticks-labels {
.tui-slider-ticks-labels(m);
}
Loading

0 comments on commit 13cfc63

Please sign in to comment.