@atlaskit/tokens 1.11.3 → 1.12.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 (102) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/artifacts/atlassian-dark-token-value-for-contrast-check.js +24 -0
  3. package/dist/cjs/artifacts/atlassian-light-token-value-for-contrast-check.js +24 -0
  4. package/dist/cjs/constants.js +3 -1
  5. package/dist/cjs/custom-theme.js +108 -0
  6. package/dist/cjs/get-token-value.js +1 -1
  7. package/dist/cjs/get-token.js +1 -1
  8. package/dist/cjs/set-global-theme.js +156 -59
  9. package/dist/cjs/utils/color-utils.js +178 -0
  10. package/dist/cjs/utils/custom-theme-loading-utils.js +47 -0
  11. package/dist/cjs/utils/custom-theme-token-contrast-check.js +74 -0
  12. package/dist/cjs/utils/generate-custom-color-ramp.js +213 -0
  13. package/dist/cjs/utils/hash.js +17 -0
  14. package/dist/cjs/utils/hct-color-utils/color-utils.js +310 -0
  15. package/dist/cjs/utils/hct-color-utils/contrast.js +188 -0
  16. package/dist/cjs/utils/hct-color-utils/hct.js +1036 -0
  17. package/dist/cjs/utils/hct-color-utils/index.js +32 -0
  18. package/dist/cjs/utils/hct-color-utils/math-utils.js +159 -0
  19. package/dist/cjs/utils/theme-loading.js +1 -1
  20. package/dist/cjs/utils/theme-state-transformer.js +1 -1
  21. package/dist/cjs/version.json +1 -1
  22. package/dist/es2019/artifacts/atlassian-dark-token-value-for-contrast-check.js +17 -0
  23. package/dist/es2019/artifacts/atlassian-light-token-value-for-contrast-check.js +17 -0
  24. package/dist/es2019/constants.js +1 -0
  25. package/dist/es2019/custom-theme.js +77 -0
  26. package/dist/es2019/get-token-value.js +1 -1
  27. package/dist/es2019/get-token.js +1 -1
  28. package/dist/es2019/set-global-theme.js +67 -13
  29. package/dist/es2019/utils/color-utils.js +154 -0
  30. package/dist/es2019/utils/custom-theme-loading-utils.js +31 -0
  31. package/dist/es2019/utils/custom-theme-token-contrast-check.js +68 -0
  32. package/dist/es2019/utils/generate-custom-color-ramp.js +187 -0
  33. package/dist/es2019/utils/hash.js +10 -0
  34. package/dist/es2019/utils/hct-color-utils/color-utils.js +286 -0
  35. package/dist/es2019/utils/hct-color-utils/contrast.js +161 -0
  36. package/dist/es2019/utils/hct-color-utils/hct.js +931 -0
  37. package/dist/es2019/utils/hct-color-utils/index.js +3 -0
  38. package/dist/es2019/utils/hct-color-utils/math-utils.js +145 -0
  39. package/dist/es2019/utils/theme-loading.js +2 -2
  40. package/dist/es2019/utils/theme-state-transformer.js +3 -1
  41. package/dist/es2019/version.json +1 -1
  42. package/dist/esm/artifacts/atlassian-dark-token-value-for-contrast-check.js +17 -0
  43. package/dist/esm/artifacts/atlassian-light-token-value-for-contrast-check.js +17 -0
  44. package/dist/esm/constants.js +1 -0
  45. package/dist/esm/custom-theme.js +98 -0
  46. package/dist/esm/get-token-value.js +1 -1
  47. package/dist/esm/get-token.js +1 -1
  48. package/dist/esm/set-global-theme.js +149 -60
  49. package/dist/esm/utils/color-utils.js +162 -0
  50. package/dist/esm/utils/custom-theme-loading-utils.js +38 -0
  51. package/dist/esm/utils/custom-theme-token-contrast-check.js +65 -0
  52. package/dist/esm/utils/generate-custom-color-ramp.js +202 -0
  53. package/dist/esm/utils/hash.js +10 -0
  54. package/dist/esm/utils/hct-color-utils/color-utils.js +285 -0
  55. package/dist/esm/utils/hct-color-utils/contrast.js +181 -0
  56. package/dist/esm/utils/hct-color-utils/hct.js +1029 -0
  57. package/dist/esm/utils/hct-color-utils/index.js +3 -0
  58. package/dist/esm/utils/hct-color-utils/math-utils.js +145 -0
  59. package/dist/esm/utils/theme-loading.js +2 -2
  60. package/dist/esm/utils/theme-state-transformer.js +1 -1
  61. package/dist/esm/version.json +1 -1
  62. package/dist/types/artifacts/atlassian-dark-token-value-for-contrast-check.d.ts +17 -0
  63. package/dist/types/artifacts/atlassian-light-token-value-for-contrast-check.d.ts +17 -0
  64. package/dist/types/constants.d.ts +1 -0
  65. package/dist/types/custom-theme.d.ts +30 -0
  66. package/dist/types/index.d.ts +1 -0
  67. package/dist/types/set-global-theme.d.ts +9 -3
  68. package/dist/types/tokens/atlassian-dark/utility/utility.d.ts +1 -1
  69. package/dist/types/tokens/atlassian-light/utility/utility.d.ts +1 -1
  70. package/dist/types/tokens/default/utility/utility.d.ts +1 -1
  71. package/dist/types/utils/color-utils.d.ts +10 -0
  72. package/dist/types/utils/custom-theme-loading-utils.d.ts +11 -0
  73. package/dist/types/utils/custom-theme-token-contrast-check.d.ts +20 -0
  74. package/dist/types/utils/generate-custom-color-ramp.d.ts +19 -0
  75. package/dist/types/utils/hash.d.ts +1 -0
  76. package/dist/types/utils/hct-color-utils/color-utils.d.ts +131 -0
  77. package/dist/types/utils/hct-color-utils/contrast.d.ts +78 -0
  78. package/dist/types/utils/hct-color-utils/hct.d.ts +137 -0
  79. package/dist/types/utils/hct-color-utils/index.d.ts +3 -0
  80. package/dist/types/utils/hct-color-utils/math-utils.d.ts +86 -0
  81. package/dist/types-ts4.5/artifacts/atlassian-dark-token-value-for-contrast-check.d.ts +17 -0
  82. package/dist/types-ts4.5/artifacts/atlassian-light-token-value-for-contrast-check.d.ts +17 -0
  83. package/dist/types-ts4.5/constants.d.ts +1 -0
  84. package/dist/types-ts4.5/custom-theme.d.ts +30 -0
  85. package/dist/types-ts4.5/index.d.ts +1 -0
  86. package/dist/types-ts4.5/set-global-theme.d.ts +9 -3
  87. package/dist/types-ts4.5/tokens/atlassian-dark/utility/utility.d.ts +1 -1
  88. package/dist/types-ts4.5/tokens/atlassian-light/utility/utility.d.ts +1 -1
  89. package/dist/types-ts4.5/tokens/default/utility/utility.d.ts +1 -1
  90. package/dist/types-ts4.5/utils/color-utils.d.ts +27 -0
  91. package/dist/types-ts4.5/utils/custom-theme-loading-utils.d.ts +11 -0
  92. package/dist/types-ts4.5/utils/custom-theme-token-contrast-check.d.ts +20 -0
  93. package/dist/types-ts4.5/utils/generate-custom-color-ramp.d.ts +19 -0
  94. package/dist/types-ts4.5/utils/hash.d.ts +1 -0
  95. package/dist/types-ts4.5/utils/hct-color-utils/color-utils.d.ts +131 -0
  96. package/dist/types-ts4.5/utils/hct-color-utils/contrast.d.ts +78 -0
  97. package/dist/types-ts4.5/utils/hct-color-utils/hct.d.ts +137 -0
  98. package/dist/types-ts4.5/utils/hct-color-utils/index.d.ts +3 -0
  99. package/dist/types-ts4.5/utils/hct-color-utils/math-utils.d.ts +86 -0
  100. package/package.json +35 -36
  101. package/report.api.md +24 -1
  102. package/tmp/api-report-tmp.d.ts +0 -1132
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.HSLToRGB = HSLToRGB;
7
+ exports.deltaE = deltaE;
8
+ exports.getAlpha = getAlpha;
9
+ exports.getContrastRatio = getContrastRatio;
10
+ exports.hexToHSL = hexToHSL;
11
+ exports.hexToRgb = hexToRgb;
12
+ exports.hexToRgbA = hexToRgbA;
13
+ exports.isValidBrandHex = void 0;
14
+ exports.relativeLuminanceW3C = relativeLuminanceW3C;
15
+ exports.rgbToHex = rgbToHex;
16
+ // valid hex color with 6 digits
17
+ var isValidBrandHex = function isValidBrandHex(hex) {
18
+ return /^#[0-9A-F]{6}$/i.test(hex);
19
+ };
20
+
21
+ // valid hex color with 4, 6 or 8 digits
22
+ exports.isValidBrandHex = isValidBrandHex;
23
+ var isValidHex = function isValidHex(hex) {
24
+ return /^#([A-Fa-f0-9]{3,4}){1,2}$/.test(hex);
25
+ };
26
+ function rgbToHex(r, g, b) {
27
+ return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
28
+ }
29
+ function getAlpha(hex) {
30
+ if (hex.length === 9) {
31
+ var int = parseInt(hex.slice(7, 9), 16) / 255;
32
+ return Number(parseFloat(int.toString()).toFixed(2));
33
+ }
34
+ return 1;
35
+ }
36
+ function hexToRgbA(hex) {
37
+ if (!isValidHex(hex)) {
38
+ throw new Error('Invalid HEX');
39
+ }
40
+ var c;
41
+ c = hex.substring(1).split('');
42
+ if (c.length === 3) {
43
+ c = [c[0], c[0], c[1], c[1], c[2], c[2]];
44
+ }
45
+ c = '0x' + c.join('');
46
+ return [c >> 16 & 255, c >> 8 & 255, c & 255, getAlpha(hex)];
47
+ }
48
+ function hexToRgb(hex) {
49
+ if (!isValidHex(hex)) {
50
+ throw new Error('Invalid HEX');
51
+ }
52
+ var c;
53
+ c = hex.substring(1).split('');
54
+ if (c.length === 3) {
55
+ c = [c[0], c[0], c[1], c[1], c[2], c[2]];
56
+ }
57
+ c = '0x' + c.join('');
58
+ return [c >> 16 & 255, c >> 8 & 255, c & 255];
59
+ }
60
+ function hexToHSL(hex) {
61
+ if (!isValidHex(hex)) {
62
+ throw new Error('Invalid HEX');
63
+ }
64
+ var r = 0,
65
+ g = 0,
66
+ b = 0;
67
+ if (hex.length === 4) {
68
+ r = '0x' + hex[1] + hex[1];
69
+ g = '0x' + hex[2] + hex[2];
70
+ b = '0x' + hex[3] + hex[3];
71
+ } else if (hex.length === 7) {
72
+ r = '0x' + hex[1] + hex[2];
73
+ g = '0x' + hex[3] + hex[4];
74
+ b = '0x' + hex[5] + hex[6];
75
+ }
76
+ // Then to HSL
77
+ r /= 255;
78
+ g /= 255;
79
+ b /= 255;
80
+ var cmin = Math.min(r, g, b),
81
+ cmax = Math.max(r, g, b),
82
+ delta = cmax - cmin,
83
+ h = 0,
84
+ s = 0,
85
+ l = 0;
86
+ if (delta === 0) {
87
+ h = 0;
88
+ } else if (cmax === r) {
89
+ h = (g - b) / delta % 6;
90
+ } else if (cmax === g) {
91
+ h = (b - r) / delta + 2;
92
+ } else {
93
+ h = (r - g) / delta + 4;
94
+ }
95
+ h = Math.round(h * 60);
96
+ if (h < 0) {
97
+ h += 360;
98
+ }
99
+ l = (cmax + cmin) / 2;
100
+ s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
101
+ s = +(s * 100).toFixed(1);
102
+ l = +(l * 100).toFixed(1);
103
+ return [h, s, l];
104
+ }
105
+ function HSLToRGB(h, s, l) {
106
+ s /= 100;
107
+ l /= 100;
108
+ var k = function k(n) {
109
+ return (n + h / 30) % 12;
110
+ };
111
+ var a = s * Math.min(l, 1 - l);
112
+ var f = function f(n) {
113
+ return l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
114
+ };
115
+ return [255 * f(0), 255 * f(8), 255 * f(4)];
116
+ }
117
+ function relativeLuminanceW3C(r, g, b) {
118
+ var RsRGB = r / 255;
119
+ var GsRGB = g / 255;
120
+ var BsRGB = b / 255;
121
+ var R = RsRGB <= 0.03928 ? RsRGB / 12.92 : Math.pow((RsRGB + 0.055) / 1.055, 2.4);
122
+ var G = GsRGB <= 0.03928 ? GsRGB / 12.92 : Math.pow((GsRGB + 0.055) / 1.055, 2.4);
123
+ var B = BsRGB <= 0.03928 ? BsRGB / 12.92 : Math.pow((BsRGB + 0.055) / 1.055, 2.4);
124
+
125
+ // For the sRGB colorspace, the relative luminance of a color is defined as:
126
+ var L = 0.2126 * R + 0.7152 * G + 0.0722 * B;
127
+ return L;
128
+ }
129
+ function getContrastRatio(foreground, background) {
130
+ if (!isValidHex(foreground) || !isValidHex(background)) {
131
+ throw new Error('Invalid HEX');
132
+ }
133
+ var foregroundRgb = hexToRgb(foreground);
134
+ var backgroundRgb = hexToRgb(background);
135
+ var foregroundLuminance = relativeLuminanceW3C(foregroundRgb[0], foregroundRgb[1], foregroundRgb[2]);
136
+ var backgroundLuminance = relativeLuminanceW3C(backgroundRgb[0], backgroundRgb[1], backgroundRgb[2]);
137
+ // calculate the color contrast ratio
138
+ var brightest = Math.max(foregroundLuminance, backgroundLuminance);
139
+ var darkest = Math.min(foregroundLuminance, backgroundLuminance);
140
+ return (brightest + 0.05) / (darkest + 0.05);
141
+ }
142
+ function deltaE(rgbA, rgbB) {
143
+ var labA = rgbToLab(rgbA);
144
+ var labB = rgbToLab(rgbB);
145
+ var deltaL = labA[0] - labB[0];
146
+ var deltaA = labA[1] - labB[1];
147
+ var deltaB = labA[2] - labB[2];
148
+ var c1 = Math.sqrt(labA[1] * labA[1] + labA[2] * labA[2]);
149
+ var c2 = Math.sqrt(labB[1] * labB[1] + labB[2] * labB[2]);
150
+ var deltaC = c1 - c2;
151
+ var deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC;
152
+ deltaH = deltaH < 0 ? 0 : Math.sqrt(deltaH);
153
+ var sc = 1.0 + 0.045 * c1;
154
+ var sh = 1.0 + 0.015 * c1;
155
+ var deltaLKlsl = deltaL / 1.0;
156
+ var deltaCkcsc = deltaC / sc;
157
+ var deltaHkhsh = deltaH / sh;
158
+ var i = deltaLKlsl * deltaLKlsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh;
159
+ return i < 0 ? 0 : Math.sqrt(i);
160
+ }
161
+ function rgbToLab(rgb) {
162
+ var r = rgb[0] / 255,
163
+ g = rgb[1] / 255,
164
+ b = rgb[2] / 255,
165
+ x,
166
+ y,
167
+ z;
168
+ r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
169
+ g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
170
+ b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
171
+ x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
172
+ y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.0;
173
+ z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
174
+ x = x > 0.008856 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116;
175
+ y = y > 0.008856 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
176
+ z = z > 0.008856 ? Math.pow(z, 1 / 3) : 7.787 * z + 16 / 116;
177
+ return [116 * y - 16, 500 * (x - y), 200 * (y - z)];
178
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.findMissingCustomStyleElements = findMissingCustomStyleElements;
8
+ exports.limitSizeOfCustomStyleElements = limitSizeOfCustomStyleElements;
9
+ exports.reduceTokenMap = reduceTokenMap;
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
12
+ var _tokenNames = _interopRequireDefault(require("../artifacts/token-names"));
13
+ var _constants = require("../constants");
14
+ var _hash = require("./hash");
15
+ function findMissingCustomStyleElements(UNSAFE_themeOptions, mode) {
16
+ var optionString = JSON.stringify(UNSAFE_themeOptions);
17
+ var uniqueId = (0, _hash.hash)(optionString);
18
+ var attrOfMissingCustomStyles = [];
19
+ (mode === 'auto' ? ['light', 'dark'] : [mode]).forEach(function (themeId) {
20
+ var element = document.head.querySelector("style[".concat(_constants.CUSTOM_THEME_ATTRIBUTE, "=\"").concat(uniqueId, "\"][").concat(_constants.THEME_DATA_ATTRIBUTE, "=\"").concat(themeId, "\"]"));
21
+ if (element) {
22
+ // Append the existing custom styles to take precedence over others
23
+ document.head.appendChild(element);
24
+ } else {
25
+ attrOfMissingCustomStyles.push(themeId);
26
+ }
27
+ });
28
+ return attrOfMissingCustomStyles;
29
+ }
30
+ function limitSizeOfCustomStyleElements(sizeThreshold) {
31
+ var styleTags = (0, _toConsumableArray2.default)(document.head.querySelectorAll("style[".concat(_constants.CUSTOM_THEME_ATTRIBUTE, "][").concat(_constants.THEME_DATA_ATTRIBUTE, "]")));
32
+ if (styleTags.length < sizeThreshold) {
33
+ return;
34
+ }
35
+ styleTags.slice(0, styleTags.length - (sizeThreshold - 1)).forEach(function (element) {
36
+ return element.remove();
37
+ });
38
+ }
39
+ function reduceTokenMap(tokenMap, themeRamp) {
40
+ return Object.entries(tokenMap).reduce(function (acc, _ref) {
41
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
42
+ key = _ref2[0],
43
+ value = _ref2[1];
44
+ var cssVar = _tokenNames.default[key];
45
+ return cssVar ? "".concat(acc, "\n ").concat(cssVar, ": ").concat(themeRamp[value], ";") : acc;
46
+ }, '');
47
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.additionalContrastChecker = exports.additionalChecks = void 0;
8
+ var _atlassianDarkTokenValueForContrastCheck = _interopRequireDefault(require("../artifacts/atlassian-dark-token-value-for-contrast-check"));
9
+ var _atlassianLightTokenValueForContrastCheck = _interopRequireDefault(require("../artifacts/atlassian-light-token-value-for-contrast-check"));
10
+ var _colorUtils = require("./color-utils");
11
+ var additionalChecks = [{
12
+ foreground: 'color.text.brand',
13
+ backgroundLight: 'elevation.surface.sunken',
14
+ backgroundDark: 'elevation.surface.overlay',
15
+ desiredContrast: 4.5,
16
+ updatedTokens: [
17
+ // In light mode: darken the following tokens by one base token
18
+ // In dark mode: lighten the following tokens by one base token
19
+ 'color.text.brand', 'color.text.selected', 'color.link', 'color.link.pressed', 'color.icon.brand', 'color.icon.selected']
20
+ }, {
21
+ foreground: 'color.text.selected',
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 token
27
+ updatedTokens: ['color.text.selected', 'color.icon.selected']
28
+ }, {
29
+ foreground: 'color.border.brand',
30
+ backgroundLight: 'elevation.surface.sunken',
31
+ backgroundDark: 'elevation.surface.overlay',
32
+ desiredContrast: 3,
33
+ // In light mode: darken the following tokens by one base token
34
+ // In dark mode: lighten the following tokens by one base toke
35
+ updatedTokens: ['color.border.brand', 'color.border.selected']
36
+ }, {
37
+ foreground: 'color.chart.brand',
38
+ backgroundLight: 'elevation.surface.sunken',
39
+ backgroundDark: 'elevation.surface.overlay',
40
+ desiredContrast: 3,
41
+ // In light mode: darken the following tokens by one base token
42
+ // In dark mode: lighten the following tokens by one base token
43
+ updatedTokens: ['color.chart.brand', 'color.chart.brand.hovered']
44
+ }];
45
+ exports.additionalChecks = additionalChecks;
46
+ var getColorFromTokenRaw = function getColorFromTokenRaw(tokenName, mode) {
47
+ return mode === 'light' ? _atlassianLightTokenValueForContrastCheck.default[tokenName] : _atlassianDarkTokenValueForContrastCheck.default[tokenName];
48
+ };
49
+ var additionalContrastChecker = function additionalContrastChecker(_ref) {
50
+ var customThemeTokenMap = _ref.customThemeTokenMap,
51
+ mode = _ref.mode,
52
+ themeRamp = _ref.themeRamp;
53
+ var updatedCustomThemeTokenMap = {};
54
+ var brandTokens = Object.keys(customThemeTokenMap);
55
+ additionalChecks.forEach(function (pairing) {
56
+ var backgroundLight = pairing.backgroundLight,
57
+ backgroundDark = pairing.backgroundDark,
58
+ foreground = pairing.foreground,
59
+ desiredContrast = pairing.desiredContrast,
60
+ updatedTokens = pairing.updatedTokens;
61
+ 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);
64
+ var contrast = (0, _colorUtils.getContrastRatio)(foregroundColor, backgroundColor);
65
+ if (contrast <= desiredContrast) {
66
+ updatedTokens.forEach(function (token) {
67
+ var rampValue = customThemeTokenMap[token];
68
+ updatedCustomThemeTokenMap[token] = mode === 'light' ? rampValue + 1 : rampValue - 1;
69
+ });
70
+ }
71
+ });
72
+ return updatedCustomThemeTokenMap;
73
+ };
74
+ exports.additionalContrastChecker = additionalContrastChecker;
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getClosestColorIndex = exports.generateTokenMapWithContrastCheck = exports.generateTokenMap = exports.generateColors = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
+ var _atlassianDark = _interopRequireDefault(require("../artifacts/tokens-raw/atlassian-dark"));
12
+ var _colorUtils = require("./color-utils");
13
+ var _customThemeTokenContrastCheck = require("./custom-theme-token-contrast-check");
14
+ var _hctColorUtils = require("./hct-color-utils");
15
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
16
+ 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) { (0, _defineProperty2.default)(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; }
17
+ var lowLuminanceContrastRatios = [1.12, 1.33, 2.03, 2.73, 3.33, 4.27, 5.2, 6.62, 12.46, 15.98];
18
+ var highLuminanceContrastRatios = [1.08, 1.24, 1.55, 1.99, 2.45, 3.34, 4.64, 6.1, 10.19, 13.43];
19
+ var getClosestColorIndex = function getClosestColorIndex(themeRamp, brandColor) {
20
+ // Iterate over themeRamp and find whichever color is closest to brandColor
21
+ var closestColorIndex = 0;
22
+ var closestColorDistance = null;
23
+ themeRamp.forEach(function (value, index) {
24
+ var distance = (0, _colorUtils.deltaE)((0, _colorUtils.hexToRgb)(value), (0, _colorUtils.hexToRgb)(brandColor));
25
+ if (closestColorDistance === null || distance < closestColorDistance) {
26
+ closestColorIndex = index;
27
+ closestColorDistance = distance;
28
+ }
29
+ });
30
+ return closestColorIndex;
31
+ };
32
+ exports.getClosestColorIndex = getClosestColorIndex;
33
+ var generateColors = function generateColors(brandColor) {
34
+ // Determine luminance
35
+ var HSLBrandColorHue = (0, _colorUtils.hexToHSL)(brandColor)[0];
36
+ var baseRgb = (0, _colorUtils.HSLToRGB)(HSLBrandColorHue, 100, 60);
37
+ var isLowLuminance = (0, _colorUtils.relativeLuminanceW3C)(baseRgb[0], baseRgb[1], baseRgb[2]) < 0.4;
38
+ // Choose right palette
39
+ var themeRatios = isLowLuminance ? lowLuminanceContrastRatios : highLuminanceContrastRatios;
40
+ var brandRgba = (0, _colorUtils.hexToRgbA)(brandColor);
41
+ var hctColor = _hctColorUtils.Hct.fromInt((0, _hctColorUtils.argbFromRgba)({
42
+ r: brandRgba[0],
43
+ g: brandRgba[1],
44
+ b: brandRgba[2],
45
+ a: brandRgba[3]
46
+ }));
47
+ var themeRamp = themeRatios.map(function (contrast) {
48
+ var rgbaColor = (0, _hctColorUtils.rgbaFromArgb)(_hctColorUtils.Hct.from(hctColor.hue, hctColor.chroma, _hctColorUtils.Contrast.darker(100, contrast) + 0.25 // Material's utils provide an offset
49
+ ).toInt());
50
+ return (0, _colorUtils.rgbToHex)(rgbaColor.r, rgbaColor.g, rgbaColor.b);
51
+ });
52
+ var closestColorIndex = getClosestColorIndex(themeRamp, brandColor);
53
+
54
+ // Replace closet color with brandColor
55
+ var updatedThemeRamp = (0, _toConsumableArray2.default)(themeRamp);
56
+ updatedThemeRamp[closestColorIndex] = brandColor;
57
+ return updatedThemeRamp;
58
+ };
59
+
60
+ /**
61
+ * Return the interaction tokens for a color, given its ramp position and the number of
62
+ * needed interaction states. Use higher-indexed colors (i.e. darker colors) if possible;
63
+ * if there's not enough room to shift up for the required number of interaction tokens,
64
+ * it goes as far as it can, then returns lighter colors lower down the ramp instead.
65
+ *
66
+ * Returns an array of the resulting colors
67
+ */
68
+ exports.generateColors = generateColors;
69
+ function getInteractionStates(rampPosition, number, colors) {
70
+ var result = [];
71
+ for (var i = 1; i <= number; i++) {
72
+ if (rampPosition + i < colors.length) {
73
+ result.push(rampPosition + i);
74
+ } else {
75
+ result.push(rampPosition - (i - (colors.length - 1 - rampPosition)));
76
+ }
77
+ }
78
+ return result;
79
+ }
80
+ var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
81
+ var colors = themeRamp || generateColors(brandColor);
82
+ var closestColorIndex = getClosestColorIndex(colors, brandColor);
83
+ var customThemeTokenMapLight = {};
84
+ var customThemeTokenMapDark = {};
85
+ var inputContrast = (0, _colorUtils.getContrastRatio)(brandColor, '#FFFFFF');
86
+ // Branch based on brandColor's contrast against white
87
+ if (inputContrast >= 4.5) {
88
+ /**
89
+ * Generate interaction tokens for
90
+ * - color.background.brand.bold
91
+ * - color.background.selected.bold
92
+ */
93
+ var _getInteractionStates = getInteractionStates(closestColorIndex, 2, colors),
94
+ _getInteractionStates2 = (0, _slicedToArray2.default)(_getInteractionStates, 2),
95
+ brandBoldSelectedHoveredIndex = _getInteractionStates2[0],
96
+ brandBoldSelectedPressedIndex = _getInteractionStates2[1];
97
+
98
+ /**
99
+ * Generate interaction token for color.link:
100
+ * If inputted color replaces X1000
101
+ * - Pressed = X900
102
+ *
103
+ * If inputted color replaces X700-X900
104
+ * - Shift one 1 step darker
105
+ */
106
+ var _getInteractionStates3 = getInteractionStates(closestColorIndex, 1, colors),
107
+ _getInteractionStates4 = (0, _slicedToArray2.default)(_getInteractionStates3, 1),
108
+ linkPressed = _getInteractionStates4[0];
109
+ customThemeTokenMapLight = {
110
+ 'color.text.brand': closestColorIndex,
111
+ 'color.icon.brand': closestColorIndex,
112
+ 'color.background.brand.bold': closestColorIndex,
113
+ 'color.background.brand.bold.hovered': brandBoldSelectedHoveredIndex,
114
+ 'color.background.brand.bold.pressed': brandBoldSelectedPressedIndex,
115
+ 'color.border.brand': closestColorIndex,
116
+ 'color.text.selected': closestColorIndex,
117
+ 'color.icon.selected': closestColorIndex,
118
+ 'color.background.selected.bold': closestColorIndex,
119
+ 'color.background.selected.bold.hovered': brandBoldSelectedHoveredIndex,
120
+ 'color.background.selected.bold.pressed': brandBoldSelectedPressedIndex,
121
+ 'color.border.selected': closestColorIndex,
122
+ 'color.link': closestColorIndex,
123
+ 'color.link.pressed': linkPressed,
124
+ 'color.chart.brand': 5,
125
+ 'color.chart.brand.hovered': 6,
126
+ 'color.background.selected': 0,
127
+ 'color.background.selected.hovered': 1,
128
+ 'color.background.selected.pressed': 2
129
+ };
130
+ } else {
131
+ customThemeTokenMapLight = {
132
+ 'color.background.brand.bold': 6,
133
+ 'color.background.brand.bold.hovered': 7,
134
+ 'color.background.brand.bold.pressed': 8,
135
+ 'color.border.brand': 6,
136
+ 'color.background.selected.bold': 6,
137
+ 'color.background.selected.bold.hovered': 7,
138
+ 'color.background.selected.bold.pressed': 8,
139
+ 'color.text.brand': 6,
140
+ 'color.icon.brand': 6,
141
+ 'color.chart.brand': 5,
142
+ 'color.chart.brand.hovered': 6,
143
+ 'color.text.selected': 6,
144
+ 'color.icon.selected': 6,
145
+ 'color.border.selected': 6,
146
+ 'color.background.selected': 0,
147
+ 'color.background.selected.hovered': 1,
148
+ 'color.background.selected.pressed': 2,
149
+ 'color.link': 6,
150
+ 'color.link.pressed': 7
151
+ };
152
+ }
153
+ if (mode === 'light') {
154
+ return {
155
+ light: customThemeTokenMapLight
156
+ };
157
+ }
158
+
159
+ /**
160
+ * Generate dark mode values using rule of symmetry
161
+ */
162
+ Object.entries(customThemeTokenMapLight).forEach(function (_ref) {
163
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
164
+ key = _ref2[0],
165
+ value = _ref2[1];
166
+ customThemeTokenMapDark[key] = 9 - value;
167
+ });
168
+
169
+ /**
170
+ * If the input brand color < 4.5, and it meets 4.5 contrast again inverse text color
171
+ * in dark mode, shift color.background.brand.bold to the brand color
172
+ */
173
+ if (inputContrast < 4.5) {
174
+ var _rawTokensDark$find;
175
+ var inverseTextColor = (_rawTokensDark$find = _atlassianDark.default.find(function (token) {
176
+ return token.cleanName === 'color.text.inverse';
177
+ })) === null || _rawTokensDark$find === void 0 ? void 0 : _rawTokensDark$find.value;
178
+ if ((0, _colorUtils.getContrastRatio)(inverseTextColor, brandColor) >= 4.5 && closestColorIndex >= 2) {
179
+ customThemeTokenMapDark['color.background.brand.bold'] = closestColorIndex;
180
+ customThemeTokenMapDark['color.background.brand.bold.hovered'] = closestColorIndex - 1;
181
+ customThemeTokenMapDark['color.background.brand.bold.pressed'] = closestColorIndex - 2;
182
+ }
183
+ }
184
+ if (mode === 'dark') {
185
+ return {
186
+ dark: customThemeTokenMapDark
187
+ };
188
+ }
189
+ return {
190
+ light: customThemeTokenMapLight,
191
+ dark: customThemeTokenMapDark
192
+ };
193
+ };
194
+ exports.generateTokenMap = generateTokenMap;
195
+ var generateTokenMapWithContrastCheck = function generateTokenMapWithContrastCheck(brandColor, mode, themeRamp) {
196
+ var colors = themeRamp || generateColors(brandColor);
197
+ var tokenMaps = generateTokenMap(brandColor, mode, colors);
198
+ var result = {};
199
+ Object.entries(tokenMaps).forEach(function (_ref3) {
200
+ var _ref4 = (0, _slicedToArray2.default)(_ref3, 2),
201
+ mode = _ref4[0],
202
+ map = _ref4[1];
203
+ if (mode === 'light' || mode === 'dark') {
204
+ result[mode] = _objectSpread(_objectSpread({}, map), (0, _customThemeTokenContrastCheck.additionalContrastChecker)({
205
+ customThemeTokenMap: map,
206
+ mode: mode,
207
+ themeRamp: colors
208
+ }));
209
+ }
210
+ });
211
+ return result;
212
+ };
213
+ exports.generateTokenMapWithContrastCheck = generateTokenMapWithContrastCheck;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.hash = void 0;
7
+ var hash = function hash(str) {
8
+ var hash = 0;
9
+ for (var i = 0; i < str.length; i++) {
10
+ var char = str.charCodeAt(i);
11
+ hash = (hash << 5) - hash + char;
12
+ hash &= hash; // Convert to 32bit integer
13
+ }
14
+
15
+ return new Uint32Array([hash])[0].toString(36);
16
+ };
17
+ exports.hash = hash;