@atlaskit/tokens 1.13.1 → 1.14.0

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/custom-theme.js +17 -13
  3. package/dist/cjs/get-global-theme.js +4 -3
  4. package/dist/cjs/get-ssr-auto-script.js +21 -0
  5. package/dist/cjs/get-theme-html-attrs.js +76 -0
  6. package/dist/cjs/get-theme-styles.js +139 -0
  7. package/dist/cjs/get-token-value.js +1 -1
  8. package/dist/cjs/get-token.js +1 -1
  9. package/dist/cjs/index.js +15 -15
  10. package/dist/cjs/set-global-theme.js +9 -242
  11. package/dist/cjs/theme-config.js +23 -1
  12. package/dist/cjs/theme-mutation-observer.js +4 -4
  13. package/dist/cjs/{utils/theme-state-transformer.js → theme-state-transformer.js} +21 -3
  14. package/dist/cjs/use-theme-observer.js +7 -6
  15. package/dist/cjs/utils/get-theme-preferences.js +35 -0
  16. package/dist/cjs/utils/theme-loading.js +4 -2
  17. package/dist/cjs/version.json +1 -1
  18. package/dist/es2019/custom-theme.js +10 -10
  19. package/dist/es2019/get-global-theme.js +4 -3
  20. package/dist/es2019/get-ssr-auto-script.js +23 -0
  21. package/dist/es2019/get-theme-html-attrs.js +62 -0
  22. package/dist/es2019/get-theme-styles.js +72 -0
  23. package/dist/es2019/get-token-value.js +1 -1
  24. package/dist/es2019/get-token.js +1 -1
  25. package/dist/es2019/index.js +9 -6
  26. package/dist/es2019/set-global-theme.js +5 -185
  27. package/dist/es2019/theme-config.js +21 -0
  28. package/dist/es2019/theme-mutation-observer.js +2 -2
  29. package/dist/es2019/{utils/theme-state-transformer.js → theme-state-transformer.js} +22 -5
  30. package/dist/es2019/use-theme-observer.js +5 -4
  31. package/dist/es2019/utils/get-theme-preferences.js +28 -0
  32. package/dist/es2019/utils/theme-loading.js +2 -1
  33. package/dist/es2019/version.json +1 -1
  34. package/dist/esm/custom-theme.js +15 -11
  35. package/dist/esm/get-global-theme.js +4 -3
  36. package/dist/esm/get-ssr-auto-script.js +15 -0
  37. package/dist/esm/get-theme-html-attrs.js +68 -0
  38. package/dist/esm/get-theme-styles.js +126 -0
  39. package/dist/esm/get-token-value.js +1 -1
  40. package/dist/esm/get-token.js +1 -1
  41. package/dist/esm/index.js +9 -6
  42. package/dist/esm/set-global-theme.js +6 -233
  43. package/dist/esm/theme-config.js +21 -0
  44. package/dist/esm/theme-mutation-observer.js +4 -3
  45. package/dist/esm/{utils/theme-state-transformer.js → theme-state-transformer.js} +21 -3
  46. package/dist/esm/use-theme-observer.js +5 -4
  47. package/dist/esm/utils/get-theme-preferences.js +27 -0
  48. package/dist/esm/utils/theme-loading.js +2 -1
  49. package/dist/esm/version.json +1 -1
  50. package/dist/types/custom-theme.d.ts +4 -9
  51. package/dist/types/get-global-theme.d.ts +2 -1
  52. package/dist/types/get-ssr-auto-script.d.ts +11 -0
  53. package/dist/types/get-theme-html-attrs.d.ts +17 -0
  54. package/dist/types/get-theme-styles.d.ts +24 -0
  55. package/dist/types/index.d.ts +10 -9
  56. package/dist/types/set-global-theme.d.ts +1 -58
  57. package/dist/types/theme-config.d.ts +24 -0
  58. package/dist/types/theme-mutation-observer.d.ts +1 -1
  59. package/dist/{types-ts4.5/utils → types}/theme-state-transformer.d.ts +1 -1
  60. package/dist/types/use-theme-observer.d.ts +2 -1
  61. package/dist/types/utils/custom-theme-loading-utils.d.ts +2 -3
  62. package/dist/types/utils/generate-custom-color-ramp.d.ts +1 -2
  63. package/dist/types/utils/get-theme-preferences.d.ts +2 -0
  64. package/dist/types/utils/theme-loading.d.ts +1 -0
  65. package/dist/types-ts4.5/custom-theme.d.ts +4 -9
  66. package/dist/types-ts4.5/get-global-theme.d.ts +2 -1
  67. package/dist/types-ts4.5/get-ssr-auto-script.d.ts +11 -0
  68. package/dist/types-ts4.5/get-theme-html-attrs.d.ts +17 -0
  69. package/dist/types-ts4.5/get-theme-styles.d.ts +24 -0
  70. package/dist/types-ts4.5/index.d.ts +10 -9
  71. package/dist/types-ts4.5/set-global-theme.d.ts +1 -58
  72. package/dist/types-ts4.5/theme-config.d.ts +24 -0
  73. package/dist/types-ts4.5/theme-mutation-observer.d.ts +1 -1
  74. package/dist/{types/utils → types-ts4.5}/theme-state-transformer.d.ts +1 -1
  75. package/dist/types-ts4.5/use-theme-observer.d.ts +2 -1
  76. package/dist/types-ts4.5/utils/custom-theme-loading-utils.d.ts +2 -3
  77. package/dist/types-ts4.5/utils/generate-custom-color-ramp.d.ts +1 -2
  78. package/dist/types-ts4.5/utils/get-theme-preferences.d.ts +2 -0
  79. package/dist/types-ts4.5/utils/theme-loading.d.ts +1 -0
  80. package/package.json +1 -1
  81. package/report.api.md +8 -8
  82. package/tmp/api-report-tmp.d.ts +1158 -0
