|
14 | 14 | * The following URL parameters are supported: |
15 | 15 | * - `rtl`: Set to `true` to enable right-to-left directionality. |
16 | 16 | * - `ionic:_testing`: Set to `true` to identify testing environments. |
17 | | - * - `ionic:mode`: Set to `ios` or `md` to load a specific mode. |
18 | | - * Defaults to `md`. |
| 17 | + * - `ionic:theme`: Set to `ionic`, `ios`, or `md` to load a specific |
| 18 | + * theme. Defaults to `md`. |
19 | 19 | * - `palette`: Set to `light`, `dark`, `high-contrast`, or |
20 | 20 | * `high-contrast-dark` to load a specific palette. Defaults to `light`. |
21 | 21 | */ |
22 | 22 |
|
23 | | -(function() { |
| 23 | +const DEFAULT_THEME = 'md'; |
24 | 24 |
|
| 25 | +(function() { |
| 26 | + |
25 | 27 | /** |
26 | 28 | * The `rtl` param is used to set the directionality of the |
27 | 29 | * document. This can be `true` or `false`. |
|
48 | 50 | document.head.appendChild(style); |
49 | 51 | } |
50 | 52 |
|
| 53 | + /** |
| 54 | + * The `theme` param is used to load a specific theme. |
| 55 | + * This can be `ionic`, `ios`, or `md`. Default to `md` for tests. |
| 56 | + */ |
| 57 | + const themeQuery = window.location.search.match(/ionic:theme=([a-z0-9]+)/i); |
| 58 | + const themeHash = window.location.hash.match(/ionic:theme=([a-z0-9]+)/i); |
| 59 | + const themeAttr = document.documentElement.getAttribute('theme'); |
| 60 | + const themeName = themeQuery?.[1] || themeHash?.[1] || themeAttr || DEFAULT_THEME; |
| 61 | + |
| 62 | + // TODO(): Remove this when the tokens are working for all components |
| 63 | + // and the themes all use the same bundle |
| 64 | + if ((themeQuery && themeQuery[1] === 'ionic') || themeAttr === 'ionic') { |
| 65 | + const ionicThemeLinkTag = document.querySelector('link[href*="css/ionic/bundle.ionic.css"]'); |
| 66 | + |
| 67 | + if (!ionicThemeLinkTag) { |
| 68 | + const linkTag = document.createElement('link'); |
| 69 | + linkTag.setAttribute('rel', 'stylesheet'); |
| 70 | + linkTag.setAttribute('type', 'text/css'); |
| 71 | + linkTag.setAttribute('href', '/css/ionic/bundle.ionic.css'); |
| 72 | + document.head.appendChild(linkTag); |
| 73 | + } |
| 74 | + |
| 75 | + const defaultThemeLinkTag = document.querySelector('link[href*="css/ionic.bundle.css"]'); |
| 76 | + if (defaultThemeLinkTag) { |
| 77 | + defaultThemeLinkTag.remove(); |
| 78 | + } |
| 79 | + } |
| 80 | + |
51 | 81 | /** |
52 | 82 | * The `palette` param is used to load a specific palette |
53 | 83 | * for the theme. |
|
63 | 93 |
|
64 | 94 | const paletteName = paletteQuery?.[1] || paletteHash?.[1] || darkClass || 'light'; |
65 | 95 |
|
66 | | - if (paletteName !== 'light') { |
67 | | - const linkTag = document.createElement('link'); |
68 | | - linkTag.setAttribute('rel', 'stylesheet'); |
69 | | - linkTag.setAttribute('type', 'text/css'); |
70 | | - linkTag.setAttribute('href', `/css/palettes/${paletteName}.always.css`); |
71 | | - document.head.appendChild(linkTag); |
| 96 | + // Load theme tokens if the theme is valid |
| 97 | + const validThemes = ['ionic', 'ios', 'md']; |
| 98 | + if (themeName && validThemes.includes(themeName)) { |
| 99 | + loadThemeTokens(themeName, paletteName); |
| 100 | + } else if(themeName) { |
| 101 | + console.warn( |
| 102 | + `Unsupported theme "${themeName}". Supported themes are: ${validThemes.join(', ')}. Defaulting to ${DEFAULT_THEME}.` |
| 103 | + ); |
72 | 104 | } |
73 | 105 |
|
74 | | - /** |
75 | | - * The `ionic` theme uses a different stylesheet than the `iOS` and `md` themes. |
76 | | - * This is to ensure that the `ionic` theme is loaded when the `ionic:theme=ionic` |
77 | | - * or when the HTML tag has the `theme="ionic"` attribute. This is useful for |
78 | | - * the snapshot tests, where the `ionic` theme is not loaded by default. |
79 | | - */ |
80 | | - const themeQuery = window.location.search.match(/ionic:theme=([a-z]+)/); |
81 | | - const themeAttr = document.documentElement.getAttribute('theme'); |
82 | | - |
83 | | - if ((themeQuery && themeQuery[1] === 'ionic') || themeAttr === 'ionic') { |
84 | | - const ionicThemeLinkTag = document.querySelector('link[href*="css/ionic/bundle.ionic.css"]'); |
| 106 | + async function loadThemeTokens(themeName, paletteName) { |
| 107 | + try { |
| 108 | + // Load the default tokens for the theme |
| 109 | + const defaultTokens = await import(`/themes/${themeName}/default.tokens.js`); |
| 110 | + const theme = defaultTokens.defaultTheme; |
85 | 111 |
|
86 | | - if (!ionicThemeLinkTag) { |
87 | | - const linkTag = document.createElement('link'); |
88 | | - linkTag.setAttribute('rel', 'stylesheet'); |
89 | | - linkTag.setAttribute('type', 'text/css'); |
90 | | - linkTag.setAttribute('href', '/css/ionic/bundle.ionic.css'); |
91 | | - document.head.appendChild(linkTag); |
92 | | - } |
| 112 | + // If a specific palette is requested, modify the palette structure |
| 113 | + // to set the enabled property to 'always' |
| 114 | + if (paletteName === 'dark' && theme.palette?.dark) { |
| 115 | + theme.palette.dark.enabled = 'always'; |
| 116 | + } |
93 | 117 |
|
94 | | - const utilsBundleLinkTag = document.querySelector('link[href*="css/utils.bundle.css"]'); |
95 | | - if (!utilsBundleLinkTag) { |
96 | | - const linkTag = document.createElement('link'); |
97 | | - linkTag.setAttribute('rel', 'stylesheet'); |
98 | | - linkTag.setAttribute('type', 'text/css'); |
99 | | - linkTag.setAttribute('href', '/css/utils.bundle.css'); |
100 | | - document.head.appendChild(linkTag); |
101 | | - } |
| 118 | + // Apply the theme tokens to Ionic config |
| 119 | + window.Ionic = window.Ionic || {}; |
| 120 | + window.Ionic.config = window.Ionic.config || {}; |
| 121 | + window.Ionic.config.customTheme = theme; |
102 | 122 |
|
103 | | - const defaultThemeLinkTag = document.querySelector('link[href*="css/ionic.bundle.css"]'); |
104 | | - if (defaultThemeLinkTag) { |
105 | | - defaultThemeLinkTag.remove(); |
| 123 | + // Re-apply the global theme |
| 124 | + if (window.Ionic.config.get && window.Ionic.config.set) { |
| 125 | + const themeModule = await import('/themes/utils/theme.js'); |
| 126 | + themeModule.applyGlobalTheme(theme); |
| 127 | + } |
| 128 | + } catch (error) { |
| 129 | + console.error(`Failed to load theme tokens for ${themeName}:`, error); |
106 | 130 | } |
107 | 131 | } |
108 | 132 |
|
|
0 commit comments