feat(avatar): add styles for soft shape in ionic theme (#29552)
Issue number: internal --------- ## What is the current behavior? Avatar does not have styles for the `"soft"` shape in the ionic theme. ## What is the new behavior? - Adds the styles for the soft shape (border radius) - The `xsmall` and `small` sizes have a different border radius than the larger sizes - Adds e2e tests for the soft shape ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information [Preview](https://ionic-framework-git-rou-10739-ionic1.vercel.app/src/components/avatar/test/shape?ionic:theme=ionic)
@ -184,7 +184,7 @@ ion-app,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
|||||||
|
|
||||||
ion-avatar,shadow
|
ion-avatar,shadow
|
||||||
ion-avatar,prop,mode,"ios" | "md",undefined,false,false
|
ion-avatar,prop,mode,"ios" | "md",undefined,false,false
|
||||||
ion-avatar,prop,shape,"rectangular" | "round" | undefined,undefined,false,false
|
ion-avatar,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
|
||||||
ion-avatar,prop,size,"large" | "medium" | "small" | "xlarge" | "xsmall" | undefined,undefined,false,false
|
ion-avatar,prop,size,"large" | "medium" | "small" | "xlarge" | "xsmall" | undefined,undefined,false,false
|
||||||
ion-avatar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
ion-avatar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||||
ion-avatar,css-prop,--border-radius,ionic
|
ion-avatar,css-prop,--border-radius,ionic
|
||||||
|
8
core/src/components.d.ts
vendored
@ -336,9 +336,9 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
"mode"?: "ios" | "md";
|
"mode"?: "ios" | "md";
|
||||||
/**
|
/**
|
||||||
* Set to `"round"` for an avatar with fully rounded corners, or `"rectangular"` for an avatar without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
* Set to `"soft"` for an avatar with slightly rounded corners, `"round"` for an avatar with fully rounded corners, or `"rectangular"` for an avatar without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
||||||
*/
|
*/
|
||||||
"shape"?: 'round' | 'rectangular';
|
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||||
/**
|
/**
|
||||||
* Set to `"xsmall"` for the smallest size, `"small"` for a compact size, `"medium"` for the default height and width, `"large"` for a larger size, or `"xlarge"` for the largest dimensions. Defaults to `"medium"` for the `ionic` theme, undefined for all other themes.
|
* Set to `"xsmall"` for the smallest size, `"small"` for a compact size, `"medium"` for the default height and width, `"large"` for a larger size, or `"xlarge"` for the largest dimensions. Defaults to `"medium"` for the `ionic` theme, undefined for all other themes.
|
||||||
*/
|
*/
|
||||||
@ -5572,9 +5572,9 @@ declare namespace LocalJSX {
|
|||||||
*/
|
*/
|
||||||
"mode"?: "ios" | "md";
|
"mode"?: "ios" | "md";
|
||||||
/**
|
/**
|
||||||
* Set to `"round"` for an avatar with fully rounded corners, or `"rectangular"` for an avatar without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
* Set to `"soft"` for an avatar with slightly rounded corners, `"round"` for an avatar with fully rounded corners, or `"rectangular"` for an avatar without rounded corners. Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
||||||
*/
|
*/
|
||||||
"shape"?: 'round' | 'rectangular';
|
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||||
/**
|
/**
|
||||||
* Set to `"xsmall"` for the smallest size, `"small"` for a compact size, `"medium"` for the default height and width, `"large"` for a larger size, or `"xlarge"` for the largest dimensions. Defaults to `"medium"` for the `ionic` theme, undefined for all other themes.
|
* Set to `"xsmall"` for the smallest size, `"small"` for a compact size, `"medium"` for the default height and width, `"large"` for a larger size, or `"xlarge"` for the largest dimensions. Defaults to `"medium"` for the `ionic` theme, undefined for all other themes.
|
||||||
*/
|
*/
|
||||||
|
@ -89,6 +89,15 @@
|
|||||||
// Avatar Shapes
|
// Avatar Shapes
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
:host(.avatar-xsmall.avatar-soft),
|
||||||
|
:host(.avatar-small.avatar-soft) {
|
||||||
|
--border-radius: #{globals.$ionic-border-radius-100};
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(.avatar-soft) {
|
||||||
|
--border-radius: #{globals.$ionic-border-radius-200};
|
||||||
|
}
|
||||||
|
|
||||||
:host(.avatar-round) {
|
:host(.avatar-round) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-full};
|
--border-radius: #{globals.$ionic-border-radius-full};
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,13 @@ export class Avatar implements ComponentInterface {
|
|||||||
@Prop() size?: `xsmall` | 'small' | 'medium' | 'large' | 'xlarge';
|
@Prop() size?: `xsmall` | 'small' | 'medium' | 'large' | 'xlarge';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to `"round"` for an avatar with fully rounded corners, or `"rectangular"`
|
* Set to `"soft"` for an avatar with slightly rounded corners,
|
||||||
|
* `"round"` for an avatar with fully rounded corners, or `"rectangular"`
|
||||||
* for an avatar without rounded corners.
|
* for an avatar without rounded corners.
|
||||||
*
|
*
|
||||||
* Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
* Defaults to `"round"` for the `ionic` theme, undefined for all other themes.
|
||||||
*/
|
*/
|
||||||
@Prop() shape?: 'round' | 'rectangular';
|
@Prop() shape?: 'soft' | 'round' | 'rectangular';
|
||||||
|
|
||||||
get hasImage() {
|
get hasImage() {
|
||||||
return !!this.el.querySelector('ion-img') || !!this.el.querySelector('img');
|
return !!this.el.querySelector('ion-img') || !!this.el.querySelector('img');
|
||||||
|
@ -95,5 +95,91 @@ configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screens
|
|||||||
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-rectangular-image`));
|
await expect(avatar).toHaveScreenshot(screenshot(`avatar-shape-rectangular-image`));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.describe('soft', () => {
|
||||||
|
test('should not have visual regressions when containing text', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<ion-avatar shape="soft" size="xsmall">AB</ion-avatar>
|
||||||
|
<ion-avatar shape="soft" size="small">AB</ion-avatar>
|
||||||
|
<ion-avatar shape="soft">AB</ion-avatar>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
const container = page.locator('#container');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`avatar-shape-soft-text`));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not have visual regressions when containing an icon', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<ion-avatar shape="soft" size="xsmall">
|
||||||
|
<ion-icon name="person-outline"></ion-icon>
|
||||||
|
</ion-avatar>
|
||||||
|
<ion-avatar shape="soft" size="small">
|
||||||
|
<ion-icon name="person-outline"></ion-icon>
|
||||||
|
</ion-avatar>
|
||||||
|
<ion-avatar shape="soft">
|
||||||
|
<ion-icon name="person-outline"></ion-icon>
|
||||||
|
</ion-avatar>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
const container = page.locator('#container');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`avatar-shape-soft-icon`));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not have visual regressions when containing an image', async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<style>
|
||||||
|
#container {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<ion-avatar shape="soft" size="xsmall">
|
||||||
|
<img src="/src/components/avatar/test/avatar.svg"/>
|
||||||
|
</ion-avatar>
|
||||||
|
<ion-avatar shape="soft" size="small">
|
||||||
|
<img src="/src/components/avatar/test/avatar.svg"/>
|
||||||
|
</ion-avatar>
|
||||||
|
<ion-avatar shape="soft">
|
||||||
|
<img src="/src/components/avatar/test/avatar.svg"/>
|
||||||
|
</ion-avatar>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
const container = page.locator('#container');
|
||||||
|
|
||||||
|
await expect(container).toHaveScreenshot(screenshot(`avatar-shape-soft-image`));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.4 KiB |
@ -41,6 +41,15 @@
|
|||||||
</ion-avatar>
|
</ion-avatar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h2>Soft</h2>
|
||||||
|
<div class="container">
|
||||||
|
<ion-avatar shape="soft" size="xsmall">AB</ion-avatar>
|
||||||
|
<ion-avatar shape="soft" size="small">AB</ion-avatar>
|
||||||
|
<ion-avatar shape="soft" size="medium">AB</ion-avatar>
|
||||||
|
<ion-avatar shape="soft" size="large">AB</ion-avatar>
|
||||||
|
<ion-avatar shape="soft" size="xlarge">AB</ion-avatar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2>Round</h2>
|
<h2>Round</h2>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<ion-avatar shape="round" size="xsmall">AB</ion-avatar>
|
<ion-avatar shape="round" size="xsmall">AB</ion-avatar>
|
||||||
|