@ionic/core 7.6.2-dev.11704390532.1202188d → 7.6.2-dev.11704834200.17f5bc99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/action-sheet.js +1 -1
- package/components/alert.js +2 -2
- package/components/button.js +2 -2
- package/components/checkbox.js +2 -2
- package/components/ion-back-button.js +1 -1
- package/components/ion-badge.js +2 -2
- package/components/ion-content.js +2 -3
- package/components/ion-fab-button.js +2 -2
- package/components/ion-input.js +2 -2
- package/components/ion-item-option.js +2 -2
- package/components/ion-loading.js +1 -1
- package/components/ion-menu-button.js +1 -1
- package/components/ion-menu.js +6 -13
- package/components/ion-picker-legacy.js +2 -2
- package/components/ion-progress-bar.js +2 -2
- package/components/ion-range.js +2 -2
- package/components/ion-refresher-content.js +1 -1
- package/components/ion-refresher.js +1 -1
- package/components/ion-router-link.js +1 -1
- package/components/ion-searchbar.js +1 -1
- package/components/ion-segment-button.js +1 -1
- package/components/ion-select.js +2 -2
- package/components/ion-split-pane.js +40 -12
- package/components/ion-tab-bar.js +2 -2
- package/components/ion-textarea.js +2 -2
- package/components/ion-toast.js +2 -2
- package/components/ion-toggle.js +2 -2
- package/components/item.js +2 -2
- package/components/label.js +1 -1
- package/components/picker-column2.js +1 -1
- package/components/radio.js +2 -2
- package/components/select-popover.js +1 -1
- package/css/core.css +35 -34
- package/css/core.css.map +1 -1
- package/css/global.bundle.css +1 -1
- package/css/ionic.bundle.css +1 -1
- package/css/ionic.bundle.css.map +1 -1
- package/css/themes/dark.always.css +122 -0
- package/css/themes/dark.always.css.map +1 -0
- package/css/themes/dark.class.css +122 -0
- package/css/themes/dark.class.css.map +1 -0
- package/css/themes/dark.css +3 -0
- package/css/themes/dark.css.map +1 -0
- package/css/themes/dark.system.css +124 -0
- package/css/themes/dark.system.css.map +1 -0
- package/css/typography.css +1 -1
- package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
- package/dist/cjs/ion-alert.cjs.entry.js +2 -2
- package/dist/cjs/ion-app_8.cjs.entry.js +2 -3
- package/dist/cjs/ion-avatar_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-back-button.cjs.entry.js +1 -1
- package/dist/cjs/ion-button_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-checkbox.cjs.entry.js +2 -2
- package/dist/cjs/ion-datetime_3.cjs.entry.js +3 -3
- package/dist/cjs/ion-fab_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-input.cjs.entry.js +2 -2
- package/dist/cjs/ion-item-option_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-item_8.cjs.entry.js +3 -3
- package/dist/cjs/ion-loading.cjs.entry.js +1 -1
- package/dist/cjs/ion-menu_3.cjs.entry.js +7 -14
- package/dist/cjs/ion-progress-bar.cjs.entry.js +2 -2
- package/dist/cjs/ion-radio_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-range.cjs.entry.js +2 -2
- package/dist/cjs/ion-refresher_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-route_4.cjs.entry.js +1 -1
- package/dist/cjs/ion-searchbar.cjs.entry.js +1 -1
- package/dist/cjs/ion-segment_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-select_3.cjs.entry.js +3 -3
- package/dist/cjs/ion-split-pane.cjs.entry.js +37 -10
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-textarea.cjs.entry.js +2 -2
- package/dist/cjs/ion-toast.cjs.entry.js +2 -2
- package/dist/cjs/ion-toggle.cjs.entry.js +2 -2
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/action-sheet/action-sheet.ios.css +3 -3
- package/dist/collection/components/action-sheet/test/a11y/action-sheet.e2e.js +23 -14
- package/dist/collection/components/alert/alert.ios.css +6 -6
- package/dist/collection/components/alert/alert.md.css +6 -6
- package/dist/collection/components/alert/test/a11y/alert.e2e.js +22 -9
- package/dist/collection/components/back-button/back-button.ios.css +1 -1
- package/dist/collection/components/back-button/test/a11y/back-button.e2e.js +21 -0
- package/dist/collection/components/badge/badge.ios.css +1 -1
- package/dist/collection/components/badge/badge.md.css +1 -1
- package/dist/collection/components/badge/test/a11y/badge.e2e.js +18 -0
- package/dist/collection/components/button/button.ios.css +10 -10
- package/dist/collection/components/button/button.md.css +8 -8
- package/dist/collection/components/button/test/a11y/button.e2e.js +48 -0
- package/dist/collection/components/checkbox/checkbox.ios.css +2 -2
- package/dist/collection/components/checkbox/checkbox.md.css +2 -2
- package/dist/collection/components/checkbox/test/a11y/checkbox.e2e.js +11 -2
- package/dist/collection/components/content/content.js +2 -3
- package/dist/collection/components/fab-button/fab-button.ios.css +13 -13
- package/dist/collection/components/fab-button/fab-button.md.css +4 -4
- package/dist/collection/components/fab-button/test/a11y/fab-button.e2e.js +50 -0
- package/dist/collection/components/input/input.ios.css +3 -3
- package/dist/collection/components/input/input.md.css +3 -3
- package/dist/collection/components/input/test/a11y/input.e2e.js +41 -3
- package/dist/collection/components/item/item.ios.css +3 -3
- package/dist/collection/components/item/item.md.css +4 -4
- package/dist/collection/components/item-option/item-option.ios.css +2 -2
- package/dist/collection/components/item-option/item-option.md.css +1 -1
- package/dist/collection/components/item-sliding/test/a11y/item-sliding.e2e.js +28 -0
- package/dist/collection/components/label/label.md.css +1 -1
- package/dist/collection/components/label/test/a11y/label.e2e.js +20 -0
- package/dist/collection/components/loading/loading.md.css +1 -1
- package/dist/collection/components/loading/test/a11y/loading.e2e.js +21 -5
- package/dist/collection/components/menu/menu.ios.css +64 -3
- package/dist/collection/components/menu/menu.js +4 -11
- package/dist/collection/components/menu/menu.md.css +64 -3
- package/dist/collection/components/menu-button/menu-button.ios.css +1 -1
- package/dist/collection/components/menu-button/test/a11y/menu-button.e2e.js +14 -0
- package/dist/collection/components/picker-legacy/picker.ios.css +1 -1
- package/dist/collection/components/picker-legacy/picker.md.css +1 -1
- package/dist/collection/components/picker-legacy-column/picker-column.md.css +1 -1
- package/dist/collection/components/progress-bar/progress-bar.ios.css +2 -2
- package/dist/collection/components/progress-bar/progress-bar.md.css +2 -2
- package/dist/collection/components/progress-bar/test/a11y/progress-bar.e2e.js +24 -0
- package/dist/collection/components/radio/radio.ios.css +2 -2
- package/dist/collection/components/radio/radio.md.css +2 -2
- package/dist/collection/components/radio/test/a11y/radio.e2e.js +101 -68
- package/dist/collection/components/range/range.ios.css +1 -1
- package/dist/collection/components/range/range.md.css +3 -3
- package/dist/collection/components/range/test/a11y/range.e2e.js +18 -8
- package/dist/collection/components/refresher/refresher.md.css +2 -2
- package/dist/collection/components/refresher/test/a11y/refresher.e2e.js +25 -0
- package/dist/collection/components/refresher-content/refresher-content.js +1 -1
- package/dist/collection/components/router-link/router-link.css +1 -1
- package/dist/collection/components/router-link/test/a11y/router-link.e2e.js +23 -0
- package/dist/collection/components/searchbar/searchbar.ios.css +1 -1
- package/dist/collection/components/segment/test/a11y/segment.e2e.js +23 -0
- package/dist/collection/components/segment-button/segment-button.md.css +2 -2
- package/dist/collection/components/select/select.ios.css +3 -3
- package/dist/collection/components/select/select.md.css +3 -3
- package/dist/collection/components/select/test/a11y/select.e2e.js +68 -4
- package/dist/collection/components/select-popover/select-popover.md.css +4 -4
- package/dist/collection/components/select-popover/test/a11y/select-popover.e2e.js +32 -0
- package/dist/collection/components/split-pane/split-pane.ios.css +1 -53
- package/dist/collection/components/split-pane/split-pane.js +75 -8
- package/dist/collection/components/split-pane/split-pane.md.css +1 -53
- package/dist/collection/components/split-pane/test/wrapped-menu/split-pane.e2e.js +19 -0
- package/dist/collection/components/tab-bar/tab-bar.ios.css +1 -1
- package/dist/collection/components/tab-bar/tab-bar.md.css +1 -1
- package/dist/collection/components/textarea/test/a11y/textarea.e2e.js +41 -3
- package/dist/collection/components/textarea/textarea.ios.css +3 -3
- package/dist/collection/components/textarea/textarea.md.css +3 -3
- package/dist/collection/components/toast/test/a11y/toast.e2e.js +56 -24
- package/dist/collection/components/toast/toast.ios.css +1 -1
- package/dist/collection/components/toast/toast.md.css +2 -2
- package/dist/collection/components/toggle/test/a11y/toggle.e2e.js +8 -2
- package/dist/collection/components/toggle/toggle.ios.css +1 -1
- package/dist/collection/components/toggle/toggle.md.css +2 -2
- package/dist/collection/css/test/a11y/typography.e2e.js +18 -0
- package/dist/collection/themes/test/colors/theme.e2e.js +114 -0
- package/dist/collection/utils/test/playwright/generator.js +1 -0
- package/dist/collection/utils/test/playwright/page/utils/set-content.js +1 -1
- package/dist/docs.json +8 -2
- package/dist/esm/ion-action-sheet.entry.js +1 -1
- package/dist/esm/ion-alert.entry.js +2 -2
- package/dist/esm/ion-app_8.entry.js +2 -3
- package/dist/esm/ion-avatar_3.entry.js +2 -2
- package/dist/esm/ion-back-button.entry.js +1 -1
- package/dist/esm/ion-button_2.entry.js +2 -2
- package/dist/esm/ion-checkbox.entry.js +2 -2
- package/dist/esm/ion-datetime_3.entry.js +3 -3
- package/dist/esm/ion-fab_3.entry.js +2 -2
- package/dist/esm/ion-input.entry.js +2 -2
- package/dist/esm/ion-item-option_3.entry.js +2 -2
- package/dist/esm/ion-item_8.entry.js +3 -3
- package/dist/esm/ion-loading.entry.js +1 -1
- package/dist/esm/ion-menu_3.entry.js +7 -14
- package/dist/esm/ion-progress-bar.entry.js +2 -2
- package/dist/esm/ion-radio_2.entry.js +2 -2
- package/dist/esm/ion-range.entry.js +2 -2
- package/dist/esm/ion-refresher_2.entry.js +2 -2
- package/dist/esm/ion-route_4.entry.js +1 -1
- package/dist/esm/ion-searchbar.entry.js +1 -1
- package/dist/esm/ion-segment_2.entry.js +1 -1
- package/dist/esm/ion-select_3.entry.js +3 -3
- package/dist/esm/ion-split-pane.entry.js +37 -10
- package/dist/esm/ion-tab-bar_2.entry.js +2 -2
- package/dist/esm/ion-textarea.entry.js +2 -2
- package/dist/esm/ion-toast.entry.js +2 -2
- package/dist/esm/ion-toggle.entry.js +2 -2
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
- package/dist/esm-es5/ion-alert.entry.js +1 -1
- package/dist/esm-es5/ion-app_8.entry.js +1 -1
- package/dist/esm-es5/ion-avatar_3.entry.js +1 -1
- package/dist/esm-es5/ion-back-button.entry.js +1 -1
- package/dist/esm-es5/ion-button_2.entry.js +1 -1
- package/dist/esm-es5/ion-checkbox.entry.js +1 -1
- package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
- package/dist/esm-es5/ion-fab_3.entry.js +1 -1
- package/dist/esm-es5/ion-input.entry.js +1 -1
- package/dist/esm-es5/ion-item-option_3.entry.js +1 -1
- package/dist/esm-es5/ion-item_8.entry.js +1 -1
- package/dist/esm-es5/ion-loading.entry.js +1 -1
- package/dist/esm-es5/ion-menu_3.entry.js +1 -1
- package/dist/esm-es5/ion-progress-bar.entry.js +1 -1
- package/dist/esm-es5/ion-radio_2.entry.js +1 -1
- package/dist/esm-es5/ion-range.entry.js +1 -1
- package/dist/esm-es5/ion-refresher_2.entry.js +1 -1
- package/dist/esm-es5/ion-route_4.entry.js +1 -1
- package/dist/esm-es5/ion-searchbar.entry.js +1 -1
- package/dist/esm-es5/ion-segment_2.entry.js +1 -1
- package/dist/esm-es5/ion-select_3.entry.js +1 -1
- package/dist/esm-es5/ion-split-pane.entry.js +1 -1
- package/dist/esm-es5/ion-tab-bar_2.entry.js +1 -1
- package/dist/esm-es5/ion-textarea.entry.js +1 -1
- package/dist/esm-es5/ion-toast.entry.js +1 -1
- package/dist/esm-es5/ion-toggle.entry.js +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/{p-61e4d3ec.entry.js → p-068950da.entry.js} +1 -1
- package/dist/ionic/{p-80c6c078.entry.js → p-0832dedf.entry.js} +1 -1
- package/dist/ionic/p-19d9ceb8.system.js +1 -1
- package/dist/ionic/{p-a1bd098f.system.entry.js → p-1c453add.system.entry.js} +1 -1
- package/dist/ionic/{p-11bf2ad0.system.entry.js → p-1d5b03e3.system.entry.js} +1 -1
- package/dist/ionic/{p-92d35b6a.entry.js → p-2724403e.entry.js} +1 -1
- package/dist/ionic/p-283bc1a1.system.entry.js +4 -0
- package/dist/ionic/{p-abd5d0d5.system.entry.js → p-354682e8.system.entry.js} +1 -1
- package/dist/ionic/{p-19c379da.system.entry.js → p-3796194b.system.entry.js} +1 -1
- package/dist/ionic/{p-cf53213c.entry.js → p-385bb983.entry.js} +1 -1
- package/dist/ionic/{p-4793c14c.system.entry.js → p-456e19bb.system.entry.js} +1 -1
- package/dist/ionic/{p-77d78f68.system.entry.js → p-47e42aa3.system.entry.js} +1 -1
- package/dist/ionic/{p-529b24fb.entry.js → p-4abb1251.entry.js} +1 -1
- package/dist/ionic/{p-e2737fef.system.entry.js → p-530bb2af.system.entry.js} +1 -1
- package/dist/ionic/p-57f02351.entry.js +4 -0
- package/dist/ionic/{p-0e908476.system.entry.js → p-590447a5.system.entry.js} +1 -1
- package/dist/ionic/{p-642ac927.entry.js → p-5aec2208.entry.js} +1 -1
- package/dist/ionic/{p-26ff1180.entry.js → p-5cbfce20.entry.js} +1 -1
- package/dist/ionic/{p-26c4bf85.entry.js → p-5f1b0512.entry.js} +1 -1
- package/dist/ionic/{p-0dfa4ab4.system.entry.js → p-662a9a47.system.entry.js} +1 -1
- package/dist/ionic/{p-c01803db.entry.js → p-713af1fe.entry.js} +1 -1
- package/dist/ionic/{p-6e0539ea.system.entry.js → p-7dade589.system.entry.js} +1 -1
- package/dist/ionic/{p-6e4c7340.system.entry.js → p-8a25bf30.system.entry.js} +1 -1
- package/dist/ionic/{p-71483cbb.entry.js → p-8b160fba.entry.js} +1 -1
- package/dist/ionic/{p-799da666.entry.js → p-8e961825.entry.js} +1 -1
- package/dist/ionic/p-97aaf697.system.entry.js +4 -0
- package/dist/ionic/{p-4685218a.system.entry.js → p-9a8bc8f3.system.entry.js} +1 -1
- package/dist/ionic/{p-bb3fd397.entry.js → p-9c48f42f.entry.js} +1 -1
- package/dist/ionic/{p-964dcdb2.system.entry.js → p-9f94e34a.system.entry.js} +1 -1
- package/dist/ionic/{p-75a3e35b.entry.js → p-a17a9130.entry.js} +1 -1
- package/dist/ionic/{p-7dcf795f.entry.js → p-a29db3a0.entry.js} +1 -1
- package/dist/ionic/{p-8ce4e506.system.entry.js → p-a6e5f54e.system.entry.js} +1 -1
- package/dist/ionic/{p-6855f26a.entry.js → p-aa975ff8.entry.js} +1 -1
- package/dist/ionic/{p-043aa6cc.system.entry.js → p-b59fe3bd.system.entry.js} +1 -1
- package/dist/ionic/p-b7e03ff0.system.entry.js +4 -0
- package/dist/ionic/{p-ba5d9e27.entry.js → p-bc01c384.entry.js} +1 -1
- package/dist/ionic/{p-7be412e8.system.entry.js → p-c16fbc5f.system.entry.js} +1 -1
- package/dist/ionic/p-c4f9e650.system.entry.js +4 -0
- package/dist/ionic/{p-0cc80201.entry.js → p-c6e9ef77.entry.js} +1 -1
- package/dist/ionic/{p-db05ecb6.system.entry.js → p-cc700688.system.entry.js} +1 -1
- package/dist/ionic/p-cd3e1a06.entry.js +4 -0
- package/dist/ionic/{p-da666998.system.entry.js → p-d01449a3.system.entry.js} +1 -1
- package/dist/ionic/{p-84b567a6.entry.js → p-d08e0136.entry.js} +1 -1
- package/dist/ionic/p-d1ad57d5.system.entry.js +4 -0
- package/dist/ionic/p-d757eb10.entry.js +4 -0
- package/dist/ionic/{p-41208f54.system.entry.js → p-d88ed181.system.entry.js} +1 -1
- package/dist/ionic/{p-10339dcc.entry.js → p-df6f50ef.entry.js} +1 -1
- package/dist/ionic/{p-20755eb0.entry.js → p-e403ff07.entry.js} +1 -1
- package/dist/ionic/{p-ae4b7df8.entry.js → p-e9431a58.entry.js} +1 -1
- package/dist/ionic/p-ea6c3dd5.system.entry.js +4 -0
- package/dist/ionic/{p-f0dea903.system.entry.js → p-ec0a9b2c.system.entry.js} +1 -1
- package/dist/ionic/{p-b2b5d761.entry.js → p-ee8b825e.entry.js} +1 -1
- package/dist/ionic/{p-42925096.system.entry.js → p-f0dbd73e.system.entry.js} +1 -1
- package/dist/ionic/{p-806a9810.entry.js → p-f38c1f8d.entry.js} +1 -1
- package/dist/ionic/p-fc17f198.entry.js +4 -0
- package/dist/types/components/menu/menu.d.ts +1 -1
- package/dist/types/components/split-pane/split-pane.d.ts +26 -2
- package/dist/types/components.d.ts +1 -0
- package/hydrate/index.js +107 -72
- package/package.json +1 -1
- package/dist/ionic/p-2f449cdf.system.entry.js +0 -4
- package/dist/ionic/p-38531958.system.entry.js +0 -4
- package/dist/ionic/p-3b434dee.system.entry.js +0 -4
- package/dist/ionic/p-4981ea0a.system.entry.js +0 -4
- package/dist/ionic/p-950c05ad.entry.js +0 -4
- package/dist/ionic/p-a3013394.entry.js +0 -4
- package/dist/ionic/p-beed2450.system.entry.js +0 -4
- package/dist/ionic/p-beeed22c.system.entry.js +0 -4
- package/dist/ionic/p-ed8402d6.entry.js +0 -4
- package/dist/ionic/p-f8c5008f.entry.js +0 -4
|
@@ -1,8 +1,56 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
+
import AxeBuilder from "@axe-core/playwright";
|
|
4
5
|
import { expect } from "@playwright/test";
|
|
5
6
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
7
|
+
configs({ directions: ['ltr'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
8
|
+
test.describe(title('button: a11y for ion-color()'), () => {
|
|
9
|
+
test('should not have accessibility violations', async ({ page }) => {
|
|
10
|
+
await page.setContent(`
|
|
11
|
+
<ion-button>Default</ion-button>
|
|
12
|
+
<ion-button fill="solid">Solid</ion-button>
|
|
13
|
+
<ion-button fill="outline">Outline</ion-button>
|
|
14
|
+
<ion-button fill="clear">Clear</ion-button>
|
|
15
|
+
`, config);
|
|
16
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
17
|
+
expect(results.violations).toEqual([]);
|
|
18
|
+
});
|
|
19
|
+
test('focused state should not have accessibility violations', async ({ page }) => {
|
|
20
|
+
await page.setContent(`
|
|
21
|
+
<ion-button class="ion-focused" fill="solid">Solid</ion-button>
|
|
22
|
+
<ion-button class="ion-focused" fill="outline">Outline</ion-button>
|
|
23
|
+
<ion-button class="ion-focused" fill="clear">Clear</ion-button>
|
|
24
|
+
`, config);
|
|
25
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
26
|
+
expect(results.violations).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
test('button in toolbar should not have accessibility violations', async ({ page }) => {
|
|
29
|
+
await page.setContent(`
|
|
30
|
+
<ion-toolbar>
|
|
31
|
+
<ion-button fill="outline" class="ion-activated">Start</ion-button>
|
|
32
|
+
</ion-toolbar>
|
|
33
|
+
`, config);
|
|
34
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
35
|
+
expect(results.violations).toEqual([]);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Only ios mode uses ion-color() for the activated button state
|
|
41
|
+
*/
|
|
42
|
+
configs({ directions: ['ltr'], modes: ['ios'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
43
|
+
test.describe(title('button: ios contrast'), () => {
|
|
44
|
+
test('activated state should not have accessibility violations', async ({ page }) => {
|
|
45
|
+
await page.setContent(`
|
|
46
|
+
<ion-button class="ion-activated" fill="solid">Solid</ion-button>
|
|
47
|
+
<ion-button class="ion-activated" fill="outline">Outline</ion-button>
|
|
48
|
+
`, config);
|
|
49
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
50
|
+
expect(results.violations).toEqual([]);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
6
54
|
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
7
55
|
test.describe(title('button: font scaling'), () => {
|
|
8
56
|
test('should scale default button text on larger font sizes', async ({ page }) => {
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
* @prop --checkmark-color: Color of the checkbox checkmark when checked
|
|
72
72
|
* @prop --checkmark-width: Stroke width of the checkbox checkmark
|
|
73
73
|
*/
|
|
74
|
-
--checkbox-background-checked: var(--ion-color-primary, #
|
|
75
|
-
--border-color-checked: var(--ion-color-primary, #
|
|
74
|
+
--checkbox-background-checked: var(--ion-color-primary, #0054e9);
|
|
75
|
+
--border-color-checked: var(--ion-color-primary, #0054e9);
|
|
76
76
|
--checkmark-color: var(--ion-color-primary-contrast, #fff);
|
|
77
77
|
--checkmark-width: 1;
|
|
78
78
|
--transition: none;
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
* @prop --checkmark-color: Color of the checkbox checkmark when checked
|
|
72
72
|
* @prop --checkmark-width: Stroke width of the checkbox checkmark
|
|
73
73
|
*/
|
|
74
|
-
--checkbox-background-checked: var(--ion-color-primary, #
|
|
75
|
-
--border-color-checked: var(--ion-color-primary, #
|
|
74
|
+
--checkbox-background-checked: var(--ion-color-primary, #0054e9);
|
|
75
|
+
--border-color-checked: var(--ion-color-primary, #0054e9);
|
|
76
76
|
--checkmark-color: var(--ion-color-primary-contrast, #fff);
|
|
77
77
|
--checkmark-width: 1;
|
|
78
78
|
--transition: none;
|
|
@@ -4,10 +4,19 @@
|
|
|
4
4
|
import AxeBuilder from "@axe-core/playwright";
|
|
5
5
|
import { expect } from "@playwright/test";
|
|
6
6
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
7
|
-
configs({
|
|
7
|
+
configs({ directions: ['ltr'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
8
8
|
test.describe(title('checkbox: a11y'), () => {
|
|
9
9
|
test('should not have accessibility violations', async ({ page }) => {
|
|
10
|
-
await page.
|
|
10
|
+
await page.setContent(`
|
|
11
|
+
<main>
|
|
12
|
+
<ion-checkbox>Label</ion-checkbox>
|
|
13
|
+
<ion-checkbox aria-label="my aria label"></ion-checkbox>
|
|
14
|
+
<ion-checkbox checked="true">Checked</ion-checkbox>
|
|
15
|
+
<ion-item>
|
|
16
|
+
<ion-checkbox>Checkbox in item</ion-checkbox>
|
|
17
|
+
</ion-item>
|
|
18
|
+
</main>
|
|
19
|
+
`, config);
|
|
11
20
|
const results = await new AxeBuilder({ page }).analyze();
|
|
12
21
|
expect(results.violations).toEqual([]);
|
|
13
22
|
});
|
|
@@ -334,9 +334,8 @@ export class Content {
|
|
|
334
334
|
const mode = getIonMode(this);
|
|
335
335
|
const forceOverscroll = this.shouldForceOverscroll();
|
|
336
336
|
const transitionShadow = mode === 'ios';
|
|
337
|
-
const TagType = isMainContent ? 'main' : 'div';
|
|
338
337
|
this.resize();
|
|
339
|
-
return (h(Host, { class: createColorClasses(this.color, {
|
|
338
|
+
return (h(Host, { role: isMainContent ? 'main' : undefined, class: createColorClasses(this.color, {
|
|
340
339
|
[mode]: true,
|
|
341
340
|
'content-sizing': hostContext('ion-popover', this.el),
|
|
342
341
|
overscroll: forceOverscroll,
|
|
@@ -344,7 +343,7 @@ export class Content {
|
|
|
344
343
|
}), style: {
|
|
345
344
|
'--offset-top': `${this.cTop}px`,
|
|
346
345
|
'--offset-bottom': `${this.cBottom}px`,
|
|
347
|
-
} }, h("div", { ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), h(
|
|
346
|
+
} }, h("div", { ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), h("div", { class: {
|
|
348
347
|
'inner-scroll': true,
|
|
349
348
|
'scroll-x': scrollX,
|
|
350
349
|
'scroll-y': scrollY,
|
|
@@ -334,10 +334,10 @@ ion-ripple-effect {
|
|
|
334
334
|
* }
|
|
335
335
|
*/
|
|
336
336
|
:host {
|
|
337
|
-
--background: var(--ion-color-primary, #
|
|
338
|
-
--background-activated: var(--ion-color-primary-shade, #
|
|
339
|
-
--background-focused: var(--ion-color-primary-shade, #
|
|
340
|
-
--background-hover: var(--ion-color-primary-tint, #
|
|
337
|
+
--background: var(--ion-color-primary, #0054e9);
|
|
338
|
+
--background-activated: var(--ion-color-primary-shade, #004acd);
|
|
339
|
+
--background-focused: var(--ion-color-primary-shade, #004acd);
|
|
340
|
+
--background-hover: var(--ion-color-primary-tint, #1a65eb);
|
|
341
341
|
--background-activated-opacity: 1;
|
|
342
342
|
--background-focused-opacity: 1;
|
|
343
343
|
--background-hover-opacity: 1;
|
|
@@ -358,10 +358,10 @@ ion-ripple-effect {
|
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
:host(.fab-button-in-list) {
|
|
361
|
-
--background: var(--ion-color-light, #
|
|
362
|
-
--background-activated: var(--ion-color-light-shade, #
|
|
361
|
+
--background: var(--ion-color-light, #f6f8fc);
|
|
362
|
+
--background-activated: var(--ion-color-light-shade, #d8dade);
|
|
363
363
|
--background-focused: var(--background-activated);
|
|
364
|
-
--background-hover: var(--ion-color-light-tint, #
|
|
364
|
+
--background-hover: var(--ion-color-light-tint, #f7f9fc);
|
|
365
365
|
--color: var(--ion-color-light-contrast, #000);
|
|
366
366
|
--color-activated: var(--ion-color-light-contrast, #000);
|
|
367
367
|
--color-focused: var(--color-activated);
|
|
@@ -395,15 +395,15 @@ ion-ripple-effect {
|
|
|
395
395
|
}
|
|
396
396
|
@supports (backdrop-filter: blur(0)) {
|
|
397
397
|
:host(.fab-button-translucent) {
|
|
398
|
-
--background: rgba(var(--ion-color-primary-rgb,
|
|
399
|
-
--background-hover: rgba(var(--ion-color-primary-rgb,
|
|
400
|
-
--background-focused: rgba(var(--ion-color-primary-rgb,
|
|
398
|
+
--background: rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.9);
|
|
399
|
+
--background-hover: rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.8);
|
|
400
|
+
--background-focused: rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.82);
|
|
401
401
|
--backdrop-filter: saturate(180%) blur(20px);
|
|
402
402
|
}
|
|
403
403
|
:host(.fab-button-translucent-in-list) {
|
|
404
|
-
--background: rgba(var(--ion-color-light-rgb,
|
|
405
|
-
--background-hover: rgba(var(--ion-color-light-rgb,
|
|
406
|
-
--background-focused: rgba(var(--ion-color-light-rgb,
|
|
404
|
+
--background: rgba(var(--ion-color-light-rgb, 246, 248, 252), 0.9);
|
|
405
|
+
--background-hover: rgba(var(--ion-color-light-rgb, 246, 248, 252), 0.8);
|
|
406
|
+
--background-focused: rgba(var(--ion-color-light-rgb, 246, 248, 252), 0.82);
|
|
407
407
|
}
|
|
408
408
|
}
|
|
409
409
|
@supports (backdrop-filter: blur(0)) {
|
|
@@ -334,7 +334,7 @@ ion-ripple-effect {
|
|
|
334
334
|
* }
|
|
335
335
|
*/
|
|
336
336
|
:host {
|
|
337
|
-
--background: var(--ion-color-primary, #
|
|
337
|
+
--background: var(--ion-color-primary, #0054e9);
|
|
338
338
|
--background-activated: transparent;
|
|
339
339
|
--background-focused: currentColor;
|
|
340
340
|
--background-hover: currentColor;
|
|
@@ -359,10 +359,10 @@ ion-ripple-effect {
|
|
|
359
359
|
--color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);
|
|
360
360
|
--color-activated: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);
|
|
361
361
|
--color-focused: var(--color-activated);
|
|
362
|
-
--background: var(--ion-color-light, #
|
|
362
|
+
--background: var(--ion-color-light, #f6f8fc);
|
|
363
363
|
--background-activated: transparent;
|
|
364
|
-
--background-focused: var(--ion-color-light-shade, #
|
|
365
|
-
--background-hover: var(--ion-color-light-tint, #
|
|
364
|
+
--background-focused: var(--ion-color-light-shade, #d8dade);
|
|
365
|
+
--background-hover: var(--ion-color-light-tint, #f7f9fc);
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
:host(.fab-button-in-list) ::slotted(ion-icon) {
|
|
@@ -1,8 +1,58 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
+
import AxeBuilder from "@axe-core/playwright";
|
|
4
5
|
import { expect } from "@playwright/test";
|
|
5
6
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
7
|
+
configs({ directions: ['ltr'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
8
|
+
test.describe(title('fab-button: a11y'), () => {
|
|
9
|
+
test('should not have accessibility violations', async ({ page }) => {
|
|
10
|
+
await page.setContent(`
|
|
11
|
+
<ion-fab-button>FAB</ion-fab-button>
|
|
12
|
+
<ion-fab-button class="ion-activated">FAB</ion-fab-button>
|
|
13
|
+
`, config);
|
|
14
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
15
|
+
expect(results.violations).toEqual([]);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
test.describe(title('fab-list: contrast'), () => {
|
|
19
|
+
test('should not have accessibility violations', async ({ page }) => {
|
|
20
|
+
await page.setContent(`
|
|
21
|
+
<ion-fab activated="true">
|
|
22
|
+
<ion-fab-button>
|
|
23
|
+
Open
|
|
24
|
+
</ion-fab-button>
|
|
25
|
+
<ion-fab-list side="bottom">
|
|
26
|
+
<ion-fab-button>Down</ion-fab-button>
|
|
27
|
+
<ion-fab-button class="ion-activated">Down</ion-fab-button>
|
|
28
|
+
<ion-fab-button class="ion-focused">Down</ion-fab-button>
|
|
29
|
+
</ion-fab-list>
|
|
30
|
+
</ion-fab>
|
|
31
|
+
`, config);
|
|
32
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
33
|
+
expect(results.violations).toEqual([]);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
test.describe(title('fab: translucent contrast'), () => {
|
|
37
|
+
test('should not have accessibility violations', async ({ page }) => {
|
|
38
|
+
await page.setContent(`
|
|
39
|
+
<ion-fab-button translucent="true">FAB</ion-fab-button>
|
|
40
|
+
<ion-fab-button class="ion-focused" translucent="true">FAB</ion-fab-button>
|
|
41
|
+
<ion-fab activated="true">
|
|
42
|
+
<ion-fab-button>
|
|
43
|
+
Open
|
|
44
|
+
</ion-fab-button>
|
|
45
|
+
<ion-fab-list side="bottom">
|
|
46
|
+
<ion-fab-button translucent="true">Down</ion-fab-button>
|
|
47
|
+
<ion-fab-button class="ion-focused" translucent="true">Down</ion-fab-button>
|
|
48
|
+
</ion-fab-list>
|
|
49
|
+
</ion-fab>
|
|
50
|
+
`, config);
|
|
51
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
52
|
+
expect(results.violations).toEqual([]);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
6
56
|
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|
7
57
|
test.describe(title('fab-button: aria attributes'), () => {
|
|
8
58
|
test('should inherit aria attributes to inner button', async ({ page }) => {
|
|
@@ -89,9 +89,9 @@
|
|
|
89
89
|
--background: transparent;
|
|
90
90
|
--color: initial;
|
|
91
91
|
--border-style: solid;
|
|
92
|
-
--highlight-color-focused: var(--ion-color-primary, #
|
|
93
|
-
--highlight-color-valid: var(--ion-color-success, #
|
|
94
|
-
--highlight-color-invalid: var(--ion-color-danger, #
|
|
92
|
+
--highlight-color-focused: var(--ion-color-primary, #0054e9);
|
|
93
|
+
--highlight-color-valid: var(--ion-color-success, #2dd55b);
|
|
94
|
+
--highlight-color-invalid: var(--ion-color-danger, #c5000f);
|
|
95
95
|
/**
|
|
96
96
|
* This is a private API that is used to switch
|
|
97
97
|
* out the highlight color based on the state
|
|
@@ -89,9 +89,9 @@
|
|
|
89
89
|
--background: transparent;
|
|
90
90
|
--color: initial;
|
|
91
91
|
--border-style: solid;
|
|
92
|
-
--highlight-color-focused: var(--ion-color-primary, #
|
|
93
|
-
--highlight-color-valid: var(--ion-color-success, #
|
|
94
|
-
--highlight-color-invalid: var(--ion-color-danger, #
|
|
92
|
+
--highlight-color-focused: var(--ion-color-primary, #0054e9);
|
|
93
|
+
--highlight-color-valid: var(--ion-color-success, #2dd55b);
|
|
94
|
+
--highlight-color-invalid: var(--ion-color-danger, #c5000f);
|
|
95
95
|
/**
|
|
96
96
|
* This is a private API that is used to switch
|
|
97
97
|
* out the highlight color based on the state
|
|
@@ -4,14 +4,52 @@
|
|
|
4
4
|
import AxeBuilder from "@axe-core/playwright";
|
|
5
5
|
import { expect } from "@playwright/test";
|
|
6
6
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
7
|
-
configs({ directions: ['ltr'] }).forEach(({ title, config
|
|
7
|
+
configs({ directions: ['ltr'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
8
8
|
test.describe(title('input: a11y'), () => {
|
|
9
|
-
test('should not have accessibility violations', async ({ page }) => {
|
|
10
|
-
await page.
|
|
9
|
+
test('default layout should not have accessibility violations', async ({ page }) => {
|
|
10
|
+
await page.setContent(`
|
|
11
|
+
<main>
|
|
12
|
+
<ion-input label="Label" placeholder="Placeholder"></ion-input>
|
|
13
|
+
<ion-input placeholder="Placeholder">
|
|
14
|
+
<div slot="label">Label"></div>
|
|
15
|
+
</ion-input>
|
|
16
|
+
<ion-input label="Label" value="My Text"></ion-input>
|
|
17
|
+
<ion-input aria-label="Label"></ion-input>
|
|
18
|
+
<ion-input label="Email" fill="solid" value="hi@ionic.io">
|
|
19
|
+
<ion-icon slot="start" name="lock-closed" aria-hidden="true"></ion-icon>
|
|
20
|
+
<ion-button slot="end" aria-label="button">
|
|
21
|
+
<ion-icon slot="icon-only" name="lock-closed" aria-hidden="true"></ion-icon>
|
|
22
|
+
</ion-button>
|
|
23
|
+
</ion-input>
|
|
24
|
+
</main>
|
|
25
|
+
`, config);
|
|
26
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
27
|
+
expect(results.violations).toEqual([]);
|
|
28
|
+
});
|
|
29
|
+
test('focused state should not have accessibility violations', async ({ page }) => {
|
|
30
|
+
/**
|
|
31
|
+
* The primary color against the focus background
|
|
32
|
+
* when using fill="solid" does not meet AA
|
|
33
|
+
* contrast guidelines so it excluded from the test.
|
|
34
|
+
* The contrast here is a significant improvement
|
|
35
|
+
* over what Ionic has had in the past, so the team
|
|
36
|
+
* has decided that this tradeoff is acceptable since
|
|
37
|
+
* the scope of the problem is limited to the focus
|
|
38
|
+
* state with the primary color when fill="solid".
|
|
39
|
+
*/
|
|
40
|
+
await page.setContent(`
|
|
41
|
+
<main>
|
|
42
|
+
<ion-input class="has-focus" label="Label" value="My Text"></ion-input>
|
|
43
|
+
<ion-input class="has-focus" label-placement="floating" label="Label" value="My Text"></ion-input>
|
|
44
|
+
<ion-input class="has-focus" fill="outline" label-placement="floating" label="Label" value="My Text"></ion-input>
|
|
45
|
+
</main>
|
|
46
|
+
`, config);
|
|
11
47
|
const results = await new AxeBuilder({ page }).analyze();
|
|
12
48
|
expect(results.violations).toEqual([]);
|
|
13
49
|
});
|
|
14
50
|
});
|
|
51
|
+
});
|
|
52
|
+
configs({ directions: ['ltr'] }).forEach(({ title, config, screenshot }) => {
|
|
15
53
|
test.describe(title('input: font scaling'), () => {
|
|
16
54
|
test('should scale text on larger font sizes', async ({ page }) => {
|
|
17
55
|
await page.setContent(`
|
|
@@ -700,9 +700,9 @@ ion-ripple-effect {
|
|
|
700
700
|
--border-color: var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, #c8c7cc)));
|
|
701
701
|
--color: var(--ion-item-color, var(--ion-text-color, #000));
|
|
702
702
|
--highlight-height: 0px;
|
|
703
|
-
--highlight-color-focused: var(--ion-color-primary, #
|
|
704
|
-
--highlight-color-valid: var(--ion-color-success, #
|
|
705
|
-
--highlight-color-invalid: var(--ion-color-danger, #
|
|
703
|
+
--highlight-color-focused: var(--ion-color-primary, #0054e9);
|
|
704
|
+
--highlight-color-valid: var(--ion-color-success, #2dd55b);
|
|
705
|
+
--highlight-color-invalid: var(--ion-color-danger, #c5000f);
|
|
706
706
|
--bottom-padding-start: 0px;
|
|
707
707
|
font-size: 1rem;
|
|
708
708
|
}
|
|
@@ -800,9 +800,9 @@ ion-ripple-effect {
|
|
|
800
800
|
--inner-padding-end: 16px;
|
|
801
801
|
--inner-border-width: 0 0 1px 0;
|
|
802
802
|
--highlight-height: 1px;
|
|
803
|
-
--highlight-color-focused: var(--ion-color-primary, #
|
|
804
|
-
--highlight-color-valid: var(--ion-color-success, #
|
|
805
|
-
--highlight-color-invalid: var(--ion-color-danger, #
|
|
803
|
+
--highlight-color-focused: var(--ion-color-primary, #0054e9);
|
|
804
|
+
--highlight-color-valid: var(--ion-color-success, #2dd55b);
|
|
805
|
+
--highlight-color-invalid: var(--ion-color-danger, #c5000f);
|
|
806
806
|
font-size: 1rem;
|
|
807
807
|
font-weight: normal;
|
|
808
808
|
text-transform: none;
|
|
@@ -1100,7 +1100,7 @@ ion-ripple-effect {
|
|
|
1100
1100
|
:host(.ion-focused:not(.ion-color)) ::slotted(.label-floating),
|
|
1101
1101
|
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-stacked),
|
|
1102
1102
|
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating) {
|
|
1103
|
-
color: var(--ion-color-primary, #
|
|
1103
|
+
color: var(--ion-color-primary, #0054e9);
|
|
1104
1104
|
}
|
|
1105
1105
|
|
|
1106
1106
|
:host(.ion-color) {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
* @prop --background: Background of the item option
|
|
59
59
|
* @prop --color: Color of the item option
|
|
60
60
|
*/
|
|
61
|
-
--background: var(--ion-color-primary, #
|
|
61
|
+
--background: var(--ion-color-primary, #0054e9);
|
|
62
62
|
--color: var(--ion-color-primary-contrast, #fff);
|
|
63
63
|
background: var(--background);
|
|
64
64
|
color: var(--color);
|
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
:host(.ion-activated) {
|
|
237
|
-
background: var(--ion-color-primary-shade, #
|
|
237
|
+
background: var(--ion-color-primary-shade, #004acd);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
:host(.ion-color.ion-activated) {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
* @prop --background: Background of the item option
|
|
59
59
|
* @prop --color: Color of the item option
|
|
60
60
|
*/
|
|
61
|
-
--background: var(--ion-color-primary, #
|
|
61
|
+
--background: var(--ion-color-primary, #0054e9);
|
|
62
62
|
--color: var(--ion-color-primary-contrast, #fff);
|
|
63
63
|
background: var(--background);
|
|
64
64
|
color: var(--color);
|
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
+
import AxeBuilder from "@axe-core/playwright";
|
|
5
|
+
import { expect } from "@playwright/test";
|
|
4
6
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
5
7
|
import { testSlidingItem } from "../test.utils";
|
|
8
|
+
configs({ directions: ['ltr'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
9
|
+
test.describe(title('item-sliding: a11y for ion-color()'), () => {
|
|
10
|
+
test('should not have accessibility violations', async ({ page }) => {
|
|
11
|
+
await page.setContent(`
|
|
12
|
+
<main>
|
|
13
|
+
<ion-item-sliding id="axe">
|
|
14
|
+
<ion-item>
|
|
15
|
+
<ion-label>Sliding Item with End Options</ion-label>
|
|
16
|
+
</ion-item>
|
|
17
|
+
|
|
18
|
+
<ion-item-options>
|
|
19
|
+
<ion-item-option>Favorite</ion-item-option>
|
|
20
|
+
<ion-item-option class="ion-activated">Activated</ion-item-option>
|
|
21
|
+
</ion-item-options>
|
|
22
|
+
</ion-item-sliding>
|
|
23
|
+
</main>
|
|
24
|
+
`, config);
|
|
25
|
+
await page.locator(`#axe`).evaluate(async (el) => {
|
|
26
|
+
await el.open('end');
|
|
27
|
+
});
|
|
28
|
+
await page.waitForChanges();
|
|
29
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
30
|
+
expect(results.violations).toEqual([]);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
6
34
|
/**
|
|
7
35
|
* This behavior does not vary across directions
|
|
8
36
|
*/
|
|
@@ -348,7 +348,7 @@
|
|
|
348
348
|
:host-context(.ion-focused).label-floating:not(.ion-color),
|
|
349
349
|
:host-context(.item-has-focus).label-stacked:not(.ion-color),
|
|
350
350
|
:host-context(.item-has-focus).label-floating:not(.ion-color) {
|
|
351
|
-
color: var(--ion-color-primary, #
|
|
351
|
+
color: var(--ion-color-primary, #0054e9);
|
|
352
352
|
}
|
|
353
353
|
|
|
354
354
|
:host-context(.ion-focused.ion-color).label-stacked:not(.ion-color),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
+
import AxeBuilder from "@axe-core/playwright";
|
|
4
5
|
import { expect } from "@playwright/test";
|
|
5
6
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
6
7
|
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
@@ -64,6 +65,25 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
|
64
65
|
});
|
|
65
66
|
});
|
|
66
67
|
});
|
|
68
|
+
configs({ directions: ['ltr'], modes: ['md'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
69
|
+
test.describe(title('label: a11y for ion-color()'), () => {
|
|
70
|
+
test('should not have accessibility violations when focused', async ({ page }) => {
|
|
71
|
+
/**
|
|
72
|
+
* All page content should be contained by landmarks (main, nav, etc.)
|
|
73
|
+
* By containing the badge in a main element, we can avoid this violation.
|
|
74
|
+
*/
|
|
75
|
+
await page.setContent(`
|
|
76
|
+
<main>
|
|
77
|
+
<div class="ion-focused">
|
|
78
|
+
<ion-label position="stacked">Default Label</ion-label>
|
|
79
|
+
</div>
|
|
80
|
+
</main>
|
|
81
|
+
`, config);
|
|
82
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
83
|
+
expect(results.violations).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
67
87
|
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
68
88
|
test.describe(title('label: text wrapping in item'), () => {
|
|
69
89
|
test('long text should not cause label to expand infinitely', async ({ page }) => {
|
|
@@ -173,7 +173,7 @@ ion-spinner {
|
|
|
173
173
|
--background: var(--ion-color-step-50, #f2f2f2);
|
|
174
174
|
--max-width: 280px;
|
|
175
175
|
--max-height: 90%;
|
|
176
|
-
--spinner-color: var(--ion-color-primary, #
|
|
176
|
+
--spinner-color: var(--ion-color-primary, #0054e9);
|
|
177
177
|
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
|
|
178
178
|
color: var(--ion-color-step-850, #262626);
|
|
179
179
|
font-size: 0.875rem;
|
|
@@ -4,20 +4,36 @@
|
|
|
4
4
|
import AxeBuilder from "@axe-core/playwright";
|
|
5
5
|
import { expect } from "@playwright/test";
|
|
6
6
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
7
|
-
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|
7
|
+
configs({ modes: ['ios'], directions: ['ltr'], themes: ['light', 'dark'] }).forEach(({ title, config }) => {
|
|
8
8
|
test.describe(title('loading: a11y'), () => {
|
|
9
9
|
test('should set aria-labelledby with a message', async ({ page }) => {
|
|
10
|
-
await page.
|
|
10
|
+
await page.setContent(`
|
|
11
|
+
<ion-loading></ion-loading>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
const loading = document.querySelector('ion-loading');
|
|
15
|
+
loading.message = 'Loading';
|
|
16
|
+
</script>
|
|
17
|
+
`, config);
|
|
11
18
|
const ionLoadingDidPresent = await page.spyOnEvent('ionLoadingDidPresent');
|
|
12
|
-
|
|
19
|
+
const loading = page.locator('ion-loading');
|
|
20
|
+
await loading.evaluate((el) => el.present());
|
|
13
21
|
await ionLoadingDidPresent.next();
|
|
14
22
|
const results = await new AxeBuilder({ page }).analyze();
|
|
15
23
|
expect(results.violations).toEqual([]);
|
|
16
24
|
});
|
|
17
25
|
test('should set aria-labelledby with a label', async ({ page }) => {
|
|
18
|
-
await page.
|
|
26
|
+
await page.setContent(`
|
|
27
|
+
<ion-loading aria-label="Loading"></ion-loading>
|
|
28
|
+
|
|
29
|
+
<script>
|
|
30
|
+
const loading = document.querySelector('ion-loading');
|
|
31
|
+
loading.spinner = 'bubbles';
|
|
32
|
+
</script>
|
|
33
|
+
`, config);
|
|
19
34
|
const ionLoadingDidPresent = await page.spyOnEvent('ionLoadingDidPresent');
|
|
20
|
-
|
|
35
|
+
const loading = page.locator('ion-loading');
|
|
36
|
+
await loading.evaluate((el) => el.present());
|
|
21
37
|
await ionLoadingDidPresent.next();
|
|
22
38
|
const results = await new AxeBuilder({ page }).analyze();
|
|
23
39
|
expect(results.violations).toEqual([]);
|
|
@@ -295,10 +295,49 @@ ion-backdrop {
|
|
|
295
295
|
cursor: pointer;
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
+
/**
|
|
299
|
+
* The split pane styles for menu are defined
|
|
300
|
+
* in the menu stylesheets instead in the split pane
|
|
301
|
+
* stylesheets with ::slotted to allow for menus
|
|
302
|
+
* to be wrapped in custom components.
|
|
303
|
+
* If we used ::slotted to target the menu
|
|
304
|
+
* then menus wrapped in components would never
|
|
305
|
+
* receive these styles because they are not
|
|
306
|
+
* children of the split pane.
|
|
307
|
+
*/
|
|
308
|
+
/**
|
|
309
|
+
* Do not pass CSS Variables down on larger
|
|
310
|
+
* screens as we want them to affect the outer
|
|
311
|
+
* `ion-menu` rather than the inner content
|
|
312
|
+
*/
|
|
298
313
|
:host(.menu-pane-visible) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
314
|
+
flex: 0 1 auto;
|
|
315
|
+
width: var(--side-width, var(--width));
|
|
316
|
+
min-width: var(--side-min-width, var(--min-width));
|
|
317
|
+
max-width: var(--side-max-width, var(--max-width));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
:host(.menu-pane-visible.split-pane-side) {
|
|
321
|
+
left: 0;
|
|
322
|
+
right: 0;
|
|
323
|
+
top: 0;
|
|
324
|
+
bottom: 0;
|
|
325
|
+
position: relative;
|
|
326
|
+
box-shadow: none;
|
|
327
|
+
z-index: 0;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
:host(.menu-pane-visible.split-pane-side.menu-enabled) {
|
|
331
|
+
display: flex;
|
|
332
|
+
flex-shrink: 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
:host(.menu-pane-visible.split-pane-side) {
|
|
336
|
+
order: -1;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
:host(.menu-pane-visible.split-pane-side[side=end]) {
|
|
340
|
+
order: 1;
|
|
302
341
|
}
|
|
303
342
|
|
|
304
343
|
:host(.menu-pane-visible) .menu-inner {
|
|
@@ -375,4 +414,26 @@ ion-backdrop {
|
|
|
375
414
|
|
|
376
415
|
:host(.menu-type-push) .show-backdrop {
|
|
377
416
|
display: block;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
:host(.menu-pane-visible.split-pane-side) {
|
|
420
|
+
-webkit-border-start: 0;
|
|
421
|
+
border-inline-start: 0;
|
|
422
|
+
-webkit-border-end: var(--border);
|
|
423
|
+
border-inline-end: var(--border);
|
|
424
|
+
border-top: 0;
|
|
425
|
+
border-bottom: 0;
|
|
426
|
+
min-width: var(--side-min-width);
|
|
427
|
+
max-width: var(--side-max-width);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
:host(.menu-pane-visible.split-pane-side[side=end]) {
|
|
431
|
+
-webkit-border-start: var(--border);
|
|
432
|
+
border-inline-start: var(--border);
|
|
433
|
+
-webkit-border-end: 0;
|
|
434
|
+
border-inline-end: 0;
|
|
435
|
+
border-top: 0;
|
|
436
|
+
border-bottom: 0;
|
|
437
|
+
min-width: var(--side-min-width);
|
|
438
|
+
max-width: var(--side-max-width);
|
|
378
439
|
}
|
|
@@ -172,21 +172,14 @@ export class Menu {
|
|
|
172
172
|
this.animation = undefined;
|
|
173
173
|
this.contentEl = undefined;
|
|
174
174
|
}
|
|
175
|
-
onSplitPaneChanged(
|
|
176
|
-
const { target } = ev;
|
|
175
|
+
async onSplitPaneChanged() {
|
|
177
176
|
const closestSplitPane = this.el.closest('ion-split-pane');
|
|
178
|
-
|
|
179
|
-
* Menu listens on the body for "ionSplitPaneVisible".
|
|
180
|
-
* However, this means the callback will run any time
|
|
181
|
-
* a SplitPane changes visibility. As a result, we only want
|
|
182
|
-
* Menu's visibility state to update if its parent SplitPane
|
|
183
|
-
* changes visibility.
|
|
184
|
-
*/
|
|
185
|
-
if (target !== closestSplitPane) {
|
|
177
|
+
if (closestSplitPane === null) {
|
|
186
178
|
return;
|
|
187
179
|
}
|
|
188
|
-
this.isPaneVisible =
|
|
180
|
+
this.isPaneVisible = await closestSplitPane.isPane(this.el);
|
|
189
181
|
this.updateState();
|
|
182
|
+
this.menuChanged();
|
|
190
183
|
}
|
|
191
184
|
onBackdropClick(ev) {
|
|
192
185
|
// TODO(FW-2832): type (CustomEvent triggers errors which should be sorted)
|