@@ -0,0 +1,62 @@
1
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
2
+ import { COLOR_MODE_ATTRIBUTE, CUSTOM_THEME_ATTRIBUTE, THEME_DATA_ATTRIBUTE } from './constants';
3
+ import { themeStateDefaults } from './theme-config';
4
+ import { themeObjectToString } from './theme-state-transformer';
5
+ import { isValidBrandHex } from './utils/color-utils';
6
+ import { hash } from './utils/hash';
7
+ const defaultColorMode = 'light';
8
+
9
+ /**
10
+ * Server-side rendering utility. Generates the valid HTML attributes for a given theme.
11
+ * Note: this utility does not handle automatic theme switching.
12
+ *
13
+ * @param {Object<string, string>} themeOptions - Theme options object
14
+ * @param {string} themeState.colorMode Determines which color theme is applied. If set to `auto`, the theme applied will be determined by the OS setting.
15
+ * @param {string} themeState.dark The color theme to be applied when the color mode resolves to 'dark'.
16
+ * @param {string} themeState.light The color theme to be applied when the color mode resolves to 'light'.
17
+ * @param {string} themeState.spacing The spacing theme to be applied.
18
+ * @param {string} themeState.typography The typography theme to be applied.
19
+ * @param {Object} themeState.UNSAFE_themeOptions The custom branding options to be used for custom theme generation
20
+ *
21
+ * @returns {Object} Object of HTML attributes to be applied to the document root
22
+ */
23
+ const getThemeHtmlAttrs = ({
24
+ colorMode = themeStateDefaults['colorMode'],
25
+ dark = themeStateDefaults['dark'],
26
+ light = themeStateDefaults['light'],
27
+ shape = themeStateDefaults['shape'],
28
+ spacing = themeStateDefaults['spacing'],
29
+ typography = themeStateDefaults['typography'],
30
+ UNSAFE_themeOptions = themeStateDefaults['UNSAFE_themeOptions']
31
+ } = {}) => {
32
+ let themePreferences = {
33
+ dark,
34
+ light,
35
+ shape,
36
+ spacing,
37
+ typography
38
+ };
39
+
40
+ // Load spacing by default, currently behind a feature flag
41
+ if (getBooleanFF('platform.design-system-team.space-and-shape-tokens_q5me6')) {
42
+ themePreferences = {
43
+ dark,
44
+ light,
45
+ shape,
46
+ spacing: 'spacing',
47
+ typography
48
+ };
49
+ }
50
+ const themeAttribute = themeObjectToString(themePreferences);
51
+ const result = {
52
+ [THEME_DATA_ATTRIBUTE]: themeAttribute,
53
+ [COLOR_MODE_ATTRIBUTE]: colorMode === 'auto' ? defaultColorMode : colorMode
54
+ };
55
+ if (UNSAFE_themeOptions && isValidBrandHex(UNSAFE_themeOptions.brandColor)) {
56
+ const optionString = JSON.stringify(UNSAFE_themeOptions);
57
+ const uniqueId = hash(optionString);
58
+ result[CUSTOM_THEME_ATTRIBUTE] = uniqueId;
59
+ }
60
+ return result;
61
+ };
62
+ export default getThemeHtmlAttrs;
@@ -0,0 +1,72 @@
1
+ import { themeIdsWithOverrides, themeStateDefaults } from './theme-config';
2
+ import { isValidBrandHex } from './utils/color-utils';
3
+ import { getThemePreferences } from './utils/get-theme-preferences';
4
+ import { loadThemeCss } from './utils/theme-loading';
5
+ /**
6
+ * Takes an object containing theme preferences, and returns an array of objects for use in applying styles to the document head.
7
+ * Only supplies the color themes necessary for initial render, based on the current themeState. I.e. if in light mode, dark mode themes are not returned.
8
+ *
9
+ * @param {Object<string, string>} themeState The themes and color mode that should be applied.
10
+ * @param {string} themeState.colorMode Determines which color theme is applied. If set to `auto`, the theme applied will be determined by the OS setting.
11
+ * @param {string} themeState.dark The color theme to be applied when the color mode resolves to 'dark'.
12
+ * @param {string} themeState.light The color theme to be applied when the color mode resolves to 'light'.
13
+ * @param {string} themeState.shape The shape theme to be applied.
14
+ * @param {string} themeState.spacing The spacing theme to be applied.
15
+ * @param {string} themeState.typography The typography theme to be applied.
16
+ * @param {Object} themeState.UNSAFE_themeOptions The custom branding options to be used for custom theme generation
17
+ *
18
+ * @returns A Promise of an object array, containing theme IDs, data-attributes to attach to the theme, and the theme CSS.
19
+ * If an error is encountered while loading themes, the themes array will be empty.
20
+ */
21
+ const getThemeStyles = async preferences => {
22
+ let themePreferences;
23
+ if (preferences === 'all') {
24
+ themePreferences = themeIdsWithOverrides;
25
+ } else {
26
+ themePreferences = getThemePreferences({
27
+ colorMode: (preferences === null || preferences === void 0 ? void 0 : preferences.colorMode) || themeStateDefaults['colorMode'],
28
+ dark: (preferences === null || preferences === void 0 ? void 0 : preferences.dark) || themeStateDefaults['dark'],
29
+ light: (preferences === null || preferences === void 0 ? void 0 : preferences.light) || themeStateDefaults['light'],
30
+ shape: (preferences === null || preferences === void 0 ? void 0 : preferences.shape) || themeStateDefaults['shape'],
31
+ spacing: (preferences === null || preferences === void 0 ? void 0 : preferences.spacing) || themeStateDefaults['spacing'],
32
+ typography: (preferences === null || preferences === void 0 ? void 0 : preferences.typography) || themeStateDefaults['typography']
33
+ });
34
+ }
35
+ const results = await Promise.all([...themePreferences.map(async themeId => {
36
+ try {
37
+ const css = await loadThemeCss(themeId);
38
+ return {
39
+ id: themeId,
40
+ attrs: {
41
+ 'data-theme': themeId
42
+ },
43
+ css
44
+ };
45
+ } catch {
46
+ // Return undefined if there's an error loading it, will be filtered out later.
47
+ return undefined;
48
+ }
49
+ }),
50
+ // Add custom themes if they're present
51
+ (async () => {
52
+ var _preferences$UNSAFE_t;
53
+ if (preferences !== 'all' && preferences !== null && preferences !== void 0 && preferences.UNSAFE_themeOptions && isValidBrandHex(preferences === null || preferences === void 0 ? void 0 : (_preferences$UNSAFE_t = preferences.UNSAFE_themeOptions) === null || _preferences$UNSAFE_t === void 0 ? void 0 : _preferences$UNSAFE_t.brandColor)) {
54
+ try {
55
+ const {
56
+ getCustomThemeStyles
57
+ } = await import( /* webpackChunkName: "@atlaskit-internal_atlassian-custom-theme" */
58
+ './custom-theme');
59
+ const customThemeStyles = await getCustomThemeStyles({
60
+ colorMode: (preferences === null || preferences === void 0 ? void 0 : preferences.colorMode) || themeStateDefaults['colorMode'],
61
+ UNSAFE_themeOptions: preferences === null || preferences === void 0 ? void 0 : preferences.UNSAFE_themeOptions
62
+ });
63
+ return customThemeStyles;
64
+ } catch {
65
+ // Return undefined if there's an error loading it, will be filtered out later.
66
+ return undefined;
67
+ }
68
+ }
69
+ })()]);
70
+ return results.flat().filter(theme => theme !== undefined);
71
+ };
72
+ export default getThemeStyles;
@@ -1,7 +1,7 @@
1
1
  import warnOnce from '@atlaskit/ds-lib/warn-once';
