feat(toggle): component can be used outside of ion-item (#26357)

resolves #25570, resolves #23213

BREAKING CHANGE:

The `--background` and `--background-checked` variables have been renamed to `--track-background` and `--track-background-checked`, respectively.
This commit is contained in:
Liam DeBeasi
2022-11-29 12:54:31 -05:00
committed by GitHub
parent 0ca6fee1d7
commit c74901c973
293 changed files with 1719 additions and 221 deletions

View File

@@ -206,6 +206,8 @@ Developers using these components will need to migrate to using Swiper.js direct
- `ionChange` is no longer emitted when the `checked` property of `ion-toggle` is modified externally. `ionChange` is only emitted from user committed changes, such as clicking the toggle to set it on or off.
- The `--background` and `--background-checked` variables have been renamed to `--track-background` and `--track-background-checked`, respectively.
<h4 id="version-7x-virtual-scroll">Virtual Scroll</h4>
`ion-virtual-scroll` has been removed from Ionic.

View File

@@ -2247,13 +2247,13 @@ when programmatically changing the value of the `checked` property.
@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'mode', 'name', 'value']
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'justify', 'labelPlacement', 'mode', 'name', 'value']
})
@Component({
selector: 'ion-toggle',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'mode', 'name', 'value']
inputs: ['checked', 'color', 'disabled', 'enableOnOffLabels', 'justify', 'labelPlacement', 'mode', 'name', 'value']
})
export class IonToggle {
protected el: HTMLElement;

View File

@@ -1428,14 +1428,14 @@ ion-toggle,prop,checked,boolean,false,false,false
ion-toggle,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-toggle,prop,disabled,boolean,false,false,false
ion-toggle,prop,enableOnOffLabels,boolean | undefined,undefined,false,false
ion-toggle,prop,justify,"end" | "space-between" | "start",'space-between',false,false
ion-toggle,prop,labelPlacement,"end" | "fixed" | "start",'start',false,false
ion-toggle,prop,mode,"ios" | "md",undefined,false,false
ion-toggle,prop,name,string,this.inputId,false,false
ion-toggle,prop,value,null | string | undefined,'on',false,false
ion-toggle,event,ionBlur,void,true
ion-toggle,event,ionChange,ToggleChangeEventDetail<any>,true
ion-toggle,event,ionFocus,void,true
ion-toggle,css-prop,--background
ion-toggle,css-prop,--background-checked
ion-toggle,css-prop,--border-radius
ion-toggle,css-prop,--handle-background
ion-toggle,css-prop,--handle-background-checked
@@ -1446,6 +1446,8 @@ ion-toggle,css-prop,--handle-max-height
ion-toggle,css-prop,--handle-spacing
ion-toggle,css-prop,--handle-transition
ion-toggle,css-prop,--handle-width
ion-toggle,css-prop,--track-background
ion-toggle,css-prop,--track-background-checked
ion-toggle,part,handle
ion-toggle,part,track

View File

@@ -2994,6 +2994,14 @@ export namespace Components {
* Enables the on/off accessibility switch labels within the toggle.
*/
"enableOnOffLabels": boolean | undefined;
/**
* How to pack the label and toggle within a line. `'start'`: The label and toggle will appear on the left in LTR and on the right in RTL. `'end'`: The label and toggle will appear on the right in LTR and on the left in RTL. `'space-between'`: The label and toggle will appear on opposite ends of the line with space between the two elements.
*/
"justify": 'start' | 'end' | 'space-between';
/**
* Where to place the label relative to the input. `'start'`: The label will appear to the left of the toggle in LTR and to the right in RTL. `'end'`: The label will appear to the right of the toggle in LTR and to the left in RTL. `'fixed'`: The label has the same behavior as `'start'` except it also has a fixed width. Long text will be truncated with ellipses ("...").
*/
"labelPlacement": 'start' | 'end' | 'fixed';
/**
* The mode determines which platform styles to use.
*/
@@ -6990,6 +6998,14 @@ declare namespace LocalJSX {
* Enables the on/off accessibility switch labels within the toggle.
*/
"enableOnOffLabels"?: boolean | undefined;
/**
* How to pack the label and toggle within a line. `'start'`: The label and toggle will appear on the left in LTR and on the right in RTL. `'end'`: The label and toggle will appear on the right in LTR and on the left in RTL. `'space-between'`: The label and toggle will appear on opposite ends of the line with space between the two elements.
*/
"justify"?: 'start' | 'end' | 'space-between';
/**
* Where to place the label relative to the input. `'start'`: The label will appear to the left of the toggle in LTR and to the right in RTL. `'end'`: The label will appear to the right of the toggle in LTR and to the left in RTL. `'fixed'`: The label has the same behavior as `'start'` except it also has a fixed width. Long text will be truncated with ellipses ("...").
*/
"labelPlacement"?: 'start' | 'end' | 'fixed';
/**
* The mode determines which platform styles to use.
*/

View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Toggle - a11y</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 nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<body>
<main>
<h1>Toggle - a11y</h1>
<ion-toggle>my label</ion-toggle><br />
<ion-toggle aria-label="my aria label"></ion-toggle><br />
</main>
</body>
</html>

View File

@@ -0,0 +1,17 @@
import AxeBuilder from '@axe-core/playwright';
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('toggle: a11y', () => {
test.beforeEach(async ({ skip }) => {
skip.rtl();
skip.mode('md');
});
test('should not have accessibility violations', async ({ page }) => {
await page.goto(`/src/components/toggle/test/a11y`);
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
});

View File

@@ -20,124 +20,18 @@
<ion-toolbar>
<ion-title>Toggle - Basic</ion-title>
<ion-buttons slot="primary">
<ion-toggle aria-label="Toggle"></ion-toggle>
<ion-toggle aria-label="Enable Notifications"></ion-toggle>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content id="content">
<ion-list>
<ion-item>
<ion-label>Orange</ion-label>
<ion-toggle id="orange" slot="start" name="orange"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Apple</ion-label>
<ion-toggle slot="start" name="apple" checked></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Banana</ion-label>
<ion-toggle slot="start" name="banana" checked class="toggle-part"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Cherry, disabled</ion-label>
<ion-toggle slot="start" color="danger" name="cherry" disabled></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Grape, checked, disabled</ion-label>
<ion-toggle slot="start" id="grapeChecked" value="grape" name="grape" checked disabled></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Kiwi, (ionChange) Secondary color</ion-label>
<ion-toggle slot="start" color="secondary" (ionChange)="kiwiChange($event)"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Strawberry, (ionChange) checked="true"</ion-label>
<ion-toggle slot="start" color="light" (ionChange)="strawberryChange($event)" checked="true"></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Checkbox right, checked, really long text that should ellipsis</ion-label>
<ion-toggle slot="end" color="danger" checked></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Checkbox right side</ion-label>
<ion-toggle slot="end" checked></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Button w/ right side default icon, really long text that should ellipsis</ion-label>
<ion-icon name="information-circle" slot="end"></ion-icon>
</ion-item>
<ion-item>
<ion-label>Custom</ion-label>
<ion-toggle slot="start" style="--border-radius: 0px; --handle-border-radius: 0px" checked></ion-toggle>
</ion-item>
<ion-item>
<ion-label>Stop Immediate Event Propagation</ion-label>
<ion-toggle slot="start" checked id="eventPropagation"></ion-toggle>
</ion-item>
</ion-list>
<p aria-hidden="true" class="ion-text-center">
<ion-button onClick="toggleBoolean('grapeChecked', 'checked')" fill="outline" size="small"
>Grape Checked</ion-button
>
<ion-button onClick="toggleBoolean('grapeChecked', 'disabled')" fill="outline" size="small"
>Grape Disabled</ion-button
>
<ion-button onClick="printForm()" fill="outline" size="small">Print Form</ion-button>
</p>
<p>
<ion-toggle aria-label="Stand-alone toggle" id="standAloneChecked"></ion-toggle>
Stand-alone toggle:
<span id="standAloneCheckedSpan"></span>
</p>
<ion-content class="ion-padding">
<ion-toggle
>Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable Notifications
Enable Notifications Enable Notifications Enable Notifications Enable Notifications Enable
Notifications</ion-toggle
>
</ion-content>
<style>
.toggle-part.toggle-checked::part(handle) {
background: red;
}
.toggle-part.toggle-checked::part(track) {
background: purple;
}
.toggle-part::part(handle) {
background: green;
}
.toggle-part::part(track) {
background: hotpink;
}
</style>
<script>
function printForm(ev) {}
function toggleBoolean(id, prop) {
var el = document.getElementById(id);
var isTrue = el[prop] ? false : true;
el[prop] = isTrue;
}
document.getElementById('eventPropagation').addEventListener('click', (evt) => {
evt.stopImmediatePropagation();
console.log('clicked');
});
</script>
</ion-app>
</body>
</html>

View File

@@ -0,0 +1,25 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('toggle: color', () => {
test.beforeEach(({ skip }) => {
skip.rtl();
});
test('should apply color when checked', async ({ page }) => {
await page.setContent(`
<ion-toggle color="danger" checked="true">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(`toggle-color-checked-${page.getSnapshotSettings()}.png`);
});
test('should not apply color when unchecked', async ({ page }) => {
await page.setContent(`
<ion-toggle color="danger">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(`toggle-color-unchecked-${page.getSnapshotSettings()}.png`);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -188,83 +188,67 @@
<ion-content>
<ion-list>
<ion-item>
<ion-label>Unchecked</ion-label>
<ion-toggle slot="end" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" enable-on-off-labels="true">Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Checked</ion-label>
<ion-toggle slot="end" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" enable-on-off-labels="true" checked>Checked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Secondary Unchecked</ion-label>
<ion-toggle slot="end" color="secondary" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" color="secondary" enable-on-off-labels="true">Secondary Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Secondary Checked</ion-label>
<ion-toggle slot="end" color="secondary" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" color="secondary" enable-on-off-labels="true" checked>Secondary Checked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Success Unchecked</ion-label>
<ion-toggle slot="end" color="success" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" color="success" enable-on-off-labels="true">Success Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Success Checked</ion-label>
<ion-toggle slot="end" color="success" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" color="success" enable-on-off-labels="true" checked>Success Checked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Danger Unchecked</ion-label>
<ion-toggle slot="end" color="danger" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" color="danger" enable-on-off-labels="true">Danger Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Danger Checked</ion-label>
<ion-toggle slot="end" color="danger" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" color="danger" enable-on-off-labels="true" checked>Danger Checked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Tertiary Unchecked</ion-label>
<ion-toggle slot="end" color="tertiary" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" color="tertiary" enable-on-off-labels="true">Tertiary Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Tertiary Checked</ion-label>
<ion-toggle slot="end" color="tertiary" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" color="tertiary" enable-on-off-labels="true" checked>Tertiary Checked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Light Unchecked</ion-label>
<ion-toggle slot="end" color="light" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" color="light" enable-on-off-labels="true">Light Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Light Checked</ion-label>
<ion-toggle slot="end" color="light" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" color="light" enable-on-off-labels="true" checked>Light Checked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Medium Unchecked</ion-label>
<ion-toggle slot="end" color="medium" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" color="medium" enable-on-off-labels="true">Medium Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Medium Checked</ion-label>
<ion-toggle slot="end" color="medium" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" color="medium" enable-on-off-labels="true" checked>Medium Checked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Dark Unchecked</ion-label>
<ion-toggle slot="end" color="dark" enable-on-off-labels="true"></ion-toggle>
<ion-toggle slot="end" color="dark" enable-on-off-labels="true">Dark Unchecked</ion-toggle>
</ion-item>
<ion-item>
<ion-label>Dark Checked</ion-label>
<ion-toggle slot="end" color="dark" enable-on-off-labels="true" checked></ion-toggle>
<ion-toggle slot="end" color="dark" enable-on-off-labels="true" checked>Dark Checked</ion-toggle>
</ion-item>
</ion-list>
</ion-content>

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 226 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 213 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

After

Width:  |  Height:  |  Size: 234 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 213 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 188 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 173 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 225 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 213 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 231 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 213 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 185 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 177 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 177 KiB

View File

@@ -0,0 +1,140 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Toggle - Item</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>
<style>
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(250px, 1fr));
grid-row-gap: 20px;
grid-column-gap: 20px;
}
h2 {
font-size: 12px;
font-weight: normal;
color: #6f7378;
margin-top: 10px;
}
@media screen and (max-width: 800px) {
.grid {
grid-template-columns: 1fr;
padding: 0;
}
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Toggle - Item</ion-title>
</ion-toolbar>
</ion-header>
<ion-content id="content" class="ion-padding">
<h1>Placement Start</h1>
<div class="grid">
<div class="grid-item">
<h2>Justify Start</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="start" justify="start">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
<div class="grid-item">
<h2>Justify End</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="start" justify="end">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
<div class="grid-item">
<h2>Justify Space Between</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="start" justify="space-between">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
</div>
<h1>Placement End</h1>
<div class="grid">
<div class="grid-item">
<h2>Justify Start</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="end" justify="start">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
<div class="grid-item">
<h2>Justify End</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="end" justify="end">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
<div class="grid-item">
<h2>Justify Space Between</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="end" justify="space-between">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
</div>
<h1>Placement Fixed</h1>
<div class="grid">
<div class="grid-item">
<h2>Justify Start</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="fixed" justify="start">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
<div class="grid-item">
<h2>Justify End</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="fixed" justify="end">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
<div class="grid-item">
<h2>Justify Space Between</h2>
<ion-list>
<ion-item>
<ion-toggle label-placement="fixed" justify="space-between">Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
</div>
</div>
</ion-content>
</ion-app>
</body>
</html>

View File

@@ -0,0 +1,37 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('toggle: item', () => {
test('should render correctly in list', async ({ page }) => {
await page.setContent(`
<ion-list>
<ion-item>
<ion-toggle>Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
`);
const list = page.locator('ion-list');
expect(await list.screenshot()).toMatchSnapshot(`toggle-list-${page.getSnapshotSettings()}.png`);
});
test('should render correctly in inset list', async ({ page }) => {
await page.setContent(`
<ion-list inset="true">
<ion-item>
<ion-toggle>Enable Notifications</ion-toggle>
</ion-item>
</ion-list>
`);
const list = page.locator('ion-list');
expect(await list.screenshot()).toMatchSnapshot(`toggle-inset-list-${page.getSnapshotSettings()}.png`);
});
test('label should have correct contrast when used in an item', async ({ page, skip }) => {
skip.rtl();
await page.setContent(`
<ion-item color="primary">
<ion-toggle>Enable Notifications</ion-toggle>
</ion-item>
`);
const item = page.locator('ion-item');
expect(await item.screenshot()).toMatchSnapshot(`toggle-item-color-${page.getSnapshotSettings()}.png`);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Toggle - Label</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>
<style>
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(250px, 1fr));
grid-row-gap: 20px;
grid-column-gap: 20px;
}
h2 {
font-size: 12px;
font-weight: normal;
color: #6f7378;
margin-top: 10px;
}
@media screen and (max-width: 800px) {
.grid {
grid-template-columns: 1fr;
padding: 0;
}
}
ion-toggle {
width: 100%;
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Toggle - Label</ion-title>
</ion-toolbar>
</ion-header>
<ion-content id="content" class="ion-padding">
<h1>Placement Start</h1>
<div class="grid">
<div class="grid-item">
<h2>Justify Start</h2>
<ion-toggle label-placement="start" justify="start">Enable Notifications</ion-toggle>
</div>
<div class="grid-item">
<h2>Justify End</h2>
<ion-toggle label-placement="start" justify="end">Enable Notifications</ion-toggle>
</div>
<div class="grid-item">
<h2>Justify Space Between</h2>
<ion-toggle label-placement="start" justify="space-between">Enable Notifications</ion-toggle>
</div>
</div>
<h1>Placement End</h1>
<div class="grid">
<div class="grid-item">
<h2>Justify Start</h2>
<ion-toggle label-placement="end" justify="start">Enable Notifications</ion-toggle>
</div>
<div class="grid-item">
<h2>Justify End</h2>
<ion-toggle label-placement="end" justify="end">Enable Notifications</ion-toggle>
</div>
<div class="grid-item">
<h2>Justify Space Between</h2>
<ion-toggle label-placement="end" justify="space-between">Enable Notifications</ion-toggle>
</div>
</div>
<h1>Placement Fixed</h1>
<div class="grid">
<div class="grid-item">
<h2>Justify Start</h2>
<ion-toggle label-placement="fixed" justify="start">Enable Notifications</ion-toggle>
</div>
<div class="grid-item">
<h2>Justify End</h2>
<ion-toggle label-placement="fixed" justify="end">Enable Notifications</ion-toggle>
</div>
<div class="grid-item">
<h2>Justify Space Between</h2>
<ion-toggle label-placement="fixed" justify="space-between">Enable Notifications</ion-toggle>
</div>
</div>
</ion-content>
</ion-app>
</body>
</html>

View File

@@ -0,0 +1,120 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
/**
* By default ion-toggle only takes up
* as much space as it needs. Justification is
* used for when the toggle takes up the full
* line (such as in an ion-item). As a result,
* we set the width of the toggle so we can
* see the justification results.
*/
test.describe('toggle: label', () => {
test.describe('toggle: start placement', () => {
test('should render a start justification with label in the start position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="start" justify="start" style="width: 200px">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-start-justify-start-${page.getSnapshotSettings()}.png`
);
});
test('should render an end justification with label in the start position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="start" justify="end" style="width: 200px">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-start-justify-end-${page.getSnapshotSettings()}.png`
);
});
test('should render a space between justification with label in the start position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="start" justify="space-between" style="width: 200px">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-start-justify-space-between-${page.getSnapshotSettings()}.png`
);
});
});
test.describe('toggle: end placement', () => {
test('should render a start justification with label in the end position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="end" justify="start" style="width: 200px">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-end-justify-start-${page.getSnapshotSettings()}.png`
);
});
test('should render an end justification with label in the end position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="end" justify="end" style="width: 200px">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-end-justify-end-${page.getSnapshotSettings()}.png`
);
});
test('should render a space between justification with label in the end position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="end" justify="space-between" style="width: 200px">Label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-end-justify-space-between-${page.getSnapshotSettings()}.png`
);
});
});
test.describe('toggle: fixed placement', () => {
test('should render a start justification with label in the fixed position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="fixed" justify="start" style="width: 200px">This is a long label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-fixed-justify-start-${page.getSnapshotSettings()}.png`
);
});
test('should render an end justification with label in the fixed position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="fixed" justify="end" style="width: 200px">This is a long label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-fixed-justify-end-${page.getSnapshotSettings()}.png`
);
});
test('should render a space between justification with label in the fixed position', async ({ page }) => {
await page.setContent(`
<ion-toggle label-placement="fixed" justify="space-between" style="width: 200px">This is a long label</ion-toggle>
`);
const toggle = page.locator('ion-toggle');
expect(await toggle.screenshot()).toMatchSnapshot(
`toggle-label-fixed-justify-space-between-${page.getSnapshotSettings()}.png`
);
});
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Some files were not shown because too many files have changed in this diff Show More