mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 09:34:19 +08:00
feat(avatar): add disabled property (#30284)
Issue number: internal --------- ## What is the current behavior? Avatar does not have a disabled state for the ionic theme. ## What is the new behavior? - Added styles for ionic theme disabled state - Added states e2e test & snapshots ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> [Preview](https://ionic-framework-git-rou-11728-ionic1.vercel.app/src/components/avatar/test/states?ionic:theme=ionic) --------- Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com> Co-authored-by: ionitron <hi@ionicframework.com>
This commit is contained in:
@ -185,6 +185,7 @@ ion-app,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
|||||||
ion-app,method,setFocus,setFocus(elements: HTMLElement[]) => Promise<void>
|
ion-app,method,setFocus,setFocus(elements: HTMLElement[]) => Promise<void>
|
||||||
|
|
||||||
ion-avatar,shadow
|
ion-avatar,shadow
|
||||||
|
ion-avatar,prop,disabled,boolean,false,false,false
|
||||||
ion-avatar,prop,mode,"ios" | "md",undefined,false,false
|
ion-avatar,prop,mode,"ios" | "md",undefined,false,false
|
||||||
ion-avatar,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
|
ion-avatar,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
|
||||||
ion-avatar,prop,size,"large" | "medium" | "small" | "xlarge" | "xsmall" | "xxsmall" | undefined,undefined,false,false
|
ion-avatar,prop,size,"large" | "medium" | "small" | "xlarge" | "xsmall" | "xxsmall" | undefined,undefined,false,false
|
||||||
|
8
core/src/components.d.ts
vendored
8
core/src/components.d.ts
vendored
@ -343,6 +343,10 @@ export namespace Components {
|
|||||||
"theme"?: "ios" | "md" | "ionic";
|
"theme"?: "ios" | "md" | "ionic";
|
||||||
}
|
}
|
||||||
interface IonAvatar {
|
interface IonAvatar {
|
||||||
|
/**
|
||||||
|
* If `true`, the user cannot interact with the avatar.
|
||||||
|
*/
|
||||||
|
"disabled": boolean;
|
||||||
/**
|
/**
|
||||||
* The mode determines the platform behaviors of the component.
|
* The mode determines the platform behaviors of the component.
|
||||||
*/
|
*/
|
||||||
@ -5759,6 +5763,10 @@ declare namespace LocalJSX {
|
|||||||
"theme"?: "ios" | "md" | "ionic";
|
"theme"?: "ios" | "md" | "ionic";
|
||||||
}
|
}
|
||||||
interface IonAvatar {
|
interface IonAvatar {
|
||||||
|
/**
|
||||||
|
* If `true`, the user cannot interact with the avatar.
|
||||||
|
*/
|
||||||
|
"disabled"?: boolean;
|
||||||
/**
|
/**
|
||||||
* The mode determines the platform behaviors of the component.
|
* The mode determines the platform behaviors of the component.
|
||||||
*/
|
*/
|
||||||
|
@ -171,3 +171,9 @@
|
|||||||
:host(.avatar-xxsmall) ::slotted(ion-badge.badge-vertical-bottom:empty) {
|
:host(.avatar-xxsmall) ::slotted(ion-badge.badge-vertical-bottom:empty) {
|
||||||
transform: translate(globals.$ion-scale-100, calc(globals.$ion-scale-100));
|
transform: translate(globals.$ion-scale-100, calc(globals.$ion-scale-100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avatar Disabled
|
||||||
|
// --------------------------------------------------
|
||||||
|
:host(.avatar-disabled)::before {
|
||||||
|
@include globals.disabled-state();
|
||||||
|
}
|
||||||
|
@ -40,6 +40,11 @@ export class Avatar implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop() shape?: 'soft' | 'round' | 'rectangular';
|
@Prop() shape?: 'soft' | 'round' | 'rectangular';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `true`, the user cannot interact with the avatar.
|
||||||
|
*/
|
||||||
|
@Prop() disabled = false;
|
||||||
|
|
||||||
get hasImage() {
|
get hasImage() {
|
||||||
return !!this.el.querySelector('ion-img') || !!this.el.querySelector('img');
|
return !!this.el.querySelector('ion-img') || !!this.el.querySelector('img');
|
||||||
}
|
}
|
||||||
@ -81,6 +86,7 @@ export class Avatar implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { hasImage, hasIcon, disabled } = this;
|
||||||
const theme = getIonTheme(this);
|
const theme = getIonTheme(this);
|
||||||
const size = this.getSize();
|
const size = this.getSize();
|
||||||
const shape = this.getShape();
|
const shape = this.getShape();
|
||||||
@ -91,8 +97,9 @@ export class Avatar implements ComponentInterface {
|
|||||||
[theme]: true,
|
[theme]: true,
|
||||||
[`avatar-${size}`]: size !== undefined,
|
[`avatar-${size}`]: size !== undefined,
|
||||||
[`avatar-${shape}`]: shape !== undefined,
|
[`avatar-${shape}`]: shape !== undefined,
|
||||||
[`avatar-image`]: this.hasImage,
|
[`avatar-image`]: hasImage,
|
||||||
[`avatar-icon`]: this.hasIcon,
|
[`avatar-icon`]: hasIcon,
|
||||||
|
[`avatar-disabled`]: disabled,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
27
core/src/components/avatar/test/states/avatar.e2e.ts
Normal file
27
core/src/components/avatar/test/states/avatar.e2e.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { expect } from '@playwright/test';
|
||||||
|
import { configs, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avatar does not test RTL behaviors.
|
||||||
|
* Usages of Avatar in slots are tested in components that use Avatar.
|
||||||
|
*/
|
||||||
|
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screenshot, title }) => {
|
||||||
|
test.describe(title('avatar: states'), () => {
|
||||||
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<div id="container">
|
||||||
|
<ion-avatar disabled> AV </ion-avatar>
|
||||||
|
<ion-avatar disabled>
|
||||||
|
<img src="/src/components/avatar/test/avatar.svg" />
|
||||||
|
</ion-avatar>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
const container = page.locator('#container');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`avatar-disabled`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
34
core/src/components/avatar/test/states/index.html
Normal file
34
core/src/components/avatar/test/states/index.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Avatar - States</title>
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
|
/>
|
||||||
|
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||||
|
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||||
|
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||||
|
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||||
|
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Avatar - States</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content>
|
||||||
|
<h3>Disabled</h3>
|
||||||
|
<ion-avatar disabled>AV</ion-avatar>
|
||||||
|
<ion-avatar disabled>
|
||||||
|
<img src="/src/components/avatar/test/avatar.svg" />
|
||||||
|
</ion-avatar>
|
||||||
|
</ion-content>
|
||||||
|
</ion-app>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -211,14 +211,14 @@ export declare interface IonApp extends Components.IonApp {}
|
|||||||
|
|
||||||
|
|
||||||
@ProxyCmp({
|
@ProxyCmp({
|
||||||
inputs: ['mode', 'shape', 'size', 'theme']
|
inputs: ['disabled', 'mode', 'shape', 'size', 'theme']
|
||||||
})
|
})
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-avatar',
|
selector: 'ion-avatar',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
template: '<ng-content></ng-content>',
|
template: '<ng-content></ng-content>',
|
||||||
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
||||||
inputs: ['mode', 'shape', 'size', 'theme'],
|
inputs: ['disabled', 'mode', 'shape', 'size', 'theme'],
|
||||||
})
|
})
|
||||||
export class IonAvatar {
|
export class IonAvatar {
|
||||||
protected el: HTMLIonAvatarElement;
|
protected el: HTMLIonAvatarElement;
|
||||||
|
@ -295,14 +295,14 @@ export declare interface IonApp extends Components.IonApp {}
|
|||||||
|
|
||||||
@ProxyCmp({
|
@ProxyCmp({
|
||||||
defineCustomElementFn: defineIonAvatar,
|
defineCustomElementFn: defineIonAvatar,
|
||||||
inputs: ['mode', 'shape', 'size', 'theme']
|
inputs: ['disabled', 'mode', 'shape', 'size', 'theme']
|
||||||
})
|
})
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-avatar',
|
selector: 'ion-avatar',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
template: '<ng-content></ng-content>',
|
template: '<ng-content></ng-content>',
|
||||||
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
||||||
inputs: ['mode', 'shape', 'size', 'theme'],
|
inputs: ['disabled', 'mode', 'shape', 'size', 'theme'],
|
||||||
standalone: true
|
standalone: true
|
||||||
})
|
})
|
||||||
export class IonAvatar {
|
export class IonAvatar {
|
||||||
|
@ -112,7 +112,8 @@ export const IonAccordionGroup: StencilVueComponent<JSX.IonAccordionGroup, JSX.I
|
|||||||
|
|
||||||
export const IonAvatar: StencilVueComponent<JSX.IonAvatar> = /*@__PURE__*/ defineContainer<JSX.IonAvatar>('ion-avatar', defineIonAvatar, [
|
export const IonAvatar: StencilVueComponent<JSX.IonAvatar> = /*@__PURE__*/ defineContainer<JSX.IonAvatar>('ion-avatar', defineIonAvatar, [
|
||||||
'size',
|
'size',
|
||||||
'shape'
|
'shape',
|
||||||
|
'disabled'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user