mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
fix(label): keep color when focused on a floating or stacked label (#18576)
fixes #18531
This commit is contained in:
4
core/src/components.d.ts
vendored
4
core/src/components.d.ts
vendored
@ -4442,6 +4442,10 @@ declare namespace LocalJSX {
|
||||
* The mode determines which platform styles to use.
|
||||
*/
|
||||
"mode"?: "ios" | "md";
|
||||
/**
|
||||
* Emitted when the color changes.
|
||||
*/
|
||||
"onIonColor"?: (event: CustomEvent<StyleEventDetail>) => void;
|
||||
/**
|
||||
* Emitted when the styles change.
|
||||
*/
|
||||
|
||||
@ -282,3 +282,14 @@
|
||||
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating) {
|
||||
color: $label-md-text-color-focused;
|
||||
}
|
||||
|
||||
// Material Design Inputs: Highlight Color
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.ion-color) {
|
||||
--highlight-color-focused: #{current-color(contrast)};
|
||||
}
|
||||
|
||||
:host(.item-label-color) {
|
||||
--highlight-color-focused: #{current-color(base)};
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
|
||||
})
|
||||
export class Item implements ComponentInterface, AnchorInterface, ButtonInterface {
|
||||
|
||||
private labelColorStyles = {};
|
||||
private itemStyles = new Map<string, CssClassMap>();
|
||||
|
||||
@Element() el!: HTMLIonItemElement;
|
||||
@ -111,6 +112,18 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
*/
|
||||
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
|
||||
|
||||
@Listen('ionColor')
|
||||
labelColorChanged(ev: CustomEvent<string>) {
|
||||
const { color } = this;
|
||||
|
||||
// There will be a conflict with item color if
|
||||
// we apply the label color to item, so we ignore
|
||||
// the label color if the user sets a color on item
|
||||
if (color === undefined) {
|
||||
this.labelColorStyles = ev.detail;
|
||||
}
|
||||
}
|
||||
|
||||
@Listen('ionStyle')
|
||||
itemStyle(ev: CustomEvent<StyleEventDetail>) {
|
||||
ev.stopPropagation();
|
||||
@ -212,7 +225,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
}
|
||||
|
||||
render() {
|
||||
const { detail, detailIcon, download, lines, disabled, href, rel, target, routerAnimation, routerDirection } = this;
|
||||
const { detail, detailIcon, download, labelColorStyles, lines, disabled, href, rel, target, routerAnimation, routerDirection } = this;
|
||||
const childStyles = {};
|
||||
const mode = getIonMode(this);
|
||||
const clickable = this.isClickable();
|
||||
@ -236,6 +249,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
aria-disabled={disabled ? 'true' : null}
|
||||
class={{
|
||||
...childStyles,
|
||||
...labelColorStyles,
|
||||
...createColorClasses(this.color, {
|
||||
'item': true,
|
||||
[mode]: true,
|
||||
|
||||
@ -44,11 +44,16 @@
|
||||
@include transform(translateY(50%), scale(.75));
|
||||
}
|
||||
|
||||
:host-context(.item-has-focus).label-stacked,
|
||||
:host-context(.item-has-focus).label-floating {
|
||||
:host-context(.item-has-focus).label-stacked:not(.ion-color),
|
||||
:host-context(.item-has-focus).label-floating:not(.ion-color) {
|
||||
color: $label-md-text-color-focused;
|
||||
}
|
||||
|
||||
:host-context(.item-has-focus.ion-color).label-stacked:not(.ion-color),
|
||||
:host-context(.item-has-focus.ion-color).label-floating:not(.ion-color) {
|
||||
color: #{current-color(contrast)};
|
||||
}
|
||||
|
||||
|
||||
// MD Typography
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -32,6 +32,12 @@ export class Label implements ComponentInterface {
|
||||
*/
|
||||
@Prop() position?: 'fixed' | 'stacked' | 'floating';
|
||||
|
||||
/**
|
||||
* Emitted when the color changes.
|
||||
* @internal
|
||||
*/
|
||||
@Event() ionColor!: EventEmitter<StyleEventDetail>;
|
||||
|
||||
/**
|
||||
* Emitted when the styles change.
|
||||
* @internal
|
||||
@ -44,6 +50,7 @@ export class Label implements ComponentInterface {
|
||||
this.inRange = !!this.el.closest('ion-range');
|
||||
this.noAnimate = (this.position === 'floating');
|
||||
this.emitStyle();
|
||||
this.emitColor();
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
@ -54,11 +61,25 @@ export class Label implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
@Watch('color')
|
||||
colorChanged() {
|
||||
this.emitColor();
|
||||
}
|
||||
|
||||
@Watch('position')
|
||||
positionChanged() {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
private emitColor() {
|
||||
const { color } = this;
|
||||
|
||||
this.ionColor.emit({
|
||||
'item-label-color': color !== undefined,
|
||||
[`ion-color-${color}`]: color !== undefined
|
||||
});
|
||||
}
|
||||
|
||||
private emitStyle() {
|
||||
const { inRange, position } = this;
|
||||
|
||||
|
||||
@ -17,6 +17,11 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Label - Basic</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button onClick="changeColors()">
|
||||
Color Change
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
@ -58,10 +63,37 @@
|
||||
<ion-label position="floating">Floating</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item class="floating-color">
|
||||
<ion-label position="floating" color="success">Floating: Success</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label position="stacked">Stacked</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item class="stacked-color">
|
||||
<ion-label position="stacked" color="danger">Stacked: Danger</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-item color="tertiary">
|
||||
<ion-label position="floating">(Item: Tertiary) Floating</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item color="primary">
|
||||
<ion-label position="stacked">(Item: Primary) Stacked</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item class="floating-color" color="tertiary">
|
||||
<ion-label position="floating" color="success">(Item: Tertiary) Floating: Success</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item class="stacked-color" color="primary">
|
||||
<ion-label position="stacked" color="danger">(Item: Primary) Stacked: Danger</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
|
||||
@ -70,6 +102,17 @@
|
||||
color: lightblue;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const labels = document.querySelectorAll('.floating-color ion-label, .stacked-color ion-label');
|
||||
|
||||
function changeColors() {
|
||||
for (label of labels) {
|
||||
const currentColor = label.color;
|
||||
label.color = currentColor === 'success' ? 'danger' : 'success';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user