@atlaskit/tokens 1.14.0 → 1.14.1

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 (29) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/custom-theme.js +1 -1
  3. package/dist/cjs/get-token-value.js +1 -1
  4. package/dist/cjs/get-token.js +1 -1
  5. package/dist/cjs/utils/custom-theme-loading-utils.js +1 -1
  6. package/dist/cjs/utils/custom-theme-token-contrast-check.js +15 -3
  7. package/dist/cjs/utils/generate-custom-color-ramp.js +30 -10
  8. package/dist/cjs/version.json +1 -1
  9. package/dist/es2019/custom-theme.js +1 -1
  10. package/dist/es2019/get-token-value.js +1 -1
  11. package/dist/es2019/get-token.js +1 -1
  12. package/dist/es2019/utils/custom-theme-loading-utils.js +1 -1
  13. package/dist/es2019/utils/custom-theme-token-contrast-check.js +15 -3
  14. package/dist/es2019/utils/generate-custom-color-ramp.js +31 -10
  15. package/dist/es2019/version.json +1 -1
  16. package/dist/esm/custom-theme.js +1 -1
  17. package/dist/esm/get-token-value.js +1 -1
  18. package/dist/esm/get-token.js +1 -1
  19. package/dist/esm/utils/custom-theme-loading-utils.js +1 -1
  20. package/dist/esm/utils/custom-theme-token-contrast-check.js +15 -3
  21. package/dist/esm/utils/generate-custom-color-ramp.js +30 -10
  22. package/dist/esm/version.json +1 -1
  23. package/dist/types/utils/custom-theme-loading-utils.d.ts +1 -1
  24. package/dist/types/utils/custom-theme-token-contrast-check.d.ts +1 -1
  25. package/dist/types/utils/generate-custom-color-ramp.d.ts +5 -2
  26. package/dist/types-ts4.5/utils/custom-theme-loading-utils.d.ts +1 -1
  27. package/dist/types-ts4.5/utils/custom-theme-token-contrast-check.d.ts +1 -1
  28. package/dist/types-ts4.5/utils/generate-custom-color-ramp.d.ts +5 -2
  29. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @atlaskit/tokens
2
2
 
3
+ ## 1.14.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`b423f118bb8`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b423f118bb8) - Adjusted color generation system for custom theming to improve accessibility.
8
+
3
9
  ## 1.14.0
4
10
 
5
11
  ### Minor Changes
