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.
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
16
core/src/components.d.ts
vendored
@@ -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.
|
||||
*/
|
||||
|
||||
22
core/src/components/toggle/test/a11y/index.html
Normal 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>
|
||||
17
core/src/components/toggle/test/a11y/toggle.e2e.ts
Normal 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([]);
|
||||
});
|
||||
});
|
||||
@@ -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>
|
||||
|
||||
25
core/src/components/toggle/test/color/toggle.e2e.ts
Normal 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`);
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
@@ -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>
|
||||
|
||||
|
Before Width: | Height: | Size: 234 KiB After Width: | Height: | Size: 226 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 185 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 177 KiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 177 KiB |
140
core/src/components/toggle/test/item/index.html
Normal 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>
|
||||
37
core/src/components/toggle/test/item/label.e2e.ts
Normal 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`);
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 11 KiB |
108
core/src/components/toggle/test/label/index.html
Normal 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>
|
||||
120
core/src/components/toggle/test/label/toggle.e2e.ts
Normal 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`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 4.3 KiB |