feat(accordion): add shape styles for the ionic theme (#29973)
- Applies border radius based on the `shape` defined on the parent accordion group - Adds an e2e test for shape with focused items to show the border radius - Adds screenshots for the e2e test
@ -19,13 +19,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:host(.accordion-group-expand-inset.accordion-group-shape-round) {
|
:host(.accordion-group-expand-inset.accordion-group-shape-round) {
|
||||||
|
--border-radius: #{globals.$ion-border-radius-400};
|
||||||
|
|
||||||
@include globals.border-radius(globals.$ion-border-radius-400);
|
@include globals.border-radius(globals.$ion-border-radius-400);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.accordion-group-expand-inset.accordion-group-shape-soft) {
|
:host(.accordion-group-expand-inset.accordion-group-shape-soft) {
|
||||||
|
--border-radius: #{globals.$ion-border-radius-200};
|
||||||
|
|
||||||
@include globals.border-radius(globals.$ion-border-radius-200);
|
@include globals.border-radius(globals.$ion-border-radius-200);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.accordion-group-expand-inset.accordion-group-shape-rectangular) {
|
:host(.accordion-group-expand-inset.accordion-group-shape-rectangular) {
|
||||||
|
--border-radius: #{globals.$ion-border-radius-0};
|
||||||
|
|
||||||
@include globals.border-radius(globals.$ion-border-radius-0);
|
@include globals.border-radius(globals.$ion-border-radius-0);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
// @import "../../themes/functions.string";
|
|
||||||
// @import "../../themes/mixins";
|
|
||||||
|
|
||||||
// Accordion: Common
|
// Accordion: Common
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
// The border is removed from the item in the header because
|
// The border is removed from the item in the header because
|
||||||
// we are adding a border to the ::after element of the accordion.
|
// we are adding a border to the ::after element of the accordion.
|
||||||
::slotted(ion-item[slot="header"]) {
|
::slotted(ion-item[slot="header"]) {
|
||||||
--border-radius: #{globals.$ion-border-radius-0};
|
--border-radius: inherit;
|
||||||
--color: #{globals.$ion-primitives-neutral-1200};
|
--color: #{globals.$ion-primitives-neutral-1200};
|
||||||
--border-width: 0;
|
--border-width: 0;
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0;
|
||||||
@ -55,11 +55,6 @@
|
|||||||
@include globals.typography(globals.$ion-heading-h6-medium);
|
@include globals.typography(globals.$ion-heading-h6-medium);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shape only applies when inside an inset accordion group
|
|
||||||
:host(.in-accordion-group-expand-inset) ::slotted(ion-item[slot="header"]) {
|
|
||||||
--border-radius: #{globals.$ion-border-radius-400};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accordion Content
|
// Accordion Content
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
48
core/src/components/accordion/test/shape/accordion.e2e.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { expect } from '@playwright/test';
|
||||||
|
import { configs, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
configs({ directions: ['ltr'], modes: ['ionic-md'] }).forEach(({ config, screenshot, title }) => {
|
||||||
|
test.describe(title('accordion: shape'), () => {
|
||||||
|
['round', 'soft', 'rectangular'].forEach((shape) => {
|
||||||
|
test(`${shape} - should not have visual regressions`, async ({ page }) => {
|
||||||
|
await page.setContent(
|
||||||
|
`
|
||||||
|
<style>
|
||||||
|
/* Background styles to show the border radius */
|
||||||
|
:root {
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Focused accordion to show the border radius -->
|
||||||
|
<ion-accordion-group value="first" expand="inset" shape="${shape}">
|
||||||
|
<ion-accordion value="first">
|
||||||
|
<ion-item slot="header" class="ion-focused">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="second">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="third">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
</ion-accordion-group>
|
||||||
|
`,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
|
||||||
|
const accordionGroup = page.locator('ion-accordion-group');
|
||||||
|
|
||||||
|
await expect(accordionGroup).toHaveScreenshot(screenshot(`accordion-shape-${shape}`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 9.2 KiB |
135
core/src/components/accordion/test/shape/index.html
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Accordion - Shape</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
||||||
|
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||||
|
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||||
|
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||||
|
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||||
|
<style>
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
grid-row-gap: 20px;
|
||||||
|
grid-column-gap: 20px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
color: #6f7378;
|
||||||
|
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
<ion-header translucent="true">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Accordion - Shape</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content fullscreen="true" color="light">
|
||||||
|
<div class="grid ion-padding">
|
||||||
|
<div class="grid-item">
|
||||||
|
<h2>Default</h2>
|
||||||
|
<ion-accordion-group expand="inset" value="first">
|
||||||
|
<ion-accordion value="first">
|
||||||
|
<ion-item slot="header" class="ion-focused">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="second">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="third">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
</ion-accordion-group>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<h2>Round</h2>
|
||||||
|
<ion-accordion-group expand="inset" value="first" shape="round">
|
||||||
|
<ion-accordion value="first">
|
||||||
|
<ion-item slot="header" class="ion-focused">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="second">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="third">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
</ion-accordion-group>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<h2>Soft</h2>
|
||||||
|
<ion-accordion-group expand="inset" value="first" shape="soft">
|
||||||
|
<ion-accordion value="first">
|
||||||
|
<ion-item slot="header" class="ion-focused">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="second">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="third">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
</ion-accordion-group>
|
||||||
|
</div>
|
||||||
|
<div class="grid-item">
|
||||||
|
<h2>Rectangular</h2>
|
||||||
|
<ion-accordion-group expand="inset" value="first" shape="rectangular">
|
||||||
|
<ion-accordion value="first">
|
||||||
|
<ion-item slot="header" class="ion-focused">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="second">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
<ion-accordion value="third">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-label>Accordion title</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div slot="content">This is the body of the accordion.</div>
|
||||||
|
</ion-accordion>
|
||||||
|
</ion-accordion-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
|
</ion-app>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -47,6 +47,7 @@ body.backdrop-no-scroll {
|
|||||||
|
|
||||||
// Modal - Card Style
|
// Modal - Card Style
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Card style modal needs additional padding on the
|
* Card style modal needs additional padding on the
|
||||||
* top of the header. We accomplish this by targeting
|
* top of the header. We accomplish this by targeting
|
||||||
@ -293,14 +294,18 @@ ion-card-header.ion-color .ion-inherit-color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Accordion Styles
|
// Accordion Styles
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
ion-accordion-group.accordion-group-expand-inset > ion-accordion:first-of-type {
|
ion-accordion-group.accordion-group-expand-inset > ion-accordion:first-of-type {
|
||||||
border-top-left-radius: 8px;
|
border-top-left-radius: 8px;
|
||||||
border-top-right-radius: 8px;
|
border-top-right-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-accordion-group.accordion-group-expand-inset > ion-accordion:last-of-type {
|
ion-accordion-group.accordion-group-expand-inset > ion-accordion:last-of-type {
|
||||||
border-bottom-left-radius: 8px;
|
border-bottom-left-radius: 8px;
|
||||||
border-bottom-right-radius: 8px;
|
border-bottom-right-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-accordion-group > ion-accordion:last-of-type ion-item[slot="header"] {
|
ion-accordion-group > ion-accordion:last-of-type ion-item[slot="header"] {
|
||||||
--border-width: 0px;
|
--border-width: 0px;
|
||||||
}
|
}
|
||||||
@ -315,6 +320,7 @@ ion-accordion.accordion-animated > [slot="header"] .ion-accordion-toggle-icon {
|
|||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The > [slot="header"] selector ensures that we do
|
* The > [slot="header"] selector ensures that we do
|
||||||
* not modify toggle icons for any nested accordions. The state
|
* not modify toggle icons for any nested accordions. The state
|
||||||
@ -336,6 +342,9 @@ ion-accordion-group.accordion-group-expand-inset.md > ion-accordion.accordion-ex
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Datetime Styles
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
// Safari/iOS 15 changes the appearance of input[type="date"].
|
// Safari/iOS 15 changes the appearance of input[type="date"].
|
||||||
// For backwards compatibility from Ionic 5/Safari 14 designs,
|
// For backwards compatibility from Ionic 5/Safari 14 designs,
|
||||||
// we override the appearance only when using within an ion-input.
|
// we override the appearance only when using within an ion-input.
|
||||||
@ -383,6 +392,9 @@ h1[tabindex="-1"]:focus,
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Popover Styles
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a popover has a child ion-content (or class equivalent) then the .popover-viewport element
|
* If a popover has a child ion-content (or class equivalent) then the .popover-viewport element
|
||||||
* should not be scrollable to ensure the inner content does scroll. However, if the popover
|
* should not be scrollable to ensure the inner content does scroll. However, if the popover
|
||||||
|
@ -36,6 +36,7 @@ body.backdrop-no-scroll {
|
|||||||
|
|
||||||
// Modal - Card Style
|
// Modal - Card Style
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
html.ionic ion-modal ion-header {
|
html.ionic ion-modal ion-header {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
@ -301,14 +302,7 @@ ion-card-header.ion-color .ion-inherit-color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Accordion Styles
|
// Accordion Styles
|
||||||
ion-accordion-group.accordion-group-expand-inset > ion-accordion:first-of-type {
|
// --------------------------------------------------
|
||||||
border-top-left-radius: globals.$ion-border-radius-200;
|
|
||||||
border-top-right-radius: globals.$ion-border-radius-200;
|
|
||||||
}
|
|
||||||
ion-accordion-group.accordion-group-expand-inset > ion-accordion:last-of-type {
|
|
||||||
border-bottom-left-radius: globals.$ion-border-radius-200;
|
|
||||||
border-bottom-right-radius: globals.$ion-border-radius-200;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The toggle icon is nested in the accordion item so we need to
|
// The toggle icon is nested in the accordion item so we need to
|
||||||
// style it from a global level.
|
// style it from a global level.
|
||||||
@ -327,6 +321,7 @@ ion-accordion.accordion-animated > [slot="header"] .ion-accordion-toggle-icon {
|
|||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The > [slot="header"] selector ensures that we do
|
* The > [slot="header"] selector ensures that we do
|
||||||
* not modify toggle icons for any nested accordions. The state
|
* not modify toggle icons for any nested accordions. The state
|
||||||
@ -352,6 +347,9 @@ ion-accordion > [slot="content"] ion-item {
|
|||||||
--min-height: #{globals.$ion-scale-700};
|
--min-height: #{globals.$ion-scale-700};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Datetime Styles
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
// Safari/iOS 15 changes the appearance of input[type="date"].
|
// Safari/iOS 15 changes the appearance of input[type="date"].
|
||||||
// For backwards compatibility from Ionic 5/Safari 14 designs,
|
// For backwards compatibility from Ionic 5/Safari 14 designs,
|
||||||
// we override the appearance only when using within an ion-input.
|
// we override the appearance only when using within an ion-input.
|
||||||
@ -382,6 +380,9 @@ ion-input input::-webkit-date-and-time-value {
|
|||||||
min-height: 320px;
|
min-height: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Popover Styles
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a popover has a child ion-content (or class equivalent) then the .popover-viewport element
|
* If a popover has a child ion-content (or class equivalent) then the .popover-viewport element
|
||||||
* should not be scrollable to ensure the inner content does scroll. However, if the popover
|
* should not be scrollable to ensure the inner content does scroll. However, if the popover
|
||||||
|
@ -43,8 +43,11 @@ export const setContent = async (page: Page, html: string, testInfo: TestInfo, o
|
|||||||
<title>Ionic Playwright Test</title>
|
<title>Ionic Playwright Test</title>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
||||||
<link href="${baseUrl}/css/ionic.bundle.css" rel="stylesheet" />
|
${
|
||||||
${theme === 'ionic' ? `<link href="${baseUrl}/css/ionic/bundle.ionic.css" rel="stylesheet" />` : ''}
|
theme === 'ionic'
|
||||||
|
? `<link href="${baseUrl}/css/ionic/bundle.ionic.css" rel="stylesheet" />`
|
||||||
|
: `<link href="${baseUrl}/css/ionic.bundle.css" rel="stylesheet" />`
|
||||||
|
}
|
||||||
<link href="${baseUrl}/scripts/testing/styles.css" rel="stylesheet" />
|
<link href="${baseUrl}/scripts/testing/styles.css" rel="stylesheet" />
|
||||||
${palette !== 'light' ? `<link href="${baseUrl}/css/palettes/${palette}.always.css" rel="stylesheet" />` : ''}
|
${palette !== 'light' ? `<link href="${baseUrl}/css/palettes/${palette}.always.css" rel="stylesheet" />` : ''}
|
||||||
<script src="${baseUrl}/scripts/testing/scripts.js"></script>
|
<script src="${baseUrl}/scripts/testing/scripts.js"></script>
|
||||||
|