Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kit): Range use Slider inside #1538

Merged
merged 8 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,4 +1,5 @@
<tui-range
[formControl]="control"
[max]="10"
[quantum]="1"
></tui-range>
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>
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;
nsbarsukov marked this conversation as resolved.
Show resolved Hide resolved
}

.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]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<tui-range
id="range-with-segments"
new
size="m"
class="range"
[min]="min"
[max]="max"
[quantum]="quantum"
[segments]="segments"
[(ngModel)]="value"
></tui-range>

<div class="ticks-labels">
<div *ngFor="let label of labels">
<ng-container *ngIf="label !== 750; else labelWithIcon">
{{label | i18nPlural: pluralMap}}
</ng-container>
</div>

<ng-template #labelWithIcon>
<tui-svg src="tuiIconArrowUp"></tui-svg>
<div>3/4</div>
</ng-template>
</div>

<p class="tui-space_top-12 tui-space_bottom-0">
Control value:
<output for="range-with-segments">
<code>{{value | json}}</code>
</output>
</p>
Loading