mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 01:03:03 +08:00
refactor(angular): apply range to numeric value accessor (#29029)
Issue number: Internal --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> The ticket describes renaming `TextValueAccessorDirective` since `ion-range` is not a text-based control, however I think this was an incorrect assumption made during the original implementation. `ion-range` is a numeric based value accessor (either as a single number or an object accepting a numeric start/end value). ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Migrates the usage of `ion-range` value accessor implementation to the `NumericValueAccessorDirective` - Adds tests for validating the value accessor is functioning as expected ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer for more information. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> --------- Co-authored-by: Liam DeBeasi <liamdebeasi@users.noreply.github.com>
This commit is contained in:
@ -3,7 +3,7 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|||||||
import { ValueAccessor } from '@ionic/angular/common';
|
import { ValueAccessor } from '@ionic/angular/common';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: 'ion-input[type=number]',
|
selector: 'ion-input[type=number],ion-range',
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
@ -13,18 +13,22 @@ import { ValueAccessor } from '@ionic/angular/common';
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class NumericValueAccessorDirective extends ValueAccessor {
|
export class NumericValueAccessorDirective extends ValueAccessor {
|
||||||
constructor(injector: Injector, el: ElementRef) {
|
constructor(injector: Injector, private el: ElementRef<HTMLInputElement | HTMLIonRangeElement>) {
|
||||||
super(injector, el);
|
super(injector, el);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('ionInput', ['$event.target'])
|
@HostListener('ionInput', ['$event.target'])
|
||||||
handleInputEvent(el: HTMLIonInputElement): void {
|
handleInputEvent(el: HTMLIonInputElement | HTMLIonRangeElement): void {
|
||||||
this.handleValueChange(el, el.value);
|
this.handleValueChange(el, el.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnChange(fn: (_: number | null) => void): void {
|
registerOnChange(fn: (_: number | null) => void): void {
|
||||||
super.registerOnChange((value: string) => {
|
if (this.el.nativeElement.tagName === 'ION-INPUT') {
|
||||||
fn(value === '' ? null : parseFloat(value));
|
super.registerOnChange((value: string) => {
|
||||||
});
|
fn(value === '' ? null : parseFloat(value));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
super.registerOnChange(fn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,8 @@ import { ElementRef, Injector, Directive, HostListener } from '@angular/core';
|
|||||||
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
import { ValueAccessor } from '@ionic/angular/common';
|
import { ValueAccessor } from '@ionic/angular/common';
|
||||||
|
|
||||||
// TODO(FW-5495): rename class since range isn't a text component
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: 'ion-input:not([type=number]),ion-textarea,ion-searchbar,ion-range',
|
selector: 'ion-input:not([type=number]),ion-textarea,ion-searchbar',
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
@ -19,9 +18,7 @@ export class TextValueAccessorDirective extends ValueAccessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('ionInput', ['$event.target'])
|
@HostListener('ionInput', ['$event.target'])
|
||||||
_handleInputEvent(
|
_handleInputEvent(el: HTMLIonInputElement | HTMLIonTextareaElement | HTMLIonSearchbarElement): void {
|
||||||
el: HTMLIonInputElement | HTMLIonTextareaElement | HTMLIonSearchbarElement | HTMLIonRangeElement
|
|
||||||
): void {
|
|
||||||
this.handleValueChange(el, el.value);
|
this.handleValueChange(el, el.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ describe('Inputs', () => {
|
|||||||
cy.get('ion-input').should('have.prop', 'value').and('equal', 'some text');
|
cy.get('ion-input').should('have.prop', 'value').and('equal', 'some text');
|
||||||
cy.get('ion-datetime').should('have.prop', 'value').and('equal', '1994-03-15');
|
cy.get('ion-datetime').should('have.prop', 'value').and('equal', '1994-03-15');
|
||||||
cy.get('ion-select').should('have.prop', 'value').and('equal', 'nes');
|
cy.get('ion-select').should('have.prop', 'value').and('equal', 'nes');
|
||||||
|
cy.get('ion-range').should('have.prop', 'value').and('equal', 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have reset value', () => {
|
it('should have reset value', () => {
|
||||||
@ -27,6 +28,7 @@ describe('Inputs', () => {
|
|||||||
cy.get('ion-input').should('not.have.prop', 'value');
|
cy.get('ion-input').should('not.have.prop', 'value');
|
||||||
cy.get('ion-datetime').should('not.have.prop', 'value');
|
cy.get('ion-datetime').should('not.have.prop', 'value');
|
||||||
cy.get('ion-select').should('not.have.prop', 'value');
|
cy.get('ion-select').should('not.have.prop', 'value');
|
||||||
|
cy.get('ion-range').should('not.have.prop', 'value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get some value', () => {
|
it('should get some value', () => {
|
||||||
@ -39,6 +41,7 @@ describe('Inputs', () => {
|
|||||||
cy.get('ion-input').should('have.prop', 'value').and('equal', 'some text');
|
cy.get('ion-input').should('have.prop', 'value').and('equal', 'some text');
|
||||||
cy.get('ion-datetime').should('have.prop', 'value').and('equal', '1994-03-15');
|
cy.get('ion-datetime').should('have.prop', 'value').and('equal', '1994-03-15');
|
||||||
cy.get('ion-select').should('have.prop', 'value').and('equal', 'nes');
|
cy.get('ion-select').should('have.prop', 'value').and('equal', 'nes');
|
||||||
|
cy.get('ion-range').should('have.prop', 'value').and('equal', 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('change values should update angular', () => {
|
it('change values should update angular', () => {
|
||||||
|
@ -99,6 +99,12 @@
|
|||||||
<ion-note slot="end">{{radio}}</ion-note>
|
<ion-note slot="end">{{radio}}</ion-note>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-range [(ngModel)]="range" min="0" max="100" id="first-range">
|
||||||
|
<ion-label slot="start">Range</ion-label>
|
||||||
|
</ion-range>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
</ion-list>
|
</ion-list>
|
||||||
<p>
|
<p>
|
||||||
<ion-button (click)="setValues()" id="set-button">Set values</ion-button>
|
<ion-button (click)="setValues()" id="set-button">Set values</ion-button>
|
||||||
|
@ -13,6 +13,7 @@ export class InputsComponent {
|
|||||||
toggle = true;
|
toggle = true;
|
||||||
select? = 'nes';
|
select? = 'nes';
|
||||||
changes = 0;
|
changes = 0;
|
||||||
|
range? = 50;
|
||||||
|
|
||||||
setValues() {
|
setValues() {
|
||||||
console.log('set values');
|
console.log('set values');
|
||||||
@ -22,6 +23,7 @@ export class InputsComponent {
|
|||||||
this.radio = 'nes';
|
this.radio = 'nes';
|
||||||
this.toggle = true;
|
this.toggle = true;
|
||||||
this.select = 'nes';
|
this.select = 'nes';
|
||||||
|
this.range = 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetValues() {
|
resetValues() {
|
||||||
@ -32,6 +34,7 @@ export class InputsComponent {
|
|||||||
this.radio = undefined;
|
this.radio = undefined;
|
||||||
this.toggle = false;
|
this.toggle = false;
|
||||||
this.select = undefined;
|
this.select = undefined;
|
||||||
|
this.range = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
counter() {
|
counter() {
|
||||||
|
Reference in New Issue
Block a user