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.
|
* The mode determines which platform styles to use.
|
||||||
*/
|
*/
|
||||||
"mode"?: "ios" | "md";
|
"mode"?: "ios" | "md";
|
||||||
|
/**
|
||||||
|
* Emitted when the color changes.
|
||||||
|
*/
|
||||||
|
"onIonColor"?: (event: CustomEvent<StyleEventDetail>) => void;
|
||||||
/**
|
/**
|
||||||
* Emitted when the styles change.
|
* Emitted when the styles change.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -282,3 +282,14 @@
|
|||||||
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating) {
|
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating) {
|
||||||
color: $label-md-text-color-focused;
|
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 {
|
export class Item implements ComponentInterface, AnchorInterface, ButtonInterface {
|
||||||
|
|
||||||
|
private labelColorStyles = {};
|
||||||
private itemStyles = new Map<string, CssClassMap>();
|
private itemStyles = new Map<string, CssClassMap>();
|
||||||
|
|
||||||
@Element() el!: HTMLIonItemElement;
|
@Element() el!: HTMLIonItemElement;
|
||||||
@ -111,6 +112,18 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
|||||||
*/
|
*/
|
||||||
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
|
@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')
|
@Listen('ionStyle')
|
||||||
itemStyle(ev: CustomEvent<StyleEventDetail>) {
|
itemStyle(ev: CustomEvent<StyleEventDetail>) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
@ -212,7 +225,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
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 childStyles = {};
|
||||||
const mode = getIonMode(this);
|
const mode = getIonMode(this);
|
||||||
const clickable = this.isClickable();
|
const clickable = this.isClickable();
|
||||||
@ -236,6 +249,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
|||||||
aria-disabled={disabled ? 'true' : null}
|
aria-disabled={disabled ? 'true' : null}
|
||||||
class={{
|
class={{
|
||||||
...childStyles,
|
...childStyles,
|
||||||
|
...labelColorStyles,
|
||||||
...createColorClasses(this.color, {
|
...createColorClasses(this.color, {
|
||||||
'item': true,
|
'item': true,
|
||||||
[mode]: true,
|
[mode]: true,
|
||||||
|
|||||||
@ -44,11 +44,16 @@
|
|||||||
@include transform(translateY(50%), scale(.75));
|
@include transform(translateY(50%), scale(.75));
|
||||||
}
|
}
|
||||||
|
|
||||||
:host-context(.item-has-focus).label-stacked,
|
:host-context(.item-has-focus).label-stacked:not(.ion-color),
|
||||||
:host-context(.item-has-focus).label-floating {
|
:host-context(.item-has-focus).label-floating:not(.ion-color) {
|
||||||
color: $label-md-text-color-focused;
|
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
|
// MD Typography
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|||||||
@ -32,6 +32,12 @@ export class Label implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() position?: 'fixed' | 'stacked' | 'floating';
|
@Prop() position?: 'fixed' | 'stacked' | 'floating';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the color changes.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
@Event() ionColor!: EventEmitter<StyleEventDetail>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when the styles change.
|
* Emitted when the styles change.
|
||||||
* @internal
|
* @internal
|
||||||
@ -44,6 +50,7 @@ export class Label implements ComponentInterface {
|
|||||||
this.inRange = !!this.el.closest('ion-range');
|
this.inRange = !!this.el.closest('ion-range');
|
||||||
this.noAnimate = (this.position === 'floating');
|
this.noAnimate = (this.position === 'floating');
|
||||||
this.emitStyle();
|
this.emitStyle();
|
||||||
|
this.emitColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidLoad() {
|
componentDidLoad() {
|
||||||
@ -54,11 +61,25 @@ export class Label implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Watch('color')
|
||||||
|
colorChanged() {
|
||||||
|
this.emitColor();
|
||||||
|
}
|
||||||
|
|
||||||
@Watch('position')
|
@Watch('position')
|
||||||
positionChanged() {
|
positionChanged() {
|
||||||
this.emitStyle();
|
this.emitStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private emitColor() {
|
||||||
|
const { color } = this;
|
||||||
|
|
||||||
|
this.ionColor.emit({
|
||||||
|
'item-label-color': color !== undefined,
|
||||||
|
[`ion-color-${color}`]: color !== undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private emitStyle() {
|
private emitStyle() {
|
||||||
const { inRange, position } = this;
|
const { inRange, position } = this;
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,11 @@
|
|||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-title>Label - Basic</ion-title>
|
<ion-title>Label - Basic</ion-title>
|
||||||
|
<ion-buttons slot="end">
|
||||||
|
<ion-button onClick="changeColors()">
|
||||||
|
Color Change
|
||||||
|
</ion-button>
|
||||||
|
</ion-buttons>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
@ -58,10 +63,37 @@
|
|||||||
<ion-label position="floating">Floating</ion-label>
|
<ion-label position="floating">Floating</ion-label>
|
||||||
<ion-input></ion-input>
|
<ion-input></ion-input>
|
||||||
</ion-item>
|
</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-item>
|
||||||
<ion-label position="stacked">Stacked</ion-label>
|
<ion-label position="stacked">Stacked</ion-label>
|
||||||
<ion-input></ion-input>
|
<ion-input></ion-input>
|
||||||
</ion-item>
|
</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-list>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
||||||
@ -70,6 +102,17 @@
|
|||||||
color: lightblue;
|
color: lightblue;
|
||||||
}
|
}
|
||||||
</style>
|
</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>
|
</ion-app>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user