2
2
  import tokens from './artifacts/token-names';
3
3
  const name = "@atlaskit/tokens";
4
- const version = "1.13.1";
4
+ const version = "1.14.0";
5
5
  /**
6
6
  * Takes a dot-separated token name and and an optional fallback, and returns the current computed CSS value for the
7
7
  * resulting CSS Custom Property.
@@ -2,7 +2,7 @@ import warnOnce from '@atlaskit/ds-lib/warn-once';
2
2
  import tokens from './artifacts/token-names';
3
3
  import { TOKEN_NOT_FOUND_CSS_VAR } from './constants';
4
4
  const name = "@atlaskit/tokens";
5
- const version = "1.13.1";
5
+ const version = "1.14.0";
6
6
  /**
7
7
  * Takes a dot-separated token name and an optional fallback, and returns the CSS custom property for the corresponding token.
8
8
  * This should be used to implement design decisions throughout your application.
@@ -1,8 +1,11 @@
1
+ export { default as themeConfig } from './theme-config';
1
2
  export { default as token } from './get-token';
2
3
  export { default as getTokenValue } from './get-token-value';
3
- export { default as setGlobalTheme, getThemeStyles, getThemeHtmlAttrs, getSSRAutoScript } from './set-global-theme';
4
- export { default as themeConfig } from './theme-config';
5
- export { useThemeObserver } from './use-theme-observer';
6
- export { ThemeMutationObserver } from './theme-mutation-observer';
7
- export { getGlobalTheme } from './get-global-theme';
8
- export { themeStringToObject, themeObjectToString } from './utils/theme-state-transformer';
4
+ export { default as setGlobalTheme } from './set-global-theme';
5
+ export { default as getThemeStyles } from './get-theme-styles';
6
+ export { default as getThemeHtmlAttrs } from './get-theme-html-attrs';
7
+ export { default as getSSRAutoScript } from './get-ssr-auto-script';
8
+ export { default as useThemeObserver } from './use-theme-observer';
9
+ export { default as ThemeMutationObserver } from './theme-mutation-observer';
10
+ export { default as getGlobalTheme } from './get-global-theme';
11
+ export { themeStringToObject, themeObjectToString } from './theme-state-transformer';
@@ -1,30 +1,18 @@
1
1
  import { bind } from 'bind-event-listener';
2
2
  import noop from '@atlaskit/ds-lib/noop';
3
- import { getBooleanFF } from '@atlaskit/platform-feature-flags';
4
- import { COLOR_MODE_ATTRIBUTE, CUSTOM_THEME_ATTRIBUTE, THEME_DATA_ATTRIBUTE } from './constants';
5
- import { themeIdsWithOverrides } from './theme-config';
3
+ import { COLOR_MODE_ATTRIBUTE } from './constants';
4
+ import getThemeHtmlAttrs from './get-theme-html-attrs';
5
+ import { themeStateDefaults } from './theme-config';
6
6
  import { isValidBrandHex } from './utils/color-utils';
7
7
  import { findMissingCustomStyleElements } from './utils/custom-theme-loading-utils';
8
- import { hash } from './utils/hash';
9
- import { loadAndAppendThemeCss, loadThemeCss } from './utils/theme-loading';
10
- import { themeObjectToString } from './utils/theme-state-transformer';
8
+ import { getThemePreferences } from './utils/get-theme-preferences';
9
+ import { darkModeMediaQuery, loadAndAppendThemeCss } from './utils/theme-loading';
11
10
 
12
11
  // Represents theme state once mounted to the page (auto is hidden from observers)
13
12
 
14
- const defaultColorMode = 'light';
15
13
  const isMatchMediaAvailable = typeof window !== 'undefined' && 'matchMedia' in window;
16
- const darkModeMediaQuery = '(prefers-color-scheme: dark)';
17
14
  const darkModeMql = isMatchMediaAvailable && window.matchMedia(darkModeMediaQuery);
18
15
  let unbindThemeChangeListener = noop;
19
- export const themeStateDefaults = {
20
- colorMode: 'auto',
21
- dark: 'dark',
22
- light: 'light',
23
- shape: undefined,
24
- spacing: undefined,
25
- typography: undefined,
26
- UNSAFE_themeOptions: undefined
27
- };
28
16
 
29
17
  /**
30
18
  * Updates the current theme when the system theme changes. Should be bound
@@ -35,33 +23,6 @@ const checkNativeListener = function (e) {
35
23
  const element = document.documentElement;
36
24
  element.setAttribute(COLOR_MODE_ATTRIBUTE, e.matches ? 'dark' : 'light');
37
25
  };
38
- const getThemePreferences = themeState => {
39
- const {
40
- colorMode,
41
- dark,
42
- light,
43
- shape,
44
- spacing,
45
- typography
46
- } = themeState;
47
- const themePreferences = colorMode === 'auto' ? [light, dark] : [themeState[colorMode]];
48
- [shape, spacing, typography].forEach(themeId => {
49
- if (themeId) {
50
- themePreferences.push(themeId);
51
- }
52
- });
53
- if (getBooleanFF('platform.design-system-team.border-checkbox_nyoiu')) {
54
- themePreferences.push(`${themePreferences.includes('dark') ? 'dark' : 'light'}-new-input-border`);
55
- }
56
-
57
- // Load shape and spacing by default, currently behind a feature flag
58
- if (getBooleanFF('platform.design-system-team.space-and-shape-tokens_q5me6')) {
59
- if (!themePreferences.includes('spacing')) {
60
- themePreferences.push('spacing');
61
- }
62
- }
63
- return [...new Set(themePreferences)];
64
- };
65
26
 
66
27
  /**
67
28
  * Sets the theme globally at runtime. This updates the `data-theme` and `data-color-mode` attributes on your page's <html> tag.
@@ -145,145 +106,4 @@ const setGlobalTheme = async ({
145
106
  });
146
107
  return unbindThemeChangeListener;
147
108
  };
148
- /**
149
- * Takes an object containing theme preferences, and returns an array of objects for use in applying styles to the document head.
150
- * Only supplies the color themes necessary for initial render, based on the current themeState. I.e. if in light mode, dark mode themes are not returned.
151
- *
152
- * @param {Object<string, string>} themeState The themes and color mode that should be applied.
153
- * @param {string} themeState.colorMode Determines which color theme is applied. If set to `auto`, the theme applied will be determined by the OS setting.
154
- * @param {string} themeState.dark The color theme to be applied when the color mode resolves to 'dark'.
155
- * @param {string} themeState.light The color theme to be applied when the color mode resolves to 'light'.
156
- * @param {string} themeState.shape The shape theme to be applied.
157
- * @param {string} themeState.spacing The spacing theme to be applied.
158
- * @param {string} themeState.typography The typography theme to be applied.
159
- * @param {Object} themeState.UNSAFE_themeOptions The custom branding options to be used for custom theme generation
160
- *
161
- * @returns A Promise of an object array, containing theme IDs, data-attributes to attach to the theme, and the theme CSS.
162
- * If an error is encountered while loading themes, the themes array will be empty.
163
- */
164
- export const getThemeStyles = async preferences => {
165
- let themePreferences;
166
- if (preferences === 'all') {
167
- themePreferences = themeIdsWithOverrides;
168
- } else {
169
- themePreferences = getThemePreferences({
170
- colorMode: (preferences === null || preferences === void 0 ? void 0 : preferences.colorMode) || themeStateDefaults['colorMode'],
171
- dark: (preferences === null || preferences === void 0 ? void 0 : preferences.dark) || themeStateDefaults['dark'],
172
- light: (preferences === null || preferences === void 0 ? void 0 : preferences.light) || themeStateDefaults['light'],
173
- shape: (preferences === null || preferences === void 0 ? void 0 : preferences.shape) || themeStateDefaults['shape'],
174
- spacing: (preferences === null || preferences === void 0 ? void 0 : preferences.spacing) || themeStateDefaults['spacing'],
175
- typography: (preferences === null || preferences === void 0 ? void 0 : preferences.typography) || themeStateDefaults['typography']
176
- });
177
- }
178
- const results = await Promise.all([...themePreferences.map(async themeId => {
179
- try {
180
- const css = await loadThemeCss(themeId);
181
- return {
182
- id: themeId,
183
- attrs: {
184
- 'data-theme': themeId
185
- },
186
- css
187
- };
188
- } catch {
189
- // Return undefined if there's an error loading it, will be filtered out later.
190
- return undefined;
191
- }
192
- }),
193
- // Add custom themes if they're present
194
- (async () => {
195
- var _preferences$UNSAFE_t;
196
- if (preferences !== 'all' && preferences !== null && preferences !== void 0 && preferences.UNSAFE_themeOptions && isValidBrandHex(preferences === null || preferences === void 0 ? void 0 : (_preferences$UNSAFE_t = preferences.UNSAFE_themeOptions) === null || _preferences$UNSAFE_t === void 0 ? void 0 : _preferences$UNSAFE_t.brandColor)) {
197
- try {
198
- const {
199
- getCustomThemeStyles
200
- } = await import( /* webpackChunkName: "@atlaskit-internal_atlassian-custom-theme" */
201
- './custom-theme');
202
- const customThemeStyles = await getCustomThemeStyles({
203
- colorMode: (preferences === null || preferences === void 0 ? void 0 : preferences.colorMode) || themeStateDefaults['colorMode'],
204
- UNSAFE_themeOptions: preferences === null || preferences === void 0 ? void 0 : preferences.UNSAFE_themeOptions
205
- });
206
- return customThemeStyles;
207
- } catch {
208
- // Return undefined if there's an error loading it, will be filtered out later.
209
- return undefined;
210
- }
211
- }
212
- })()]);
213
- return results.flat().filter(theme => theme !== undefined);
214
- };
215
-
216
- /**
217
- * Server-side rendering utility. Generates the valid HTML attributes for a given theme.
218
- * Note: this utility does not handle automatic theme switching.
219
- *
220
- * @param {Object<string, string>} themeOptions - Theme options object
221
- * @param {string} themeState.colorMode Determines which color theme is applied. If set to `auto`, the theme applied will be determined by the OS setting.
222
- * @param {string} themeState.dark The color theme to be applied when the color mode resolves to 'dark'.
223
- * @param {string} themeState.light The color theme to be applied when the color mode resolves to 'light'.
224
- * @param {string} themeState.spacing The spacing theme to be applied.
225
- * @param {string} themeState.typography The typography theme to be applied.
226
- * @param {Object} themeState.UNSAFE_themeOptions The custom branding options to be used for custom theme generation
227
- *
228
- * @returns {Object} Object of HTML attributes to be applied to the document root
229
- */
230
- export const getThemeHtmlAttrs = ({
231
- colorMode = themeStateDefaults['colorMode'],
232
- dark = themeStateDefaults['dark'],
233
- light = themeStateDefaults['light'],
234
- shape = themeStateDefaults['shape'],
235
- spacing = themeStateDefaults['spacing'],
236
- typography = themeStateDefaults['typography'],
237
- UNSAFE_themeOptions = themeStateDefaults['UNSAFE_themeOptions']
238
- } = {}) => {
239
- let themePreferences = {
240
- dark,
241
- light,
242
- shape,
243
- spacing,
244
- typography
245
- };
246
-
247
- // Load spacing by default, currently behind a feature flag
248
- if (getBooleanFF('platform.design-system-team.space-and-shape-tokens_q5me6')) {
249
- themePreferences = {
250
- dark,
251
- light,
252
- shape,
253
- spacing: 'spacing',
254
- typography
255
- };
256
- }
257
- const themeAttribute = themeObjectToString(themePreferences);
258
- const result = {
259
- [THEME_DATA_ATTRIBUTE]: themeAttribute,
260
- [COLOR_MODE_ATTRIBUTE]: colorMode === 'auto' ? defaultColorMode : colorMode
261
- };
262
- if (UNSAFE_themeOptions && isValidBrandHex(UNSAFE_themeOptions.brandColor)) {
263
- const optionString = JSON.stringify(UNSAFE_themeOptions);
264
- const uniqueId = hash(optionString);
265
- result[CUSTOM_THEME_ATTRIBUTE] = uniqueId;
266
- }
267
- return result;
268
- };
269
-
270
- /**
271
- * Provides a script that, when executed before paint, sets the `data-color-mode` attribute based on the current system theme,
272
- * to enable SSR support for automatic theme switching, avoid a flash of un-themed content on first paint.
273
- *
274
- * @param {string} colorMode Determines which color theme is applied. If set to `auto`, the theme applied will be determined by the OS setting.
275
- *
276
- * @returns {string} A string to be added to the innerHTML of a script tag in the document head
277
- */
278
- export const getSSRAutoScript = colorMode => {
279
- return colorMode === 'auto' ? `(
280
- () => {
281
- try {
282
- const mql = window.matchMedia('${darkModeMediaQuery}');
283
- const colorMode = mql.matches ? 'dark' : 'light';
284
- document.documentElement.setAttribute('${COLOR_MODE_ATTRIBUTE}', colorMode);
285
- } catch (e) {}
286
- }
287
- )()` : undefined;
288
- };
289
109
  export default setGlobalTheme;
