feat(card): set round as the default shape for all themes (#29387)
Issue number: internal --------- ## What is the current behavior? The `shape` property defaults to `undefined` which evaluates to the "Soft" shape for all themes. | Property Value | CSS Value (`ionic`) | CSS Value (`ios`) | CSS Value (`md`) | | --------------- | ------ | ----------- | ----------- | | `undefined` | `4px` | `8px ` | `4px` | | `"round"` | `16px` | unsupported | unsupported | | `"rectangular"` | `0px` | unsupported | unsupported | ## What is the new behavior? | Property Value | CSS Value (`ionic`) | CSS Value (`ios`) | CSS Value (`md`) | | --------------- | ------- | ------ | -------- | | `"soft"` | `4px` | `8px` | `4px` | | `"round"` | `16px` | `14px` | `12px` | | `"rectangular"` | `0px` | `0px` | `0px` | - Adds support for the `"soft"` shape using the existing values for `undefined` - Sets the default `shape` property to `"round"` for all themes and updates the `border-radius` to apply to the shape classes instead of `:host` - Adds support for the `"round"` and `"rectangular"` shapes in `ios` and `md` - Updates the `ios` theme to use `14px` for `"round"` as this is taken from the card in the iOS App Store <img width="400px" src="https://github.com/ionic-team/ionic-framework/assets/6577830/51f7028c-990d-48b5-b3e0-9909dae7e31c"> - Updates the `md` theme to use `12px` for `"round"` as this is taken from the [Material Design 3 guidelines](https://m3.material.io/components/cards/specs#daab7734-3b3e-464c-a967-7c7fa14e6478) ## Does this introduce a breaking change? - [x] Yes - [ ] No BREAKING CHANGE: The `border-radius` of the `ios` and `md` card now defaults to `14px` and `12px` instead of `8px` and `4px`, respectively, in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"soft"`, or override the `--border-radius` CSS variable to specify a different value. --------- Co-authored-by: ionitron <hi@ionicframework.com>
@@ -13,3 +13,12 @@ This is a comprehensive list of the breaking changes introduced in the major ver
|
||||
- [Legacy](https://github.com/ionic-team/ionic-v3/blob/master/CHANGELOG.md)
|
||||
|
||||
## Version 9.x
|
||||
|
||||
- [Components](#version-9x-components)
|
||||
- [Card](#version-9x-card)
|
||||
|
||||
<h2 id="version-9x-components">Components</h2>
|
||||
|
||||
<h4 id="version-9x-card">Card</h4>
|
||||
|
||||
- The `border-radius` of the `ios` and `md` card now defaults to `14px` and `12px` instead of `8px` and `4px`, respectively, in accordance with the iOS and Material Design 3 guidelines. To revert to the previous appearance, set the `shape` to `"soft"`, or override the `--border-radius` CSS variable to specify a different value.
|
||||
|
||||
@@ -282,11 +282,12 @@ ion-card,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-card,prop,rel,string | undefined,undefined,false,false
|
||||
ion-card,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-card,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
|
||||
ion-card,prop,shape,"rectangular" | "round" | undefined,undefined,false,true
|
||||
ion-card,prop,shape,"rectangular" | "round" | "soft" | undefined,'round',false,true
|
||||
ion-card,prop,target,string | undefined,undefined,false,false
|
||||
ion-card,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-card,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-card,css-prop,--background
|
||||
ion-card,css-prop,--border-radius
|
||||
ion-card,css-prop,--color
|
||||
ion-card,part,native
|
||||
|
||||
|
||||
8
core/src/components.d.ts
vendored
@@ -619,9 +619,9 @@ export namespace Components {
|
||||
*/
|
||||
"routerDirection": RouterDirection;
|
||||
/**
|
||||
* Set to `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners.
|
||||
* Set to `"soft"` for a card with slightly rounded corners, `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners. Defaults to `"round"`.
|
||||
*/
|
||||
"shape"?: 'round' | 'rectangular';
|
||||
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||
/**
|
||||
* Specifies where to display the linked URL. Only applies when an `href` is provided. Special keywords: `"_blank"`, `"_self"`, `"_parent"`, `"_top"`.
|
||||
*/
|
||||
@@ -5867,9 +5867,9 @@ declare namespace LocalJSX {
|
||||
*/
|
||||
"routerDirection"?: RouterDirection;
|
||||
/**
|
||||
* Set to `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners.
|
||||
* Set to `"soft"` for a card with slightly rounded corners, `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners. Defaults to `"round"`.
|
||||
*/
|
||||
"shape"?: 'round' | 'rectangular';
|
||||
"shape"?: 'soft' | 'round' | 'rectangular';
|
||||
/**
|
||||
* Specifies where to display the linked URL. Only applies when an `href` is provided. Special keywords: `"_blank"`, `"_self"`, `"_parent"`, `"_top"`.
|
||||
*/
|
||||
|
||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@@ -18,6 +18,9 @@
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
// Card Shapes
|
||||
// ---------------------------------------------
|
||||
|
||||
:host(.card-round) {
|
||||
--border-radius: #{globals.$ionic-border-radius-rounded-large};
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
--color: #{$card-ios-color};
|
||||
|
||||
@include margin($card-ios-margin-top, $card-ios-margin-end, $card-ios-margin-bottom, $card-ios-margin-start);
|
||||
@include border-radius($card-ios-border-radius);
|
||||
|
||||
transition: transform 500ms $card-ios-transition-timing-function;
|
||||
|
||||
@@ -21,3 +20,18 @@
|
||||
:host(.ion-activated) {
|
||||
transform: #{$card-ios-transform-activated};
|
||||
}
|
||||
|
||||
// Card Shapes
|
||||
// ---------------------------------------------
|
||||
|
||||
:host(.card-soft) {
|
||||
--border-radius: 8px;
|
||||
}
|
||||
|
||||
:host(.card-round) {
|
||||
--border-radius: 14px;
|
||||
}
|
||||
|
||||
:host(.card-rectangular) {
|
||||
--border-radius: 0px;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,6 @@ $card-ios-box-shadow-color: rgba(0, 0, 0, 0.12);
|
||||
/// @prop - Box shadow of the card
|
||||
$card-ios-box-shadow: 0 4px 16px $card-ios-box-shadow-color;
|
||||
|
||||
/// @prop - Border radius of the card
|
||||
$card-ios-border-radius: 8px;
|
||||
|
||||
/// @prop - Font size of the card
|
||||
$card-ios-font-size: dynamic-font(14px);
|
||||
|
||||
|
||||
@@ -9,9 +9,23 @@
|
||||
--color: #{$card-md-color};
|
||||
|
||||
@include margin($card-md-margin-top, $card-md-margin-end, $card-md-margin-bottom, $card-md-margin-start);
|
||||
@include border-radius($card-md-border-radius);
|
||||
|
||||
font-size: $card-md-font-size;
|
||||
|
||||
box-shadow: $card-md-box-shadow;
|
||||
}
|
||||
|
||||
// Card Shapes
|
||||
// ---------------------------------------------
|
||||
|
||||
:host(.card-soft) {
|
||||
--border-radius: 4px;
|
||||
}
|
||||
|
||||
:host(.card-round) {
|
||||
--border-radius: 12px;
|
||||
}
|
||||
|
||||
:host(.card-rectangular) {
|
||||
--border-radius: 0px;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,6 @@ $card-md-margin-start: 10px;
|
||||
/// @prop - Box shadow of the card
|
||||
$card-md-box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
|
||||
/// @prop - Border radius of the card
|
||||
$card-md-border-radius: 4px;
|
||||
|
||||
/// @prop - Font size of the card
|
||||
$card-md-font-size: dynamic-font(14px);
|
||||
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
/**
|
||||
* @prop --background: Background of the card
|
||||
* @prop --color: Color of the card
|
||||
* @prop --border-radius: Border radius of the card
|
||||
*/
|
||||
--ion-safe-area-left: 0px;
|
||||
--ion-safe-area-right: 0px;
|
||||
|
||||
@include border-radius(var(--border-radius));
|
||||
@include font-smoothing();
|
||||
|
||||
display: block;
|
||||
|
||||
@@ -83,9 +83,11 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
@Prop() routerAnimation: AnimationBuilder | undefined;
|
||||
|
||||
/**
|
||||
* Set to `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners.
|
||||
* Set to `"soft"` for a card with slightly rounded corners, `"round"` for a card with more
|
||||
* rounded corners, or `"rectangular"` for a card without rounded corners.
|
||||
* Defaults to `"round"`.
|
||||
*/
|
||||
@Prop({ reflect: true }) shape?: 'round' | 'rectangular';
|
||||
@Prop({ reflect: true }) shape?: 'soft' | 'round' | 'rectangular' = 'round';
|
||||
|
||||
/**
|
||||
* Specifies where to display the linked URL.
|
||||
@@ -144,8 +146,7 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[theme]: true,
|
||||
// TODO(FW-6119): remove theme === 'ionic' when support for other themes is added
|
||||
[`card-${shape}`]: theme === 'ionic' && shape !== undefined,
|
||||
[`card-${shape}`]: shape !== undefined,
|
||||
'card-disabled': this.disabled,
|
||||
'ion-activatable': this.isClickable(),
|
||||
})}
|
||||
|
||||
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -2,10 +2,9 @@ import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
/**
|
||||
* Shape is only available in the Ionic theme.
|
||||
* TODO(FW-6119): add the `ios` and `md` modes when shape support is added.
|
||||
* This behavior does not vary across directions
|
||||
*/
|
||||
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
configs({ modes: ['ionic-md', 'md', 'ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('card: shape'), () => {
|
||||
test.describe('default', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
@@ -17,6 +16,16 @@ configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screensh
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('soft', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/card/test/shape`, config);
|
||||
|
||||
const container = page.locator('#soft');
|
||||
|
||||
await expect(container).toHaveScreenshot(screenshot(`card-soft`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('round', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/card/test/shape`, config);
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 10 KiB |
@@ -15,13 +15,11 @@
|
||||
|
||||
<!-- Styles only for testing purposes to identify the card shape -->
|
||||
<style>
|
||||
:root {
|
||||
--ion-background-color: #dde2ef;
|
||||
ion-content {
|
||||
--background: #dde2ef;
|
||||
}
|
||||
|
||||
#default,
|
||||
#round,
|
||||
#rectangular {
|
||||
.container {
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -37,7 +35,7 @@
|
||||
|
||||
<ion-content class="ion-padding ion-text-center" id="content" no-bounce>
|
||||
<h1>Default</h1>
|
||||
<div id="default" class="ion-margin-top">
|
||||
<div id="default" class="container">
|
||||
<ion-card>
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
@@ -50,8 +48,24 @@
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
|
||||
<h1>Soft</h1>
|
||||
<div id="soft" class="container">
|
||||
<ion-card shape="soft">
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
<ion-card-title>Card Title</ion-card-title>
|
||||
</ion-card-header>
|
||||
|
||||
<ion-card-content>
|
||||
Keep close to Nature's heart... and break clear away, once in awhile, and climb a mountain or spend a week
|
||||
in the woods. Wash your spirit clean.
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
|
||||
<h1>Round</h1>
|
||||
<div id="round" class="ion-margin-top">
|
||||
<div id="round" class="container">
|
||||
<ion-card shape="round">
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
@@ -66,7 +80,7 @@
|
||||
</div>
|
||||
|
||||
<h1>Rectangular</h1>
|
||||
<div id="rectangular" class="ion-margin-top">
|
||||
<div id="rectangular" class="container">
|
||||
<ion-card shape="rectangular">
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 981 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.5 KiB |