Skip to content

Commit

Permalink
fix(input): stepper inputs for min & max (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
roll314 authored and pimenovoleg committed Oct 26, 2018
1 parent 75b1d7e commit 11e4d54
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/lib-dev/input/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { McInputModule } from '../../lib/input/';
export class InputDemoComponent {
value: string = '';
numberValue: number | null = null;
min = -5;
}


Expand Down
2 changes: 1 addition & 1 deletion src/lib-dev/input/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<header>Min = -5 Max = 7 Step = 0.5 Big step = 1.5 </header>
<mc-form-field>
<input mcInput [(ngModel)]="numberValue" type="number" placeholder="Number MaxMin Step"
min="-5" max="7" step="0.5" big-step="1.5">
[min]="min" max="7" step="0.5" big-step="1.5">
<mc-stepper></mc-stepper>
</mc-form-field>

Expand Down
112 changes: 112 additions & 0 deletions src/lib/input/input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,22 @@ class McNumberInput {
class McNumberInputMaxMinStep {
value: number | null = null;
}

@Component({
template: `
<mc-form-field>
<input mcInput [(ngModel)]="value" type="number" [max]="max" [min]="min" [step]="step" [bigStep]="bigStep">
<mc-stepper></mc-stepper>
</mc-form-field>
`
})
class McNumberInputMaxMinStepInput {
value: number | null = null;
max: number = 10;
min: number = 3;
step: number = 0.5;
bigStep: number = 2;
}
// tslint:enable no-unnecessary-class

// tslint:disable no-magic-numbers
Expand Down Expand Up @@ -477,6 +493,102 @@ describe('McNumberInput', () => {

expect(fixture.componentInstance.value).toBe(9.5);
}));

it('should be able to set min', fakeAsync(() => {
const fixture = createComponent(McNumberInputMaxMinStepInput);
fixture.detectChanges();

fixture.componentInstance.min = 1;

fixture.detectChanges();

const inputElementDebug = fixture.debugElement.query(By.directive(McInput));
const inputElement = inputElementDebug.nativeElement;

dispatchFakeEvent(inputElement, 'focus');
fixture.detectChanges();

const mcStepper = fixture.debugElement.query(By.css('mc-stepper'));
const icons = mcStepper.queryAll(By.css('.mc-icon'));
const iconUp = icons[0];

dispatchFakeEvent(iconUp.nativeElement, 'mousedown');

fixture.detectChanges();

expect(fixture.componentInstance.value).toBe(1.5);
}));

it('should be able to set max', fakeAsync(() => {
const fixture = createComponent(McNumberInputMaxMinStepInput);
fixture.detectChanges();

fixture.componentInstance.max = 5;

fixture.detectChanges();

const inputElementDebug = fixture.debugElement.query(By.directive(McInput));
const inputElement = inputElementDebug.nativeElement;

dispatchFakeEvent(inputElement, 'focus');
fixture.detectChanges();

const mcStepper = fixture.debugElement.query(By.css('mc-stepper'));
const icons = mcStepper.queryAll(By.css('.mc-icon'));
const iconDown = icons[1];

dispatchFakeEvent(iconDown.nativeElement, 'mousedown');

fixture.detectChanges();

expect(fixture.componentInstance.value).toBe(4.5);
}));

it('should be able to set step', fakeAsync(() => {
const fixture = createComponent(McNumberInputMaxMinStepInput);
fixture.detectChanges();

fixture.componentInstance.step = 2;

fixture.detectChanges();

const inputElementDebug = fixture.debugElement.query(By.directive(McInput));
const inputElement = inputElementDebug.nativeElement;

dispatchFakeEvent(inputElement, 'focus');
fixture.detectChanges();

const mcStepper = fixture.debugElement.query(By.css('mc-stepper'));
const icons = mcStepper.queryAll(By.css('.mc-icon'));
const iconDown = icons[1];

dispatchFakeEvent(iconDown.nativeElement, 'mousedown');

fixture.detectChanges();

expect(fixture.componentInstance.value).toBe(8);
}));

it('should be able to set big-step', fakeAsync(() => {
const fixture = createComponent(McNumberInputMaxMinStepInput);
fixture.detectChanges();

fixture.componentInstance.bigStep = 3;

fixture.detectChanges();

const inputElementDebug = fixture.debugElement.query(By.directive(McInput));
const inputElement = inputElementDebug.nativeElement;

inputElement.value = 5;
dispatchFakeEvent(inputElement, 'input');

dispatchKeyboardEvent(inputElementDebug.nativeElement, 'keydown', UP_ARROW, undefined, true);

fixture.detectChanges();

expect(fixture.componentInstance.value).toBe(8);
}));
});

