Skip to content

Commit

Permalink
feat(kit): InputRange refactor (use InputNumber inside) (#1583)
Browse files Browse the repository at this point in the history
* feat(kit): `InputRange` refactor (use `InputNumber` inside)

* chore(kit): `InputRange` refactor TS-file

* chore(demo-integrations): `InputRange` more cypress tests

* chore(demo): `InputRange` more examples

* fix(kit): `InputRange` bug with click on the thumb without value changes

* fix(core): `none`-appearance move to separate file

* fix(kit): `InputRange` case with very long placeholder
  • Loading branch information
nsbarsukov authored Apr 11, 2022
1 parent 9b55ce3 commit fc0f27a
Show file tree
Hide file tree
Showing 27 changed files with 1,113 additions and 616 deletions.
1 change: 1 addition & 0 deletions projects/core/styles/mixins/slider.less
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
margin-left: calc(var(--tui-radius-m) / 2 + @first-tick-center);
}

tui-input-range + &,
tui-range + & {
@thumb: @thumb-diameters[ @@input-size];
margin-left: @thumb;
Expand Down
1 change: 1 addition & 0 deletions projects/core/styles/theme/wrapper.less
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
@import 'wrapper/table.less';
@import 'wrapper/textfield.less';
@import 'wrapper/whiteblock.less';
@import 'wrapper/none.less';

@import 'wrapper/base.less';
6 changes: 6 additions & 0 deletions projects/core/styles/theme/wrapper/none.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
tui-wrapper[data-appearance='none'],
[tuiWrapper][data-appearance='none'] {
&:after {
border: none;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const EDITOR_PAGE_URL = 'components/editor-new';
export const MULTI_SELECT_PAGE_URL = 'components/multi-select';
export const SELECT_PAGE_URL = 'components/select';
export const SLIDER_PAGE_URL = 'components/slider';
export const INPUT_RANGE_PAGE_URL = 'components/input-range';
export const INPUT_SLIDER_PAGE_URL = 'components/input-slider';
export const INPUT_PAGE_URL = 'components/input';
export const RANGE_PAGE_URL = 'components/range';
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
import {INPUT_RANGE_PAGE_URL} from '../../../support/shared.entities';

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

describe('Keyboard interactions', () => {
beforeEach(() => {
cy.tuiVisit(`${INPUT_RANGE_PAGE_URL}/API?min=-100&max=100&quantum=5`);
initializeAliases('#demoContent tui-input-range', [0, 10]);
});

it('pressing Arrow Down decreases LEFT value when LEFT text input is focused', () => {
cy.get('@leftTextInput').focus();

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

cy.get('@leftSlider').should('have.value', -5);
cy.get('@leftTextInput').should('have.value', -5);

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

cy.get('@leftSlider').should('have.value', -10);
cy.get('@leftTextInput').should('have.value', -10);
});

it('pressing Arrow Down decreases RIGHT value when RIGHT text input is focused', () => {
cy.get('@rightTextInput').focus();

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

cy.get('@rightSlider').should('have.value', 5);
cy.get('@rightTextInput').should('have.value', 5);

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

cy.get('@rightSlider').should('have.value', 0);
cy.get('@rightTextInput').should('have.value', 0);
});

it('pressing Arrow Up increases LEFT value when LEFT text input is focused', () => {
cy.get('@leftTextInput').focus();

cy.get('body').type('{uparrow}');

cy.get('@leftSlider').should('have.value', 5);
cy.get('@leftTextInput').should('have.value', 5);

cy.get('body').type('{uparrow}');

cy.get('@leftSlider').should('have.value', 10);
cy.get('@leftTextInput').should('have.value', 10);
});

it('pressing Arrow Up increases RIGHT value when RIGHT text input is focused', () => {
cy.get('@rightTextInput').focus();

cy.get('body').type('{uparrow}');

cy.get('@rightSlider').should('have.value', 15);
cy.get('@rightTextInput').should('have.value', 15);

cy.get('body').type('{uparrow}');

cy.get('@rightSlider').should('have.value', 20);
cy.get('@rightTextInput').should('have.value', 20);
});

it('cannot set right value less than left value via ArrowDown', () => {
cy.get('@rightTextInput').focus();

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

cy.get('@leftSlider').should('have.value', 0);
cy.get('@leftTextInput').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 0);
cy.get('@rightTextInput').should('have.value', 0);
});

it('cannot set left value more than right value via ArrowUp', () => {
cy.get('@leftTextInput').focus();

cy.get('body').type('{uparrow}{uparrow}');
cy.get('body').type('{uparrow}{uparrow}');
cy.get('body').type('{uparrow}{uparrow}');

cy.get('@leftSlider').should('have.value', 10);
cy.get('@leftTextInput').should('have.value', 10);
cy.get('@rightSlider').should('have.value', 10);
cy.get('@rightTextInput').should('have.value', 10);
});

it('pressing ArrowRight does not change any value (this key is for caret navigation only)', () => {
cy.get('@leftTextInput').focus();
cy.get('body').type('{rightarrow}{rightarrow}');

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

cy.get('@leftSlider').should('have.value', 0);
cy.get('@leftTextInput').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 10);
cy.get('@rightTextInput').should('have.value', 10);
});

it('pressing ArrowLeft does not change any value (this key is for caret navigation only)', () => {
cy.get('@leftTextInput').focus();
cy.get('body').type('{leftarrow}{leftarrow}');

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

cy.get('@leftSlider').should('have.value', 0);
cy.get('@leftTextInput').should('have.value', 0);
cy.get('@rightSlider').should('have.value', 10);
cy.get('@rightTextInput').should('have.value', 10);
});
});

describe('Rounding numbers (to the nearest step which satisfies quantum) (min=0 | max=10 | quantum=2.5)', () => {
beforeEach(() => {
cy.tuiVisit(`${INPUT_RANGE_PAGE_URL}/API?min=0&max=10&quantum=2.5`);
initializeAliases('#demoContent tui-input-range', [0, 10]);
});

const testsConditions = [
{typedValue: '9', expectedRoundedValue: '10'},
{typedValue: '8', expectedRoundedValue: '7,5'},
{typedValue: '7,6', expectedRoundedValue: '7,5'},
{typedValue: '7.4', expectedRoundedValue: '7,5'},
{typedValue: '7', expectedRoundedValue: '7,5'},
{typedValue: '6', expectedRoundedValue: '5'},
{typedValue: '3.2', expectedRoundedValue: '2,5'},
{typedValue: '1', expectedRoundedValue: '0'},
{typedValue: '0.1', expectedRoundedValue: '0'},
] as const;

for (const {typedValue, expectedRoundedValue} of testsConditions) {
it(`${typedValue} => ${expectedRoundedValue}`, () => {
cy.get('@rightTextInput')
.focus()
.clear()
.type(typedValue)
.blur()
.should('have.value', expectedRoundedValue);
});
}
});

describe('Range interactions', () => {
describe("click on the sliders' track", () => {
beforeEach(() => {
cy.tuiVisit(`${INPUT_RANGE_PAGE_URL}/API?min=-100&max=100&quantum=10`);
initializeAliases('#demoContent tui-input-range', [0, 10]);
});

it('clicking on the RIGHT side changes only the RIGHT value (+ focuses the RIGHT text input)', () => {
cy.get('@rightSlider')
.click('right', {force: true})
.should('have.value', 100);

cy.get('@leftSlider').should('have.value', 0);
cy.get('@leftTextInput').should('have.value', 0);

cy.get('@rightTextInput').should('have.value', 100).should('be.focused');
});

it('clicking on the LEFT side changes only the LEFT value (+ focuses the LEFT text input)', () => {
cy.get('@leftSlider')
.click('left', {force: true})
.should('have.value', -100);

cy.get('@rightSlider').should('have.value', 10);
cy.get('@rightTextInput').should('have.value', 10);

cy.get('@leftTextInput').should('have.value', -100).should('be.focused');
});
});

describe('click on a thumb', () => {
beforeEach(() => {
cy.tuiVisit(`${INPUT_RANGE_PAGE_URL}/API?min=0&max=10&quantum=1`);
initializeAliases('#demoContent tui-input-range', [0, 10]);
});

it('click on the LEFT thumb (with NO value changes) => focuses the LEFT text input', () => {
cy.get('@leftSlider')
.click('left', {force: true})
.should('have.value', 0);

cy.get('@leftTextInput').should('have.value', 0).should('be.focused');
});

it('click on the RIGHT thumb (with NO value changes) => focuses the RIGHT text input', () => {
cy.get('@rightSlider')
.click('right', {force: true})
.should('have.value', 10);

cy.get('@rightTextInput').should('have.value', 10).should('be.focused');
});
});
});

describe('Very long placeholder', () => {
it('basic case', () => {
cy.viewport('macbook-11');
cy.tuiVisit(`${INPUT_RANGE_PAGE_URL}/API`);

cy.get('#demoContent')
.should('be.visible')
.matchImageSnapshot('01-long-placeholder_basic');
});

it('with `leftValueContent` and `rightValueContent`', () => {
cy.viewport('iphone-x');
cy.tuiVisit(
`${INPUT_RANGE_PAGE_URL}/API?rightValueContent=TOP%20SECRET&leftValueContent=I%20am%20a%20leftValueContent`,
);

cy.get('#demoContent')
.should('be.visible')
.matchImageSnapshot('02-long-placeholder_value-content');
});

it('with `pluralize`', () => {
cy.viewport('iphone-8');
cy.tuiVisit(`${INPUT_RANGE_PAGE_URL}/API?pluralize$=1`);

cy.get('#demoContent')
.should('be.visible')
.matchImageSnapshot('03-long-placeholder_pluralize');
});
});
});