@@ -141,4 +141,25 @@ const themeConfig = {
141
141
  }
142
142
  }
143
143
  };
144
+
145
+ /**
146
+ * ThemeOptionsSchema: additional configuration options used to customize Atlassian's themes
147
+ */
148
+
149
+ /**
150
+ * ThemeState: the standard representation of an app's current theme and preferences
151
+ */
152
+
153
+ /**
154
+ * themeStateDefaults: the default values for ThemeState used by theming utilities
155
+ */
156
+ export const themeStateDefaults = {
157
+ colorMode: 'auto',
158
+ dark: 'dark',
159
+ light: 'light',
160
+ shape: undefined,
161
+ spacing: undefined,
162
+ typography: undefined,
163
+ UNSAFE_themeOptions: undefined
164
+ };
144
165
  export default themeConfig;
@@ -1,6 +1,6 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { COLOR_MODE_ATTRIBUTE, THEME_DATA_ATTRIBUTE } from './constants';
3
- import { getGlobalTheme } from './get-global-theme';
3
+ import getGlobalTheme from './get-global-theme';
4
4
  /**
5
5
  * A MutationObserver which watches the `<html>` element for changes to the theme.
6
6
  *
@@ -14,7 +14,7 @@ import { getGlobalTheme } from './get-global-theme';
14
14
  * observer.observe();
15
15
  * ```
16
16
  */