describe('not empty value', () => {
Expand Down
44 changes: 22 additions & 22 deletions src/lib/input/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,46 +70,46 @@ export const _McInputMixinBase: CanUpdateErrorStateCtor & typeof McInputBase =
}
})
export class McNumberInput implements McFormFieldNumberControl<any> {

/**
* Implemented as part of McFormFieldNumberControl.
* @docs-private
*/
value: any;
@Input()
bigStep: number;

/**
* Implemented as part of McFormFieldNumberControl.
* @docs-private
*/
focused: boolean = false;
@Input()
step: number;

@Input()
min: number;

@Input()
max: number;

/**
* Implemented as part of McFormFieldNumberControl.
* @docs-private
*/
readonly stateChanges: Subject<void> = new Subject<void>();

private readonly _host: HTMLInputElement;
value: any;

/**
* Implemented as part of McFormFieldNumberControl.
* @docs-private
*/
private readonly _step: number;
get step() {
return this._step;
}
focused: boolean = false;

/**
* Implemented as part of McFormFieldNumberControl.
* @docs-private
*/
private readonly _bigStep: number;
get bigStep() {
return this._bigStep;
}
readonly stateChanges: Subject<void> = new Subject<void>();

private readonly _min: number;
private readonly _max: number;
private readonly _host: HTMLInputElement;

constructor(
private _platform: Platform ,
Expand All @@ -120,10 +120,10 @@ export class McNumberInput implements McFormFieldNumberControl<any> {
@Attribute('min') min: string,
@Attribute('max') max: string
) {
this._step = this.isDigit(step) ? parseFloat(step) : SMALL_STEP;
this._bigStep = this.isDigit(bigStep) ? parseFloat(bigStep) : BIG_STEP;
this._min = this.isDigit(min) ? parseFloat(min) : -Infinity;
this._max = this.isDigit(max) ? parseFloat(max) : Infinity;
this.step = this.isDigit(step) ? parseFloat(step) : SMALL_STEP;
this.bigStep = this.isDigit(bigStep) ? parseFloat(bigStep) : BIG_STEP;
this.min = this.isDigit(min) ? parseFloat(min) : -Infinity;
this.max = this.isDigit(max) ? parseFloat(max) : Infinity;

this._host = this._elementRef.nativeElement;

Expand Down Expand Up @@ -191,7 +191,7 @@ export class McNumberInput implements McFormFieldNumberControl<any> {
event.preventDefault();

// process steps
const step = event.shiftKey ? this._bigStep : this._step;
const step = event.shiftKey ? this.bigStep : this.step;

if (keyCode === UP_ARROW) {
this.stepUp(step);
Expand All @@ -214,14 +214,14 @@ export class McNumberInput implements McFormFieldNumberControl<any> {

stepUp(step: number) {
this._elementRef.nativeElement.focus();
const res = stepUp(this._host.valueAsNumber, this._max, this._min, step);
const res = stepUp(this._host.valueAsNumber, this.max, this.min, step);
this._host.value = res === null ? '' : res.toString();
this._model.update.emit(this._host.valueAsNumber);
}

stepDown(step: number) {
this._elementRef.nativeElement.focus();
const res = stepDown(this._host.valueAsNumber, this._max, this._min, step);
const res = stepDown(this._host.valueAsNumber, this.max, this.min, step);
this._host.value = res === null ? '' : res.toString();
this._model.update.emit(this._host.valueAsNumber);
}
Expand Down

0 comments on commit 11e4d54

Please sign in to comment.