mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 18:17:31 +08:00
fix(angular): item styling when control has value (#24932)
Resolves #23809
This commit is contained in:
@ -110,13 +110,17 @@ export class ValueAccessor implements ControlValueAccessor, AfterViewInit, OnDes
|
|||||||
|
|
||||||
export const setIonicClasses = (element: ElementRef): void => {
|
export const setIonicClasses = (element: ElementRef): void => {
|
||||||
raf(() => {
|
raf(() => {
|
||||||
const input = element.nativeElement as HTMLElement;
|
const input = element.nativeElement as HTMLInputElement;
|
||||||
|
const hasValue = input.value != null && input.value.toString().length > 0;
|
||||||
const classes = getClasses(input);
|
const classes = getClasses(input);
|
||||||
setClasses(input, classes);
|
setClasses(input, classes);
|
||||||
|
|
||||||
const item = input.closest('ion-item');
|
const item = input.closest('ion-item');
|
||||||
if (item) {
|
if (item) {
|
||||||
setClasses(item, classes);
|
if (hasValue) {
|
||||||
|
setClasses(item, [...classes, 'item-has-value']);
|
||||||
|
} else {
|
||||||
|
setClasses(item, classes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -127,7 +131,7 @@ const getClasses = (element: HTMLElement) => {
|
|||||||
for (let i = 0; i < classList.length; i++) {
|
for (let i = 0; i < classList.length; i++) {
|
||||||
const item = classList.item(i);
|
const item = classList.item(i);
|
||||||
if (item !== null && startsWith(item, 'ng-')) {
|
if (item !== null && startsWith(item, 'ng-')) {
|
||||||
classes.push(`ion-${item.substr(3)}`);
|
classes.push(`ion-${item.substring(3)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return classes;
|
return classes;
|
||||||
@ -135,13 +139,10 @@ const getClasses = (element: HTMLElement) => {
|
|||||||
|
|
||||||
const setClasses = (element: HTMLElement, classes: string[]) => {
|
const setClasses = (element: HTMLElement, classes: string[]) => {
|
||||||
const classList = element.classList;
|
const classList = element.classList;
|
||||||
['ion-valid', 'ion-invalid', 'ion-touched', 'ion-untouched', 'ion-dirty', 'ion-pristine'].forEach((c) =>
|
classList.remove('ion-valid', 'ion-invalid', 'ion-touched', 'ion-untouched', 'ion-dirty', 'ion-pristine');
|
||||||
classList.remove(c)
|
classList.add(...classes);
|
||||||
);
|
|
||||||
|
|
||||||
classes.forEach((c) => classList.add(c));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const startsWith = (input: string, search: string): boolean => {
|
const startsWith = (input: string, search: string): boolean => {
|
||||||
return input.substr(0, search.length) === search;
|
return input.substring(0, search.length) === search;
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,6 @@ describe('Modals', () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('Modals: Inline', () => {
|
describe('Modals: Inline', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/modal-inline');
|
cy.visit('/modal-inline');
|
||||||
@ -77,3 +76,29 @@ describe('Modals: Inline', () => {
|
|||||||
cy.get('ion-modal').children('.ion-page').should('not.exist');
|
cy.get('ion-modal').children('.ion-page').should('not.exist');
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when in a modal', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('/modals');
|
||||||
|
cy.get('#action-button').click();
|
||||||
|
cy.get('#close-modal').click();
|
||||||
|
cy.get('#action-button').click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render ion-item item-has-value class when control value is set', () => {
|
||||||
|
cy.get('[formControlName="select"]').invoke('attr', 'value', 0);
|
||||||
|
cy.get('#inputWithFloatingLabel').should('have.class', 'item-has-value');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render ion-item item-has-value class when control value is undefined', () => {
|
||||||
|
cy.get('[formControlName="select"]').invoke('attr', 'value', undefined);
|
||||||
|
cy.get('#inputWithFloatingLabel').should('not.have.class', 'item-has-value');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render ion-item item-has-value class when control value is null', () => {
|
||||||
|
cy.get('[formControlName="select"]').invoke('attr', 'value', null);
|
||||||
|
cy.get('#inputWithFloatingLabel').should('not.have.class', 'item-has-value');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
@ -22,4 +22,14 @@
|
|||||||
<ion-button (click)="push()" class="push-page">Push page</ion-button>
|
<ion-button (click)="push()" class="push-page">Push page</ion-button>
|
||||||
<ion-button (click)="pop()" class="pop-page">Pop page</ion-button>
|
<ion-button (click)="pop()" class="pop-page">Pop page</ion-button>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<form [formGroup]="form">
|
||||||
|
<ion-item id="inputWithFloatingLabel">
|
||||||
|
<ion-label color="primary" position="floating">Floating Label</ion-label>
|
||||||
|
<ion-select multiple="false" formControlName="select">
|
||||||
|
<ion-select-option [value]="0">Option 0</ion-select-option>
|
||||||
|
<ion-select-option [value]="1">Option 1</ion-select-option>
|
||||||
|
</ion-select>
|
||||||
|
</ion-item>
|
||||||
|
</form>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Component, Input, NgZone, OnInit, Optional } from '@angular/core';
|
import { Component, Input, NgZone, OnInit, Optional } from '@angular/core';
|
||||||
|
import { FormControl, FormGroup } from '@angular/forms';
|
||||||
import { ModalController, NavParams, IonNav, ViewWillLeave, ViewDidEnter, ViewDidLeave } from '@ionic/angular';
|
import { ModalController, NavParams, IonNav, ViewWillLeave, ViewDidEnter, ViewDidLeave } from '@ionic/angular';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -9,6 +10,10 @@ export class ModalExampleComponent implements OnInit, ViewWillLeave, ViewDidEnte
|
|||||||
|
|
||||||
@Input() value: string;
|
@Input() value: string;
|
||||||
|
|
||||||
|
form = new FormGroup({
|
||||||
|
select: new FormControl([])
|
||||||
|
});
|
||||||
|
|
||||||
valueFromParams: string;
|
valueFromParams: string;
|
||||||
onInit = 0;
|
onInit = 0;
|
||||||
willEnter = 0;
|
willEnter = 0;
|
||||||
|
Reference in New Issue
Block a user