17
- export class ThemeMutationObserver {
17
+ export default class ThemeMutationObserver {
18
18
  constructor(callback) {
19
19
  _defineProperty(this, "observer", null);
20
20
  _defineProperty(this, "mediaObserver", null);
@@ -1,5 +1,6 @@
1
- import { themeIds } from '../theme-config';
1
+ import { themeIds } from './theme-config';
2
2
  const themeKinds = ['light', 'dark', 'spacing', 'typography', 'shape'];
3
+ const customThemeOptions = 'UNSAFE_themeOptions';
3
4
  const isThemeKind = themeKind => {
4
5
  return themeKinds.find(kind => kind === themeKind) !== undefined;
5
6
  };
@@ -22,7 +23,7 @@ const isColorMode = modeId => {
22
23
  * ```
23
24
  */
24
25
  export const themeStringToObject = themeState => {
25
- return themeState.split(' ').map(theme => theme.split(':')).reduce((themeObject, [kind, id]) => {
26
+ return themeState.split(' ').map(theme => theme.split(/:(.*)/s)).reduce((themeObject, [kind, id]) => {
26
27
  if (kind === 'colorMode' && isColorMode(id)) {
27
28
  themeObject[kind] = id;
28
29
  }
@@ -30,6 +31,13 @@ export const themeStringToObject = themeState => {
30
31
  // @ts-expect-error FIXME - this is a valid ts error
31
32
  themeObject[kind] = id;
32
33
  }
34
+ if (kind === customThemeOptions) {
35
+ try {
36
+ themeObject[customThemeOptions] = JSON.parse(id);
37
+ } catch (e) {
38
+ new Error('Invalid custom theme string');
39
+ }
40
+ }
33
41
  return themeObject;
34
42
  }, {});
35
43
  };
@@ -45,6 +53,15 @@ export const themeStringToObject = themeState => {
45
53
  * // returns 'dark:dark light:legacy-light spacing:spacing'
46
54
  * ```
47
55
  */
48
- export const themeObjectToString = themeState => {
49
- return Object.entries(themeState).reduce((themeString, [kind, id]) => (kind === 'colorMode' || isThemeKind(kind)) && typeof id === 'string' && (isThemeIds(id) || isColorMode(id)) ? themeString + `${themeString ? ' ' : ''}` + `${kind}:${id}` : themeString, '');
50
- };
56
+ export const themeObjectToString = themeState => Object.entries(themeState).reduce((themeString, [kind, id]) => {
57
+ if (
58
+ // colorMode theme state
59
+ kind === 'colorMode' && typeof id === 'string' && isColorMode(id) ||
60
+ // custom theme state
61
+ kind === customThemeOptions && typeof id === 'object' ||
62
+ // other theme states
63
+ isThemeKind(kind) && typeof id === 'string' && isThemeIds(id)) {
64
+ return themeString + `${themeString ? ' ' : ''}` + `${kind}:${typeof id === 'object' ? JSON.stringify(id) : id}`;
65
+ }
66
+ return themeString;
67
+ }, '');
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
- import { getGlobalTheme } from './get-global-theme';
3
- import { ThemeMutationObserver } from './theme-mutation-observer';
2
+ import getGlobalTheme from './get-global-theme';
3
+ import ThemeMutationObserver from './theme-mutation-observer';
4
4
 
5
5
  /**
6
6
  * A React hook which returns the current themes and color-mode set on `<html>`.
@@ -15,7 +15,7 @@ import { ThemeMutationObserver } from './theme-mutation-observer';
15
15
  * }, [theme.colorMode]);
16
16
  * ```
17
17
  */
18
- export const useThemeObserver = () => {
18
+ const useThemeObserver = () => {
19
19
  const [theme, setTheme] = useState(getGlobalTheme());
20
20
  useEffect(() => {
21
21
  const observer = new ThemeMutationObserver(theme => setTheme(theme));
@@ -23,4 +23,5 @@ export const useThemeObserver = () => {
23
23
  return () => observer.disconnect();
24
24
  }, []);
25
25
  return theme;
26
- };
26
+ };
27
+ export default useThemeObserver;
@@ -0,0 +1,28 @@
1
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
2
+ export const getThemePreferences = themeState => {
3
+ const {
4
+ colorMode,
5
+ dark,
6
+ light,
7
+ shape,
8
+ spacing,
9
+ typography
10
+ } = themeState;
11
+ const themePreferences = colorMode === 'auto' ? [light, dark] : [themeState[colorMode]];
12
+ [shape, spacing, typography].forEach(themeId => {
13
+ if (themeId) {
14
+ themePreferences.push(themeId);
15
+ }
16
+ });
17
+ if (getBooleanFF('platform.design-system-team.border-checkbox_nyoiu')) {
18
+ themePreferences.push(`${themePreferences.includes('dark') ? 'dark' : 'light'}-new-input-border`);
19
+ }
20
+
21
+ // Load shape and spacing by default, currently behind a feature flag
22
+ if (getBooleanFF('platform.design-system-team.space-and-shape-tokens_q5me6')) {
23
+ if (!themePreferences.includes('spacing')) {
24
+ themePreferences.push('spacing');
25
+ }
26
+ }
27
+ return [...new Set(themePreferences)];
28
+ };
@@ -15,4 +15,5 @@ export const loadThemeCss = async themeId => {
15
15
  default: themeCss
16
16
  } = await themeImportMap[themeId]();
17
17
  return themeCss;
18
- };
18
+ };
19
+ export const darkModeMediaQuery = '(prefers-color-scheme: dark)';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/tokens",
3
- "version": "1.13.1",
3
+ "version": "1.14.0",
4
4
  "sideEffects": [
5
5
  "**/*.css"
6
6
  ]
@@ -1,11 +1,12 @@
1
1
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  import { COLOR_MODE_ATTRIBUTE, CUSTOM_THEME_ATTRIBUTE } from './constants';
4
- import { themeStateDefaults } from './set-global-theme';
4
+ import { themeStateDefaults } from './theme-config';
5
5
  import { limitSizeOfCustomStyleElements, reduceTokenMap } from './utils/custom-theme-loading-utils';
6
6
  import { generateColors, generateTokenMapWithContrastCheck } from './utils/generate-custom-color-ramp';
7
7
  import { hash } from './utils/hash';
8
8
  export var CUSTOM_STYLE_ELEMENTS_SIZE_THRESHOLD = 10;
9
+
9
10
  /**
10
11
  *
11
12
  * @param themeSchema The schema of available themes
@@ -75,20 +76,23 @@ export function loadAndAppendCustomThemeCss(_x2) {
75
76
  }
76
77
  function _loadAndAppendCustomThemeCss() {
77
78
  _loadAndAppendCustomThemeCss = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(themeState) {
79
+ var themes;
78
80
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
79
81
  while (1) switch (_context2.prev = _context2.next) {
80
82
  case 0:
81
- getCustomThemeStyles(themeState).then(function (themes) {
82
- limitSizeOfCustomStyleElements(CUSTOM_STYLE_ELEMENTS_SIZE_THRESHOLD);
83
- themes.map(function (theme) {
84
- var styleTag = document.createElement('style');
85
- document.head.appendChild(styleTag);
86
- styleTag.dataset.theme = theme.attrs['data-theme'];
87
- styleTag.dataset.customTheme = theme.attrs['data-custom-theme'];
88
- styleTag.textContent = theme.css;
89
- });
83
+ _context2.next = 2;
84
+ return getCustomThemeStyles(themeState);
85
+ case 2:
86
+ themes = _context2.sent;
87
+ limitSizeOfCustomStyleElements(CUSTOM_STYLE_ELEMENTS_SIZE_THRESHOLD);
88
+ themes.map(function (theme) {
89
+ var styleTag = document.createElement('style');
90
+ document.head.appendChild(styleTag);
91
+ styleTag.dataset.theme = theme.attrs['data-theme'];
92
+ styleTag.dataset.customTheme = theme.attrs['data-custom-theme'];
93
+ styleTag.textContent = theme.css;
90
94
  });
91
- case 1:
95
+ case 5:
92
96
  case "end":
93
97
  return _context2.stop();
94
98
  }
@@ -3,13 +3,13 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
3
3
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
4
  import { COLOR_MODE_ATTRIBUTE, THEME_DATA_ATTRIBUTE } from './constants';
5
5
  import { themeColorModes } from './theme-config';
6
- import { themeStringToObject } from './utils/theme-state-transformer';
6
+ import { themeStringToObject } from './theme-state-transformer';
7
7
  var isThemeColorMode = function isThemeColorMode(colorMode) {
8
8
  return themeColorModes.find(function (mode) {
9
9
  return mode === colorMode;
10
10
  }) !== undefined;
11
11
  };
12
- export var getGlobalTheme = function getGlobalTheme() {
12
+ var getGlobalTheme = function getGlobalTheme() {
13
13
  if (typeof document === 'undefined') {
14
14
  return {};
15
15
  }
@@ -19,4 +19,5 @@ export var getGlobalTheme = function getGlobalTheme() {
19
19
  return _objectSpread(_objectSpread({}, themeStringToObject(theme)), isThemeColorMode(colorMode) && {
20
20
  colorMode: colorMode
21
21
  });
22
- };
22
+ };
23
+ export default getGlobalTheme;
@@ -0,0 +1,15 @@
1
+ import { COLOR_MODE_ATTRIBUTE } from './constants';
2
+ import { darkModeMediaQuery } from './utils/theme-loading';
3
+
4
+ /**
5
+ * Provides a script that, when executed before paint, sets the `data-color-mode` attribute based on the current system theme,
6
+ * to enable SSR support for automatic theme switching, avoid a flash of un-themed content on first paint.
7
+ *
8
+ * @param {string} colorMode Determines which color theme is applied. If set to `auto`, the theme applied will be determined by the OS setting.
9
+ *
10
+ * @returns {string} A string to be added to the innerHTML of a script tag in the document head
11
+ */
12
+ var getSSRAutoScript = function getSSRAutoScript(colorMode) {
13
+ return colorMode === 'auto' ? "(\n () => {\n try {\n const mql = window.matchMedia('".concat(darkModeMediaQuery, "');\n const colorMode = mql.matches ? 'dark' : 'light';\n document.documentElement.setAttribute('").concat(COLOR_MODE_ATTRIBUTE, "', colorMode);\n } catch (e) {}\n }\n)()") : undefined;
14
+ };
15
+ export default getSSRAutoScript;