Skip to content
Open
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
20 changes: 17 additions & 3 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 @@ -87,18 +88,24 @@ const DEFAULT_THEME = 'md';
* Values can be `light`, `dark`, `high-contrast`,
* or `high-contrast-dark`. Default to `light` for tests.
*/
const validPalettes = ['light', 'dark', 'high-contrast', 'high-contrast-dark'];
const validPalettes = [DEFAULT_PALETTE, '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;
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 +126,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 mode
if (paletteName === 'dark' && theme.palette?.dark) {
theme.palette.dark.enabled = 'always';
// TODO(FW-4005): Implement high contrast mode
} else if (paletteName === 'high-contrast' && theme.palette?.highContrast) {
theme.palette.highContrast.enabled = 'always';
// TODO(FW-4005): Implement high contrast dark mode
} else if (paletteName === 'high-contrast-dark' && theme.palette?.highContrastDark) {
theme.palette.highContrastDark.enabled = 'always';
Comment on lines +129 to +137
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can decide at the time of dark and high contrast implementation if this order makes sense.

}

// Apply the theme tokens to Ionic config
Expand Down
15 changes: 15 additions & 0 deletions core/src/components/modal/test/dark-mode/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,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