@@ -47,7 +47,7 @@ function _getCustomThemeStyles() {
47
47
  mode = (themeState === null || themeState === void 0 ? void 0 : themeState.colorMode) || _themeConfig.themeStateDefaults['colorMode'];
48
48
  optionString = JSON.stringify(themeState === null || themeState === void 0 ? void 0 : themeState.UNSAFE_themeOptions);
49
49
  uniqueId = (0, _hash.hash)(optionString);
50
- themeRamp = (0, _generateCustomColorRamp.generateColors)(brandColor); // outputs object to generate to CSS from
50
+ themeRamp = (0, _generateCustomColorRamp.generateColors)(brandColor).ramp; // outputs object to generate to CSS from
51
51
  themes = [];
52
52
  tokenMaps = (0, _generateCustomColorRamp.generateTokenMapWithContrastCheck)(brandColor, mode, themeRamp);
53
53
  if ((mode === 'light' || mode === 'auto') && tokenMaps.light) {
@@ -8,7 +8,7 @@ exports.default = void 0;
8
8
  var _warnOnce = _interopRequireDefault(require("@atlaskit/ds-lib/warn-once"));
9
9
  var _tokenNames = _interopRequireDefault(require("./artifacts/token-names"));
10
10
  var name = "@atlaskit/tokens";
11
- var version = "1.14.0";
11
+ var version = "1.14.1";
12
12
  /**
13
13
  * Takes a dot-separated token name and and an optional fallback, and returns the current computed CSS value for the
14
14
  * resulting CSS Custom Property.
@@ -9,7 +9,7 @@ var _warnOnce = _interopRequireDefault(require("@atlaskit/ds-lib/warn-once"));
9
9
  var _tokenNames = _interopRequireDefault(require("./artifacts/token-names"));
10
10
  var _constants = require("./constants");
11
11
  var name = "@atlaskit/tokens";
12
- var version = "1.14.0";
12
+ var version = "1.14.1";
13
13
  /**
14
14
  * Takes a dot-separated token name and an optional fallback, and returns the CSS custom property for the corresponding token.
15
15
  * This should be used to implement design decisions throughout your application.
@@ -42,6 +42,6 @@ function reduceTokenMap(tokenMap, themeRamp) {
42
42
  key = _ref2[0],
43
43
  value = _ref2[1];
44
44
  var cssVar = _tokenNames.default[key];
45
- return cssVar ? "".concat(acc, "\n ").concat(cssVar, ": ").concat(themeRamp[value], ";") : acc;
45
+ return cssVar ? "".concat(acc, "\n ").concat(cssVar, ": ").concat(typeof value === 'string' ? value : themeRamp[value], ";") : acc;
46
46
  }, '');
47
47
  }
@@ -17,6 +17,14 @@ var additionalChecks = [{
17
17
  // In light mode: darken the following tokens by one base token
18
18
  // In dark mode: lighten the following tokens by one base token
19
19
  'color.text.brand', 'color.text.selected', 'color.link', 'color.link.pressed', 'color.icon.brand', 'color.icon.selected']
20
+ }, {
21
+ foreground: 'color.text.brand',
22
+ backgroundLight: 'color.background.selected',
23
+ backgroundDark: 'color.background.selected',
24
+ desiredContrast: 4.5,
25
+ // In light mode: darken the following tokens by one base token
26
+ // In dark mode: lighten the following tokens by one base toke
27
+ updatedTokens: ['color.text.brand', 'color.link', 'color.link.pressed']
20
28
  }, {
21
29
  foreground: 'color.text.selected',
22
30
  backgroundLight: 'color.background.selected',
@@ -59,13 +67,17 @@ var additionalContrastChecker = function additionalContrastChecker(_ref) {
59
67
  desiredContrast = pairing.desiredContrast,
60
68
  updatedTokens = pairing.updatedTokens;
61
69
  var background = mode === 'light' ? backgroundLight : backgroundDark;
62
- var foregroundColor = brandTokens.includes(foreground) ? themeRamp[customThemeTokenMap[foreground]] : getColorFromTokenRaw(foreground, mode);
63
- var backgroundColor = brandTokens.includes(background) ? themeRamp[customThemeTokenMap[background]] : getColorFromTokenRaw(background, mode);
70
+ var foregroundTokenValue = customThemeTokenMap[foreground];
71
+ var backgroundTokenValue = customThemeTokenMap[background];
72
+ var foregroundColor = brandTokens.includes(foreground) ? typeof foregroundTokenValue === 'string' ? foregroundTokenValue : themeRamp[foregroundTokenValue] : getColorFromTokenRaw(foreground, mode);
73
+ var backgroundColor = brandTokens.includes(background) ? typeof backgroundTokenValue === 'string' ? backgroundTokenValue : themeRamp[backgroundTokenValue] : getColorFromTokenRaw(background, mode);
64
74
  var contrast = (0, _colorUtils.getContrastRatio)(foregroundColor, backgroundColor);
65
75
  if (contrast <= desiredContrast) {
66
76
  updatedTokens.forEach(function (token) {
67
77
  var rampValue = customThemeTokenMap[token];
68
- updatedCustomThemeTokenMap[token] = mode === 'light' ? rampValue + 1 : rampValue - 1;
78
+ if (typeof rampValue === 'number') {
79
+ updatedCustomThemeTokenMap[token] = mode === 'light' ? rampValue + 1 : rampValue - 1;
80
+ }
69
81
  });
70
82
  }
71
83
  });
@@ -54,7 +54,11 @@ var generateColors = function generateColors(brandColor) {
54
54
  // Replace closet color with brandColor
55
55
  var updatedThemeRamp = (0, _toConsumableArray2.default)(themeRamp);
56
56
  updatedThemeRamp[closestColorIndex] = brandColor;
57
- return updatedThemeRamp;
57
+ return {
58
+ ramp: updatedThemeRamp,
59
+ // add the replaced color into the result
60
+ replacedColor: themeRamp[closestColorIndex]
61
+ };
58
62
  };
59
63
 
60
64
  /**
@@ -78,7 +82,10 @@ function getInteractionStates(rampPosition, number, colors) {
78
82
  return result;
79
83
  }
80
84
  var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
81
- var colors = themeRamp || generateColors(brandColor);
85
+ var _generateColors = generateColors(brandColor),
86
+ ramp = _generateColors.ramp,
87
+ replacedColor = _generateColors.replacedColor;
88
+ var colors = themeRamp || ramp;
82
89
  var closestColorIndex = getClosestColorIndex(colors, brandColor);
83
90
  var customThemeTokenMapLight = {};
84
91
  var customThemeTokenMapDark = {};
@@ -94,6 +101,12 @@ var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
94
101
  _getInteractionStates2 = (0, _slicedToArray2.default)(_getInteractionStates, 2),
95
102
  brandBoldSelectedHoveredIndex = _getInteractionStates2[0],
96
103
  brandBoldSelectedPressedIndex = _getInteractionStates2[1];
104
+ var brandTextIndex = closestColorIndex;
105
+ if (inputContrast < 5.4 && inputContrast >= 4.8 && closestColorIndex === 6) {
106
+ // Use the one-level darker closest color (X800) for color.text.brand
107
+ // and color.link to avoid contrast breaches
108
+ brandTextIndex = closestColorIndex + 1;
109
+ }
97
110
 
98
111
  /**
99
112
  * Generate interaction token for color.link:
@@ -103,11 +116,11 @@ var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
103
116
  * If inputted color replaces X700-X900
104
117
  * - Shift one 1 step darker
105
118
  */
106
- var _getInteractionStates3 = getInteractionStates(closestColorIndex, 1, colors),
119
+ var _getInteractionStates3 = getInteractionStates(brandTextIndex, 1, colors),
107
120
  _getInteractionStates4 = (0, _slicedToArray2.default)(_getInteractionStates3, 1),
108
121
  linkPressed = _getInteractionStates4[0];
109
122
  customThemeTokenMapLight = {
110
- 'color.text.brand': closestColorIndex,
123
+ 'color.text.brand': brandTextIndex,
111
124
  'color.icon.brand': closestColorIndex,
112
125
  'color.background.brand.subtlest': 0,
113
126
  'color.background.brand.subtlest.hovered': 1,
@@ -119,13 +132,13 @@ var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
119
132
  'color.background.brand.boldest.hovered': 8,
120
133
  'color.background.brand.boldest.pressed': 7,
121
134
  'color.border.brand': closestColorIndex,
122
- 'color.text.selected': closestColorIndex,
135
+ 'color.text.selected': brandTextIndex,
123
136
  'color.icon.selected': closestColorIndex,
124
137
  'color.background.selected.bold': closestColorIndex,
125
138
  'color.background.selected.bold.hovered': brandBoldSelectedHoveredIndex,
126
139
  'color.background.selected.bold.pressed': brandBoldSelectedPressedIndex,
127
140
  'color.border.selected': closestColorIndex,
128
- 'color.link': closestColorIndex,
141
+ 'color.link': brandTextIndex,
129
142
  'color.link.pressed': linkPressed,
130
143
  'color.chart.brand': 5,
131
144
  'color.chart.brand.hovered': 6,
@@ -134,18 +147,25 @@ var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
134
147
  'color.background.selected.pressed': 2
135
148
  };
136
149
  } else {
150
+ var brandBackgroundIndex = 6;
151
+ if (inputContrast < 4.5 && inputContrast >= 4 && closestColorIndex === 6) {
152
+ // Use the generated closest color instead of the input brand color for
153
+ // color.background.selected.bold and color.background.brand.bold
154
+ // to avoid contrast breaches
155
+ brandBackgroundIndex = replacedColor;
156
+ }
137
157
  customThemeTokenMapLight = {
138
158
  'color.background.brand.subtlest': 0,
139
159
  'color.background.brand.subtlest.hovered': 1,
140
160
  'color.background.brand.subtlest.pressed': 2,
141
- 'color.background.brand.bold': 6,
161
+ 'color.background.brand.bold': brandBackgroundIndex,
142
162
  'color.background.brand.bold.hovered': 7,
143
163
  'color.background.brand.bold.pressed': 8,
144
164
  'color.background.brand.boldest': 9,
145
165
  'color.background.brand.boldest.hovered': 8,
146
166
  'color.background.brand.boldest.pressed': 7,
147
167
  'color.border.brand': 6,
148
- 'color.background.selected.bold': 6,
168
+ 'color.background.selected.bold': brandBackgroundIndex,
149
169
  'color.background.selected.bold.hovered': 7,
150
170
  'color.background.selected.bold.pressed': 8,
151
171
  'color.text.brand': 6,
@@ -175,7 +195,7 @@ var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
175
195
  var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
176
196
  key = _ref2[0],
177
197
  value = _ref2[1];
178
- customThemeTokenMapDark[key] = 9 - value;
198
+ customThemeTokenMapDark[key] = 9 - (typeof value === 'string' ? closestColorIndex : value);
179
199
  });
180
200
 
181
201
  /**
@@ -202,7 +222,7 @@ var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
202
222
  };
203
223
  exports.generateTokenMap = generateTokenMap;
204
224
  var generateTokenMapWithContrastCheck = function generateTokenMapWithContrastCheck(brandColor, mode, themeRamp) {
205
- var colors = themeRamp || generateColors(brandColor);
225
+ var colors = themeRamp || generateColors(brandColor).ramp;
206
226
  var tokenMaps = generateTokenMap(brandColor, mode, colors);
207
227
  var result = {};
208
228
  Object.entries(tokenMaps).forEach(function (_ref3) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/tokens",
3
- "version": "1.14.0",
3
+ "version": "1.14.1",
4
4
  "sideEffects": [
5
5
  "**/*.css"
6
6
  ]