function initializeAliases(
inputRangeSelector: string,
[expectedLeftValue, expectedRightValue]: [number, number],
) {
cy.get(`${inputRangeSelector} [automation-id=tui-input-range__left-input] input`)
.should('exist')
.should('have.value', expectedLeftValue)
.as('leftTextInput');

cy.get(`${inputRangeSelector} [automation-id=tui-input-range__right-input] input`)
.should('exist')
.should('have.value', expectedRightValue)
.as('rightTextInput');

cy.get(`${inputRangeSelector} tui-range [tuiSlider]:first-of-type`)
.should('exist')
.should('have.value', expectedLeftValue)
.as('leftSlider');

cy.get(`${inputRangeSelector} tui-range [tuiSlider]:last-of-type`)
.should('exist')
.should('have.value', expectedRightValue)
.as('rightSlider');
}
11 changes: 10 additions & 1 deletion projects/demo/src/modules/app/app.providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import {
TUI_DOC_TITLE,
TuiDocSourceCodePathOptions,
} from '@taiga-ui/addon-doc';
import {isInsideIframe, TUI_DIALOG_CLOSES_ON_BACK, TUI_IS_CYPRESS} from '@taiga-ui/cdk';
import {
isInsideIframe,
TUI_DIALOG_CLOSES_ON_BACK,
TUI_IS_CYPRESS,
TUI_TAKE_ONLY_TRUSTED_EVENTS,
} from '@taiga-ui/cdk';
import {TUI_ANIMATIONS_DURATION, TUI_SANITIZER} from '@taiga-ui/core';
import {NgDompurifySanitizer} from '@tinkoff/ng-dompurify';
import {HIGHLIGHT_OPTIONS} from 'ngx-highlightjs';
Expand Down Expand Up @@ -109,6 +114,10 @@ export const APP_PROVIDERS = [
provide: TUI_ANIMATIONS_DURATION,
useFactory: () => (inject(TUI_IS_CYPRESS) ? 0 : 300),
},
{
provide: TUI_TAKE_ONLY_TRUSTED_EVENTS,
useFactory: () => !inject(TUI_IS_CYPRESS),
},
{
provide: TUI_DIALOG_CLOSES_ON_BACK,
useFactory: () => of(!isInsideIframe(inject(WINDOW))), // for cypress tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@

.control {
flex: 1;
min-width: 0;
margin-right: 1.5rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<tui-input-range
[min]="0"
[max]="10"
[leftValueContent]="valueContent"
[rightValueContent]="valueContent"
[pluralize]="pluralize"
[formControl]="control"
>
Desired departure day
</tui-input-range>

<ng-template
#valueContent
let-value
>
<ng-container [ngSwitch]="value">
<span *ngSwitchCase="0">Today</span>
<span *ngSwitchCase="1">Tomorrow</span>
<span *ngSwitchCase="7">In a week</span>
<span *ngSwitchDefault>
{{value}}&nbsp;{{value | i18nPlural: pluralize}}
</span>
</ng-container>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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-input-range-example-3',
templateUrl: './index.html',
styles: ['tui-input-range {max-width: 30rem}'],
changeDetection,
encapsulation,
})
export class TuiInputRangeExample3 {
readonly control = new FormControl([0, 7]);

// See https://angular.io/api/common/I18nPluralPipe
readonly pluralize = {
'=0': 'days later',
'=1': 'day later',
other: 'days later',
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<div class="wrapper">
<tui-input-range
new
[min]="0"
[max]="100"
[segments]="5"
[steps]="5"
[pluralize]="pluralize"
[formControl]="control"
>
Select volume range
</tui-input-range>

<div class="ticks-labels">
<span>
<tui-svg src="tuiIconSoundOff"></tui-svg>
</span>
<span>20%</span>
<span>40%</span>
<span>60%</span>
<span>80%</span>
<span>
<tui-svg src="tuiIconSound"></tui-svg>
</span>
</div>
</div>
Loading

0 comments on commit fc0f27a

Please sign in to comment.