Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions core/scripts/testing/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

const DEFAULT_THEME = 'md';
const DEFAULT_PALETTE = 'light';

(function() {

Expand Down Expand Up @@ -88,17 +89,33 @@ const DEFAULT_THEME = 'md';
* or `high-contrast-dark`. Default to `light` for tests.
*/
const validPalettes = ['light', 'dark', 'high-contrast', 'high-contrast-dark'];

const configDarkMode = window.Ionic?.config?.customTheme?.palette?.dark?.enabled === 'always' ? 'dark' : null;
const configHighContrastMode = window.Ionic?.config?.customTheme?.palette?.highContrast?.enabled === 'always' ? 'high-contrast' : null;
const configHighContrastDarkMode = window.Ionic?.config?.customTheme?.palette?.highContrastDark?.enabled === 'always' ? 'high-contrast-dark' : null;
/**
* Ensure window.Ionic.config is defined before importing 'testing/scripts'
* in the test HTML to properly initialize the palette configuration below.
*
* Example:
* <script>
* window.Ionic = { config: { customTheme: { palette: { ... } } } };
* </script>
* <script src="testing/scripts.js"></script>
*/
const configPalette = configDarkMode || configHighContrastMode || configHighContrastDarkMode;
const paletteQuery = window.location.search.match(/palette=([a-z-]+)/);
const paletteHash = window.location.hash.match(/palette=([a-z-]+)/);
const darkClass = document.body?.classList.contains('ion-palette-dark') ? 'dark' : null;
const highContrastClass = document.body?.classList.contains('ion-palette-high-contrast') ? 'high-contrast' : null;
const highContrastDarkClass = darkClass && highContrastClass ? 'high-contrast-dark' : null;
const paletteClass = highContrastDarkClass || highContrastClass || darkClass;

let paletteName = paletteQuery?.[1] || paletteHash?.[1] || highContrastDarkClass || darkClass || highContrastClass || 'light';
let paletteName = configPalette || paletteQuery?.[1] || paletteHash?.[1] || paletteClass || DEFAULT_PALETTE;

if (!validPalettes.includes(paletteName)) {
console.warn(`Invalid palette name: '${paletteName}'. Falling back to 'light' palette.`);
paletteName = 'light';
paletteName = DEFAULT_PALETTE;
}

// Load theme tokens if the theme is valid
Expand All @@ -119,8 +136,15 @@ const DEFAULT_THEME = 'md';

// If a specific palette is requested, modify the palette structure
// to set the enabled property to 'always'
// TODO(FW-4004): Implement dark palette
if (paletteName === 'dark' && theme.palette?.dark) {
theme.palette.dark.enabled = 'always';
// TODO(FW-4005): Implement high contrast palette
} else if (paletteName === 'high-contrast' && theme.palette?.highContrast) {
theme.palette.highContrast.enabled = 'always';
// TODO(FW-4005): Implement high contrast dark palette
} else if (paletteName === 'high-contrast-dark' && theme.palette?.highContrastDark) {
theme.palette.highContrastDark.enabled = 'always';
}

// Apply the theme tokens to Ionic config
Expand Down
17 changes: 17 additions & 0 deletions core/src/components/modal/test/dark-mode/index.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- TODO(FW-4004): Remove page and test it through the basic page tests -->

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
Expand All @@ -10,6 +12,21 @@
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../css/palettes/dark.always.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script>
// Need to be called before loading Ionic else
// the scripts.js logic runs too early.
window.Ionic = {
config: {
customTheme: {
palette: {
dark: {
enabled: 'always',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is meant to be always be in dark mode as stated in the file path.

},
},
},
},
};
</script>
<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>
Expand Down
3 changes: 2 additions & 1 deletion core/src/components/toast/test/a11y/toast.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
*/
configs({ directions: ['ltr'], palettes: ['high-contrast-dark', 'high-contrast'] }).forEach(
({ title, config, screenshot }) => {
test.describe(title('toast: high contrast: buttons'), () => {
// TODO(FW-4005): Once high contrast themes are fully implemented in ionic modular, remove the skips from these tests
test.describe.skip(title('toast: high contrast: buttons'), () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test fails because there are certain styles that are not available for toast. The point of this PR is to enable the palettes to work within tests and to not meddle with any components. Those styles should be reworked when we are fully implementing high contrast into the new theming structure.

test.beforeEach(async ({ page }) => {
await page.setContent(
`
Expand Down
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is the text color. The old version is showing #1f1f1f and the updated version is showing #000. The text color was not being displayed correctly until I updated the set-content file. If you compare the text color to next then you can verify that it should be #000.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is the text color. The old version is showing #1f1f1f and the updated version is showing #000. The text color was not being displayed correctly until I updated the set-content file. If you compare the text color to next then you can verify that it should be #000.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions core/src/themes/base/default.tokens.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { DefaultTheme } from '../themes.interfaces';

import { darkTheme } from './dark.tokens';
import { highContrastDarkTheme } from './high-contrast-dark.tokens';
import { highContrastTheme } from './high-contrast.tokens';
import { lightTheme } from './light.tokens';

export const defaultTheme: DefaultTheme = {
Expand All @@ -9,6 +11,8 @@ export const defaultTheme: DefaultTheme = {
palette: {
light: lightTheme,
dark: darkTheme,
highContrast: highContrastTheme,
highContrastDark: highContrastDarkTheme,
},

config: {
Expand Down
213 changes: 213 additions & 0 deletions core/src/themes/base/high-contrast-dark.tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import { mix } from '../../utils/theme';
import type { HighContrastDarkTheme } from '../themes.interfaces';

const colors = {
primary: '#7cabff',
secondary: '#62bdff',
tertiary: '#b6b9f9',
success: '#4ada71',
warning: '#ffce31',
danger: '#fc9aa2',
light: '#222428',
medium: '#a8aab3',
dark: '#f4f5f8',
};

export const highContrastDarkTheme: HighContrastDarkTheme = {
enabled: 'never',
color: {
primary: {
bold: {
base: colors.primary,
contrast: '#000',
foreground: colors.primary,
shade: mix(colors.primary, '#000', '12%'),
tint: mix(colors.primary, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.primary, '8%'),
contrast: colors.primary,
foreground: mix(colors.primary, '#000', '12%'),
shade: mix('#fff', colors.primary, '12%'),
tint: mix('#fff', colors.primary, '4%'),
},
},
secondary: {
bold: {
base: colors.secondary,
contrast: '#000',
foreground: colors.secondary,
shade: mix(colors.secondary, '#000', '12%'),
tint: mix(colors.secondary, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.secondary, '8%'),
contrast: colors.secondary,
foreground: mix(colors.secondary, '#000', '12%'),
shade: mix('#fff', colors.secondary, '12%'),
tint: mix('#fff', colors.secondary, '4%'),
},
},
tertiary: {
bold: {
base: colors.tertiary,
contrast: '#000',
foreground: colors.tertiary,
shade: mix(colors.tertiary, '#000', '12%'),
tint: mix(colors.tertiary, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.tertiary, '8%'),
contrast: colors.tertiary,
foreground: mix(colors.tertiary, '#000', '12%'),
shade: mix('#fff', colors.tertiary, '12%'),
tint: mix('#fff', colors.tertiary, '4%'),
},
},
success: {
bold: {
base: colors.success,
contrast: '#000',
foreground: colors.success,
shade: mix(colors.success, '#000', '12%'),
tint: mix(colors.success, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.success, '8%'),
contrast: colors.success,
foreground: mix(colors.success, '#000', '12%'),
shade: mix('#fff', colors.success, '12%'),
tint: mix('#fff', colors.success, '4%'),
},
},
warning: {
bold: {
base: colors.warning,
contrast: '#000',
foreground: colors.warning,
shade: mix(colors.warning, '#000', '12%'),
tint: mix(colors.warning, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.warning, '8%'),
contrast: colors.warning,
foreground: mix(colors.warning, '#000', '12%'),
shade: mix('#fff', colors.warning, '12%'),
tint: mix('#fff', colors.warning, '4%'),
},
},
danger: {
bold: {
base: colors.danger,
contrast: '#000',
foreground: colors.danger,
shade: mix(colors.danger, '#000', '12%'),
tint: mix(colors.danger, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.danger, '8%'),
contrast: colors.danger,
foreground: mix(colors.danger, '#000', '12%'),
shade: mix('#fff', colors.danger, '12%'),
tint: mix('#fff', colors.danger, '4%'),
},
},
light: {
bold: {
base: colors.light,
contrast: '#fff',
foreground: colors.light,
shade: mix(colors.light, '#000', '12%'),
tint: mix(colors.light, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.light, '8%'),
contrast: colors.light,
foreground: mix(colors.light, '#000', '12%'),
shade: mix('#fff', colors.light, '12%'),
tint: mix('#fff', colors.light, '4%'),
},
},
medium: {
bold: {
base: colors.medium,
contrast: '#000',
foreground: colors.medium,
shade: mix(colors.medium, '#000', '12%'),
tint: mix(colors.medium, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.medium, '8%'),
contrast: colors.medium,
foreground: mix(colors.medium, '#000', '12%'),
shade: mix('#fff', colors.medium, '12%'),
tint: mix('#fff', colors.medium, '4%'),
},
},
dark: {
bold: {
base: colors.dark,
contrast: '#000',
foreground: colors.dark,
shade: mix(colors.dark, '#000', '12%'),
tint: mix(colors.dark, '#fff', '10%'),
},
subtle: {
base: mix('#fff', colors.dark, '8%'),
contrast: colors.dark,
foreground: mix(colors.dark, '#000', '12%'),
shade: mix('#fff', colors.dark, '12%'),
tint: mix('#fff', colors.dark, '4%'),
},
},
},

backgroundColor: '#000000',
backgroundColorRgb: '0, 0, 0',
textColor: '#ffffff',
textColorRgb: '255, 255, 255',

backgroundColorStep: {
50: '#0d0d0d',
100: '#1a1a1a',
150: '#262626',
200: '#333333',
250: '#404040',
300: '#4d4d4d',
350: '#595959',
400: '#666666',
450: '#737373',
500: '#808080',
550: '#8c8c8c',
600: '#999999',
650: '#a6a6a6',
700: '#b3b3b3',
750: '#bfbfbf',
800: '#cccccc',
850: '#d9d9d9',
900: '#e6e6e6',
950: '#f2f2f2',
},

textColorStep: {
50: '#f9f9f9',
100: '#f3f3f3',
150: '#ededed',
200: '#e7e7e7',
250: '#e1e1e1',
300: '#dbdbdb',
350: '#d5d5d5',
400: '#cfcfcf',
450: '#c9c9c9',
500: '#c4c4c4',
550: '#bebebe',
600: '#b8b8b8',
650: '#b2b2b2',
700: '#acacac',
750: '#a6a6a6',
800: '#a0a0a0',
850: '#9a9a9a',
900: '#949494',
950: '#8e8e8e',
},
};
Loading
Loading