Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ ion-app,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-app,method,setFocus,setFocus(elements: HTMLElement[]) => Promise<void>

ion-avatar,shadow
ion-avatar,prop,disabled,boolean,false,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,size,"large" | "medium" | "small" | "xlarge" | "xsmall" | "xxsmall" | undefined,undefined,false,false
Expand Down
8 changes: 8 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ export namespace Components {
"theme"?: "ios" | "md" | "ionic";
}
interface IonAvatar {
/**
* If `true`, the user cannot interact with the avatar.
*/
"disabled": boolean;
/**
* The mode determines the platform behaviors of the component.
*/
Expand Down Expand Up @@ -5759,6 +5763,10 @@ declare namespace LocalJSX {
"theme"?: "ios" | "md" | "ionic";
}
interface IonAvatar {
/**
* If `true`, the user cannot interact with the avatar.
*/
"disabled"?: boolean;
/**
* The mode determines the platform behaviors of the component.
*/
Expand Down
6 changes: 6 additions & 0 deletions core/src/components/avatar/avatar.ionic.scss
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,9 @@
:host(.avatar-xxsmall) ::slotted(ion-badge.badge-vertical-bottom:empty) {
transform: translate(globals.$ion-scale-100, calc(globals.$ion-scale-100));
}

// Avatar Disabled
// --------------------------------------------------
:host(.avatar-disabled)::before {
@include globals.disabled-state();
}
11 changes: 9 additions & 2 deletions core/src/components/avatar/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export class Avatar implements ComponentInterface {
*/
@Prop() shape?: 'soft' | 'round' | 'rectangular';

/**
* If `true`, the user cannot interact with the avatar.
*/
@Prop() disabled = false;

get hasImage() {
return !!this.el.querySelector('ion-img') || !!this.el.querySelector('img');
}
Expand Down Expand Up @@ -81,6 +86,7 @@ export class Avatar implements ComponentInterface {
}

render() {
const { hasImage, hasIcon, disabled } = this;
const theme = getIonTheme(this);
const size = this.getSize();
const shape = this.getShape();
Expand All @@ -91,8 +97,9 @@ export class Avatar implements ComponentInterface {
[theme]: true,
[`avatar-${size}`]: size !== undefined,
[`avatar-${shape}`]: shape !== undefined,
[`avatar-image`]: this.hasImage,
[`avatar-icon`]: this.hasIcon,
[`avatar-image`]: hasImage,
[`avatar-icon`]: hasIcon,
[`avatar-disabled`]: disabled,
}}
>
<slot></slot>
Expand Down
27 changes: 27 additions & 0 deletions core/src/components/avatar/test/states/avatar.e2e.ts
Original file line number Diff line number Diff line change
@@ -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`));
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions core/src/components/avatar/test/states/index.html
Original file line number Diff line number Diff line change
@@ -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>
4 changes: 2 additions & 2 deletions packages/angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@ export declare interface IonApp extends Components.IonApp {}


@ProxyCmp({
inputs: ['mode', 'shape', 'size', 'theme']
inputs: ['disabled', 'mode', 'shape', 'size', 'theme']
})
@Component({
selector: 'ion-avatar',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['mode', 'shape', 'size', 'theme'],
inputs: ['disabled', 'mode', 'shape', 'size', 'theme'],
})
export class IonAvatar {
protected el: HTMLIonAvatarElement;
Expand Down
4 changes: 2 additions & 2 deletions packages/angular/standalone/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,14 +295,14 @@ export declare interface IonApp extends Components.IonApp {}

@ProxyCmp({
defineCustomElementFn: defineIonAvatar,
inputs: ['mode', 'shape', 'size', 'theme']
inputs: ['disabled', 'mode', 'shape', 'size', 'theme']
})
@Component({
selector: 'ion-avatar',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['mode', 'shape', 'size', 'theme'],
inputs: ['disabled', 'mode', 'shape', 'size', 'theme'],
standalone: true
})
export class IonAvatar {
Expand Down
3 changes: 2 additions & 1 deletion packages/vue/src/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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, [
'size',
'shape'
'shape',
'disabled'
]);


Expand Down
Loading