@@ -27,7 +27,7 @@ export async function getCustomThemeStyles(themeState) {
27
27
  const mode = (themeState === null || themeState === void 0 ? void 0 : themeState.colorMode) || themeStateDefaults['colorMode'];
28
28
  const optionString = JSON.stringify(themeState === null || themeState === void 0 ? void 0 : themeState.UNSAFE_themeOptions);
29
29
  const uniqueId = hash(optionString);
30
- const themeRamp = generateColors(brandColor);
30
+ const themeRamp = generateColors(brandColor).ramp;
31
31
 
32
32
  // outputs object to generate to CSS from
33
33
  const themes = [];
@@ -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.14.0";
4
+ const version = "1.14.1";
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.14.0";
5
+ const version = "1.14.1";
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.
@@ -26,6 +26,6 @@ export function limitSizeOfCustomStyleElements(sizeThreshold) {
26
26
  export function reduceTokenMap(tokenMap, themeRamp) {
27
27
  return Object.entries(tokenMap).reduce((acc, [key, value]) => {
28
28
  const cssVar = tokens[key];
29
- return cssVar ? `${acc}\n ${cssVar}: ${themeRamp[value]};` : acc;
29
+ return cssVar ? `${acc}\n ${cssVar}: ${typeof value === 'string' ? value : themeRamp[value]};` : acc;
30
30
  }, '');
31
31
  }
@@ -10,6 +10,14 @@ export const additionalChecks = [{
10
10
  // In light mode: darken the following tokens by one base token
11
11
  // In dark mode: lighten the following tokens by one base token
12
12
  'color.text.brand', 'color.text.selected', 'color.link', 'color.link.pressed', 'color.icon.brand', 'color.icon.selected']
13
+ }, {
14
+ foreground: 'color.text.brand',
15
+ backgroundLight: 'color.background.selected',
16
+ backgroundDark: 'color.background.selected',
17
+ desiredContrast: 4.5,
18
+ // In light mode: darken the following tokens by one base token
19
+ // In dark mode: lighten the following tokens by one base toke
20
+ updatedTokens: ['color.text.brand', 'color.link', 'color.link.pressed']
13
21
  }, {
14
22
  foreground: 'color.text.selected',
15
23
  backgroundLight: 'color.background.selected',
@@ -54,13 +62,17 @@ export const additionalContrastChecker = ({
54
62
  updatedTokens
55
63
  } = pairing;
56
64
  const background = mode === 'light' ? backgroundLight : backgroundDark;
57
- const foregroundColor = brandTokens.includes(foreground) ? themeRamp[customThemeTokenMap[foreground]] : getColorFromTokenRaw(foreground, mode);
58
- const backgroundColor = brandTokens.includes(background) ? themeRamp[customThemeTokenMap[background]] : getColorFromTokenRaw(background, mode);
65
+ const foregroundTokenValue = customThemeTokenMap[foreground];
66
+ const backgroundTokenValue = customThemeTokenMap[background];
67
+ const foregroundColor = brandTokens.includes(foreground) ? typeof foregroundTokenValue === 'string' ? foregroundTokenValue : themeRamp[foregroundTokenValue] : getColorFromTokenRaw(foreground, mode);
68
+ const backgroundColor = brandTokens.includes(background) ? typeof backgroundTokenValue === 'string' ? backgroundTokenValue : themeRamp[backgroundTokenValue] : getColorFromTokenRaw(background, mode);
59
69
  const contrast = getContrastRatio(foregroundColor, backgroundColor);
60
70
  if (contrast <= desiredContrast) {
61
71
  updatedTokens.forEach(token => {
62
72
  const rampValue = customThemeTokenMap[token];
63
- updatedCustomThemeTokenMap[token] = mode === 'light' ? rampValue + 1 : rampValue - 1;
73
+ if (typeof rampValue === 'number') {
74
+ updatedCustomThemeTokenMap[token] = mode === 'light' ? rampValue + 1 : rampValue - 1;
75
+ }
64
76
  });
65
77
  }
66
78
  });
@@ -41,7 +41,11 @@ export const generateColors = brandColor => {
41
41
  // Replace closet color with brandColor
42
42
  const updatedThemeRamp = [...themeRamp];
43
43
  updatedThemeRamp[closestColorIndex] = brandColor;
44
- return updatedThemeRamp;
44
+ return {
45
+ ramp: updatedThemeRamp,
46
+ // add the replaced color into the result
47
+ replacedColor: themeRamp[closestColorIndex]
48
+ };
45
49
  };
46
50
 
47
51
  /**
@@ -64,7 +68,11 @@ function getInteractionStates(rampPosition, number, colors) {
64
68
  return result;
65
69
  }
66
70
  export const generateTokenMap = (brandColor, mode, themeRamp) => {
67
- const colors = themeRamp || generateColors(brandColor);
71
+ const {
72
+ ramp,
73
+ replacedColor
74
+ } = generateColors(brandColor);
75
+ const colors = themeRamp || ramp;
68
76
  const closestColorIndex = getClosestColorIndex(colors, brandColor);
69
77
  let customThemeTokenMapLight = {};
70
78
  let customThemeTokenMapDark = {};
@@ -77,6 +85,12 @@ export const generateTokenMap = (brandColor, mode, themeRamp) => {
77
85
  * - color.background.selected.bold
78
86
  */
79
87
  const [brandBoldSelectedHoveredIndex, brandBoldSelectedPressedIndex] = getInteractionStates(closestColorIndex, 2, colors);
88
+ let brandTextIndex = closestColorIndex;
89
+ if (inputContrast < 5.4 && inputContrast >= 4.8 && closestColorIndex === 6) {
90
+ // Use the one-level darker closest color (X800) for color.text.brand
91
+ // and color.link to avoid contrast breaches
92
+ brandTextIndex = closestColorIndex + 1;
93
+ }
80
94
 
81
95
  /**
82
96
  * Generate interaction token for color.link:
@@ -86,9 +100,9 @@ export const generateTokenMap = (brandColor, mode, themeRamp) => {
86
100
  * If inputted color replaces X700-X900
87
101
  * - Shift one 1 step darker
88
102
  */
89
- const [linkPressed] = getInteractionStates(closestColorIndex, 1, colors);
103
+ const [linkPressed] = getInteractionStates(brandTextIndex, 1, colors);
90
104
  customThemeTokenMapLight = {
91
- 'color.text.brand': closestColorIndex,
105
+ 'color.text.brand': brandTextIndex,
92
106
  'color.icon.brand': closestColorIndex,
93
107
  'color.background.brand.subtlest': 0,
94
108
  'color.background.brand.subtlest.hovered': 1,
@@ -100,13 +114,13 @@ export const generateTokenMap = (brandColor, mode, themeRamp) => {
100
114
  'color.background.brand.boldest.hovered': 8,
101
115
  'color.background.brand.boldest.pressed': 7,
102
116
  'color.border.brand': closestColorIndex,
103
- 'color.text.selected': closestColorIndex,
117
+ 'color.text.selected': brandTextIndex,
104
118
  'color.icon.selected': closestColorIndex,
105
119
  'color.background.selected.bold': closestColorIndex,
106
120
  'color.background.selected.bold.hovered': brandBoldSelectedHoveredIndex,
107
121
  'color.background.selected.bold.pressed': brandBoldSelectedPressedIndex,
108
122
  'color.border.selected': closestColorIndex,
109
- 'color.link': closestColorIndex,
123
+ 'color.link': brandTextIndex,
110
124
  'color.link.pressed': linkPressed,
111
125
  'color.chart.brand': 5,
112
126
  'color.chart.brand.hovered': 6,
@@ -115,18 +129,25 @@ export const generateTokenMap = (brandColor, mode, themeRamp) => {
115
129
  'color.background.selected.pressed': 2
116
130
  };
117
131
  } else {
132
+ let brandBackgroundIndex = 6;
133
+ if (inputContrast < 4.5 && inputContrast >= 4 && closestColorIndex === 6) {
134
+ // Use the generated closest color instead of the input brand color for
135
+ // color.background.selected.bold and color.background.brand.bold
136
+ // to avoid contrast breaches
137
+ brandBackgroundIndex = replacedColor;
138
+ }
118
139
  customThemeTokenMapLight = {
119
140
  'color.background.brand.subtlest': 0,
120
141
  'color.background.brand.subtlest.hovered': 1,
121
142
  'color.background.brand.subtlest.pressed': 2,
122
- 'color.background.brand.bold': 6,
143
+ 'color.background.brand.bold': brandBackgroundIndex,
123
144
  'color.background.brand.bold.hovered': 7,
124
145
  'color.background.brand.bold.pressed': 8,
125
146
  'color.background.brand.boldest': 9,
126
147
  'color.background.brand.boldest.hovered': 8,
127
148
  'color.background.brand.boldest.pressed': 7,
128
149
  'color.border.brand': 6,
129
- 'color.background.selected.bold': 6,
150
+ 'color.background.selected.bold': brandBackgroundIndex,
130
151
  'color.background.selected.bold.hovered': 7,
131
152
  'color.background.selected.bold.pressed': 8,
132
153
  'color.text.brand': 6,
@@ -153,7 +174,7 @@ export const generateTokenMap = (brandColor, mode, themeRamp) => {
153
174
  * Generate dark mode values using rule of symmetry
154
175
  */
155
176
  Object.entries(customThemeTokenMapLight).forEach(([key, value]) => {
156
- customThemeTokenMapDark[key] = 9 - value;
177
+ customThemeTokenMapDark[key] = 9 - (typeof value === 'string' ? closestColorIndex : value);
157
178
  });
158
179
 
159
180
  /**
@@ -179,7 +200,7 @@ export const generateTokenMap = (brandColor, mode, themeRamp) => {
179
200
  };
180
201
  };
181
202
  export const generateTokenMapWithContrastCheck = (brandColor, mode, themeRamp) => {
182
- const colors = themeRamp || generateColors(brandColor);
203
+ const colors = themeRamp || generateColors(brandColor).ramp;
183
204
  const tokenMaps = generateTokenMap(brandColor, mode, colors);
184
205
  const result = {};
185
206
  Object.entries(tokenMaps).forEach(([mode, map]) => {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/tokens",
3
- "version": "1.14.0",
3
+ "version": "1.14.1",
4
4
  "sideEffects": [
5
5
  "**/*.css"
6
6
  ]
@@ -37,7 +37,7 @@ function _getCustomThemeStyles() {
37
37
  mode = (themeState === null || themeState === void 0 ? void 0 : themeState.colorMode) || themeStateDefaults['colorMode'];
38
38
  optionString = JSON.stringify(themeState === null || themeState === void 0 ? void 0 : themeState.UNSAFE_themeOptions);
39
39
  uniqueId = hash(optionString);
40
- themeRamp = generateColors(brandColor); // outputs object to generate to CSS from
40
+ themeRamp = generateColors(brandColor).ramp; // outputs object to generate to CSS from
41
41
  themes = [];
42
42
  tokenMaps = generateTokenMapWithContrastCheck(brandColor, mode, themeRamp);
43
43
  if ((mode === 'light' || mode === 'auto') && tokenMaps.light) {
@@ -1,7 +1,7 @@
1
1
  import warnOnce from '@atlaskit/ds-lib/warn-once';
2
2
  import tokens from './artifacts/token-names';
3
3
  var name = "@atlaskit/tokens";
4
- var version = "1.14.0";
4
+ var version = "1.14.1";
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
  var name = "@atlaskit/tokens";
5
- var version = "1.14.0";
5
+ var version = "1.14.1";
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.
@@ -33,6 +33,6 @@ export function reduceTokenMap(tokenMap, themeRamp) {
33
33
  key = _ref2[0],
34
34
  value = _ref2[1];
35
35
  var cssVar = tokens[key];
36
- return cssVar ? "".concat(acc, "\n ").concat(cssVar, ": ").concat(themeRamp[value], ";") : acc;
36
+ return cssVar ? "".concat(acc, "\n ").concat(cssVar, ": ").concat(typeof value === 'string' ? value : themeRamp[value], ";") : acc;
37
37
  }, '');
38
38
  }
@@ -10,6 +10,14 @@ export var additionalChecks = [{
10
10
  // In light mode: darken the following tokens by one base token
11
11
  // In dark mode: lighten the following tokens by one base token
12
12
  'color.text.brand', 'color.text.selected', 'color.link', 'color.link.pressed', 'color.icon.brand', 'color.icon.selected']
13
+ }, {
14
+ foreground: 'color.text.brand',
15
+ backgroundLight: 'color.background.selected',
16
+ backgroundDark: 'color.background.selected',
17
+ desiredContrast: 4.5,
18
+ // In light mode: darken the following tokens by one base token
19
+ // In dark mode: lighten the following tokens by one base toke
20
+ updatedTokens: ['color.text.brand', 'color.link', 'color.link.pressed']
13
21
  }, {
14
22
  foreground: 'color.text.selected',
15
23
  backgroundLight: 'color.background.selected',
@@ -51,13 +59,17 @@ export var additionalContrastChecker = function additionalContrastChecker(_ref)
51
59
  desiredContrast = pairing.desiredContrast,
52
60
  updatedTokens = pairing.updatedTokens;
53
61
  var background = mode === 'light' ? backgroundLight : backgroundDark;
54
- var foregroundColor = brandTokens.includes(foreground) ? themeRamp[customThemeTokenMap[foreground]] : getColorFromTokenRaw(foreground, mode);
55
- var backgroundColor = brandTokens.includes(background) ? themeRamp[customThemeTokenMap[background]] : getColorFromTokenRaw(background, mode);
62
+ var foregroundTokenValue = customThemeTokenMap[foreground];
63
+ var backgroundTokenValue = customThemeTokenMap[background];
64
+ var foregroundColor = brandTokens.includes(foreground) ? typeof foregroundTokenValue === 'string' ? foregroundTokenValue : themeRamp[foregroundTokenValue] : getColorFromTokenRaw(foreground, mode);
65
+ var backgroundColor = brandTokens.includes(background) ? typeof backgroundTokenValue === 'string' ? backgroundTokenValue : themeRamp[backgroundTokenValue] : getColorFromTokenRaw(background, mode);
56
66
  var contrast = getContrastRatio(foregroundColor, backgroundColor);
57
67
  if (contrast <= desiredContrast) {
58
68
  updatedTokens.forEach(function (token) {
59
69
  var rampValue = customThemeTokenMap[token];
60
- updatedCustomThemeTokenMap[token] = mode === 'light' ? rampValue + 1 : rampValue - 1;
70
+ if (typeof rampValue === 'number') {
71
+ updatedCustomThemeTokenMap[token] = mode === 'light' ? rampValue + 1 : rampValue - 1;
72
+ }
61
73
  });
62
74
  }
63
75
  });
@@ -46,7 +46,11 @@ export var generateColors = function generateColors(brandColor) {
46
46
  // Replace closet color with brandColor
47
47
  var updatedThemeRamp = _toConsumableArray(themeRamp);
48
48
  updatedThemeRamp[closestColorIndex] = brandColor;
49
- return updatedThemeRamp;
49
+ return {
50
+ ramp: updatedThemeRamp,
51
+ // add the replaced color into the result
52
+ replacedColor: themeRamp[closestColorIndex]
53
+ };
50
54
  };
51
55
 
52
56
  /**
@@ -69,7 +73,10 @@ function getInteractionStates(rampPosition, number, colors) {
69
73
  return result;
70
74
  }
71
75
  export var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
72
- var colors = themeRamp || generateColors(brandColor);
76
+ var _generateColors = generateColors(brandColor),
77
+ ramp = _generateColors.ramp,
78
+ replacedColor = _generateColors.replacedColor;
79
+ var colors = themeRamp || ramp;
73
80
  var closestColorIndex = getClosestColorIndex(colors, brandColor);
74
81
  var customThemeTokenMapLight = {};
75
82
  var customThemeTokenMapDark = {};
@@ -85,6 +92,12 @@ export var generateTokenMap = function generateTokenMap(brandColor, mode, themeR
85
92
  _getInteractionStates2 = _slicedToArray(_getInteractionStates, 2),
86
93
  brandBoldSelectedHoveredIndex = _getInteractionStates2[0],
87
94
  brandBoldSelectedPressedIndex = _getInteractionStates2[1];
95
+ var brandTextIndex = closestColorIndex;
96
+ if (inputContrast < 5.4 && inputContrast >= 4.8 && closestColorIndex === 6) {
97
+ // Use the one-level darker closest color (X800) for color.text.brand
98
+ // and color.link to avoid contrast breaches
99
+ brandTextIndex = closestColorIndex + 1;
100
+ }
88
101
 
89
102
  /**
90
103
  * Generate interaction token for color.link:
@@ -94,11 +107,11 @@ export var generateTokenMap = function generateTokenMap(brandColor, mode, themeR
94
107
  * If inputted color replaces X700-X900
95
108
  * - Shift one 1 step darker
96
109
  */
97
- var _getInteractionStates3 = getInteractionStates(closestColorIndex, 1, colors),
110
+ var _getInteractionStates3 = getInteractionStates(brandTextIndex, 1, colors),
98
111
  _getInteractionStates4 = _slicedToArray(_getInteractionStates3, 1),
99
112
  linkPressed = _getInteractionStates4[0];
100
113
  customThemeTokenMapLight = {
101
- 'color.text.brand': closestColorIndex,
114
+ 'color.text.brand': brandTextIndex,
102
115
  'color.icon.brand': closestColorIndex,
103
116
  'color.background.brand.subtlest': 0,
104
117
  'color.background.brand.subtlest.hovered': 1,
@@ -110,13 +123,13 @@ export var generateTokenMap = function generateTokenMap(brandColor, mode, themeR
110
123
  'color.background.brand.boldest.hovered': 8,
111
124
  'color.background.brand.boldest.pressed': 7,
112
125
  'color.border.brand': closestColorIndex,
113
- 'color.text.selected': closestColorIndex,
126
+ 'color.text.selected': brandTextIndex,
114
127
  'color.icon.selected': closestColorIndex,
115
128
  'color.background.selected.bold': closestColorIndex,
116
129
  'color.background.selected.bold.hovered': brandBoldSelectedHoveredIndex,
117
130
  'color.background.selected.bold.pressed': brandBoldSelectedPressedIndex,
118
131
  'color.border.selected': closestColorIndex,
119
- 'color.link': closestColorIndex,
132
+ 'color.link': brandTextIndex,
120
133
  'color.link.pressed': linkPressed,
121
134
  'color.chart.brand': 5,
122
135
  'color.chart.brand.hovered': 6,
@@ -125,18 +138,25 @@ export var generateTokenMap = function generateTokenMap(brandColor, mode, themeR
125
138
  'color.background.selected.pressed': 2
126
139
  };
127
140
  } else {
141
+ var brandBackgroundIndex = 6;
142
+ if (inputContrast < 4.5 && inputContrast >= 4 && closestColorIndex === 6) {
143
+ // Use the generated closest color instead of the input brand color for
144
+ // color.background.selected.bold and color.background.brand.bold
145
+ // to avoid contrast breaches
146
+ brandBackgroundIndex = replacedColor;
147
+ }
128
148
  customThemeTokenMapLight = {
129
149
  'color.background.brand.subtlest': 0,
130
150
  'color.background.brand.subtlest.hovered': 1,
131
151
  'color.background.brand.subtlest.pressed': 2,
132
- 'color.background.brand.bold': 6,
152
+ 'color.background.brand.bold': brandBackgroundIndex,
133
153
  'color.background.brand.bold.hovered': 7,
134
154
  'color.background.brand.bold.pressed': 8,
135
155
  'color.background.brand.boldest': 9,
136
156
  'color.background.brand.boldest.hovered': 8,
137
157
  'color.background.brand.boldest.pressed': 7,
138
158
  'color.border.brand': 6,
139
- 'color.background.selected.bold': 6,
159
+ 'color.background.selected.bold': brandBackgroundIndex,
140
160
  'color.background.selected.bold.hovered': 7,
141
161
  'color.background.selected.bold.pressed': 8,
142
162
  'color.text.brand': 6,
@@ -166,7 +186,7 @@ export var generateTokenMap = function generateTokenMap(brandColor, mode, themeR
166
186
  var _ref2 = _slicedToArray(_ref, 2),
167
187
  key = _ref2[0],
168
188
  value = _ref2[1];
169
- customThemeTokenMapDark[key] = 9 - value;
189
+ customThemeTokenMapDark[key] = 9 - (typeof value === 'string' ? closestColorIndex : value);
170
190
  });
171
191
 
172
192
  /**
@@ -192,7 +212,7 @@ export var generateTokenMap = function generateTokenMap(brandColor, mode, themeR
192
212
  };
193
213
  };
194
214
  export var generateTokenMapWithContrastCheck = function generateTokenMapWithContrastCheck(brandColor, mode, themeRamp) {
195
- var colors = themeRamp || generateColors(brandColor);
215
+ var colors = themeRamp || generateColors(brandColor).ramp;
196
216
  var tokenMaps = generateTokenMap(brandColor, mode, colors);
197
217
  var result = {};
198
218
  Object.entries(tokenMaps).forEach(function (_ref3) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/tokens",
3
- "version": "1.14.0",
3
+ "version": "1.14.1",
4
4
  "sideEffects": [
5
5
  "**/*.css"
6
6
  ]
@@ -5,6 +5,6 @@ type ThemeAttributeId = 'light' | 'dark';
5
5
  export declare function findMissingCustomStyleElements(UNSAFE_themeOptions: ThemeOptionsSchema, mode: ThemeColorModes): ThemeAttributeId[];
6
6
  export declare function limitSizeOfCustomStyleElements(sizeThreshold: number): void;
7
7
  export declare function reduceTokenMap(tokenMap: {
8
- [key in Token]?: number;
8
+ [key in Token]?: number | string;
9
9
  }, themeRamp: string[]): string;
10
10
  export {};
@@ -10,7 +10,7 @@ interface AdditionalContrastCheck {
10
10
  export declare const additionalChecks: AdditionalContrastCheck[];
11
11
  export declare const additionalContrastChecker: ({ customThemeTokenMap, mode, themeRamp, }: {
12
12
  customThemeTokenMap: {
13
- [key: string]: number;
13
+ [key: string]: string | number;
14
14
  };
15
15
  mode: 'light' | 'dark';
16
16
  themeRamp: string[];
@@ -2,11 +2,14 @@ import tokens from '../artifacts/token-names';
2
2
  import { CSSColor, ThemeColorModes } from '../theme-config';
3
3
  type Token = keyof typeof tokens;
4
4
  type TokenMap = {
5
- [key in Token]?: number;
5
+ [key in Token]?: number | string;
6
6
  };
7
7
  type Mode = 'light' | 'dark';
8
8
  export declare const getClosestColorIndex: (themeRamp: CSSColor[], brandColor: CSSColor) => number;
9
- export declare const generateColors: (brandColor: CSSColor) => CSSColor[];
9
+ export declare const generateColors: (brandColor: CSSColor) => {
10
+ ramp: CSSColor[];
11
+ replacedColor: CSSColor;
12
+ };
10
13
  export declare const generateTokenMap: (brandColor: CSSColor, mode: ThemeColorModes, themeRamp?: CSSColor[]) => {
11
14
  light?: TokenMap | undefined;
12
15
  dark?: TokenMap | undefined;
@@ -5,6 +5,6 @@ type ThemeAttributeId = 'light' | 'dark';
5
5
  export declare function findMissingCustomStyleElements(UNSAFE_themeOptions: ThemeOptionsSchema, mode: ThemeColorModes): ThemeAttributeId[];
6
6
  export declare function limitSizeOfCustomStyleElements(sizeThreshold: number): void;
7
7
  export declare function reduceTokenMap(tokenMap: {
8
- [key in Token]?: number;
8
+ [key in Token]?: number | string;
9
9
  }, themeRamp: string[]): string;
10
10
  export {};
@@ -10,7 +10,7 @@ interface AdditionalContrastCheck {
10
10
  export declare const additionalChecks: AdditionalContrastCheck[];
11
11
  export declare const additionalContrastChecker: ({ customThemeTokenMap, mode, themeRamp, }: {
12
12
  customThemeTokenMap: {
13
- [key: string]: number;
13
+ [key: string]: string | number;
14
14
  };
15
15
  mode: 'light' | 'dark';
16
16
  themeRamp: string[];
@@ -2,11 +2,14 @@ import tokens from '../artifacts/token-names';
2
2
  import { CSSColor, ThemeColorModes } from '../theme-config';
3
3
  type Token = keyof typeof tokens;
4
4
  type TokenMap = {
5
- [key in Token]?: number;
5
+ [key in Token]?: number | string;
6
6
  };
7
7
  type Mode = 'light' | 'dark';
8
8
  export declare const getClosestColorIndex: (themeRamp: CSSColor[], brandColor: CSSColor) => number;
9
- export declare const generateColors: (brandColor: CSSColor) => CSSColor[];
9
+ export declare const generateColors: (brandColor: CSSColor) => {
10
+ ramp: CSSColor[];
11
+ replacedColor: CSSColor;
12
+ };
10
13
  export declare const generateTokenMap: (brandColor: CSSColor, mode: ThemeColorModes, themeRamp?: CSSColor[]) => {
11
14
  light?: TokenMap | undefined;
12
15
  dark?: TokenMap | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/tokens",
3
- "version": "1.14.0",
3
+ "version": "1.14.1",
4
4
  "description": "Design tokens are the single source of truth to name and store design decisions.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"