@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.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/artifacts/atlassian-dark-token-value-for-contrast-check.js +24 -0
- package/dist/cjs/artifacts/atlassian-light-token-value-for-contrast-check.js +24 -0
- package/dist/cjs/constants.js +3 -1
- package/dist/cjs/custom-theme.js +108 -0
- package/dist/cjs/get-token-value.js +1 -1
- package/dist/cjs/get-token.js +1 -1
- package/dist/cjs/set-global-theme.js +156 -59
- package/dist/cjs/utils/color-utils.js +178 -0
- package/dist/cjs/utils/custom-theme-loading-utils.js +47 -0
- package/dist/cjs/utils/custom-theme-token-contrast-check.js +74 -0
- package/dist/cjs/utils/generate-custom-color-ramp.js +213 -0
- package/dist/cjs/utils/hash.js +17 -0
- package/dist/cjs/utils/hct-color-utils/color-utils.js +310 -0
- package/dist/cjs/utils/hct-color-utils/contrast.js +188 -0
- package/dist/cjs/utils/hct-color-utils/hct.js +1036 -0
- package/dist/cjs/utils/hct-color-utils/index.js +32 -0
- package/dist/cjs/utils/hct-color-utils/math-utils.js +159 -0
- package/dist/cjs/utils/theme-loading.js +1 -1
- package/dist/cjs/utils/theme-state-transformer.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/artifacts/atlassian-dark-token-value-for-contrast-check.js +17 -0
- package/dist/es2019/artifacts/atlassian-light-token-value-for-contrast-check.js +17 -0
- package/dist/es2019/constants.js +1 -0
- package/dist/es2019/custom-theme.js +77 -0
- package/dist/es2019/get-token-value.js +1 -1
- package/dist/es2019/get-token.js +1 -1
- package/dist/es2019/set-global-theme.js +67 -13
- package/dist/es2019/utils/color-utils.js +154 -0
- package/dist/es2019/utils/custom-theme-loading-utils.js +31 -0
- package/dist/es2019/utils/custom-theme-token-contrast-check.js +68 -0
- package/dist/es2019/utils/generate-custom-color-ramp.js +187 -0
- package/dist/es2019/utils/hash.js +10 -0
- package/dist/es2019/utils/hct-color-utils/color-utils.js +286 -0
- package/dist/es2019/utils/hct-color-utils/contrast.js +161 -0
- package/dist/es2019/utils/hct-color-utils/hct.js +931 -0
- package/dist/es2019/utils/hct-color-utils/index.js +3 -0
- package/dist/es2019/utils/hct-color-utils/math-utils.js +145 -0
- package/dist/es2019/utils/theme-loading.js +2 -2
- package/dist/es2019/utils/theme-state-transformer.js +3 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/artifacts/atlassian-dark-token-value-for-contrast-check.js +17 -0
- package/dist/esm/artifacts/atlassian-light-token-value-for-contrast-check.js +17 -0
- package/dist/esm/constants.js +1 -0
- package/dist/esm/custom-theme.js +98 -0
- package/dist/esm/get-token-value.js +1 -1
- package/dist/esm/get-token.js +1 -1
- package/dist/esm/set-global-theme.js +149 -60
- package/dist/esm/utils/color-utils.js +162 -0
- package/dist/esm/utils/custom-theme-loading-utils.js +38 -0
- package/dist/esm/utils/custom-theme-token-contrast-check.js +65 -0
- package/dist/esm/utils/generate-custom-color-ramp.js +202 -0
- package/dist/esm/utils/hash.js +10 -0
- package/dist/esm/utils/hct-color-utils/color-utils.js +285 -0
- package/dist/esm/utils/hct-color-utils/contrast.js +181 -0
- package/dist/esm/utils/hct-color-utils/hct.js +1029 -0
- package/dist/esm/utils/hct-color-utils/index.js +3 -0
- package/dist/esm/utils/hct-color-utils/math-utils.js +145 -0
- package/dist/esm/utils/theme-loading.js +2 -2
- package/dist/esm/utils/theme-state-transformer.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/artifacts/atlassian-dark-token-value-for-contrast-check.d.ts +17 -0
- package/dist/types/artifacts/atlassian-light-token-value-for-contrast-check.d.ts +17 -0
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/custom-theme.d.ts +30 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/set-global-theme.d.ts +9 -3
- package/dist/types/tokens/atlassian-dark/utility/utility.d.ts +1 -1
- package/dist/types/tokens/atlassian-light/utility/utility.d.ts +1 -1
- package/dist/types/tokens/default/utility/utility.d.ts +1 -1
- package/dist/types/utils/color-utils.d.ts +10 -0
- package/dist/types/utils/custom-theme-loading-utils.d.ts +11 -0
- package/dist/types/utils/custom-theme-token-contrast-check.d.ts +20 -0
- package/dist/types/utils/generate-custom-color-ramp.d.ts +19 -0
- package/dist/types/utils/hash.d.ts +1 -0
- package/dist/types/utils/hct-color-utils/color-utils.d.ts +131 -0
- package/dist/types/utils/hct-color-utils/contrast.d.ts +78 -0
- package/dist/types/utils/hct-color-utils/hct.d.ts +137 -0
- package/dist/types/utils/hct-color-utils/index.d.ts +3 -0
- package/dist/types/utils/hct-color-utils/math-utils.d.ts +86 -0
- package/dist/types-ts4.5/artifacts/atlassian-dark-token-value-for-contrast-check.d.ts +17 -0
- package/dist/types-ts4.5/artifacts/atlassian-light-token-value-for-contrast-check.d.ts +17 -0
- package/dist/types-ts4.5/constants.d.ts +1 -0
- package/dist/types-ts4.5/custom-theme.d.ts +30 -0
- package/dist/types-ts4.5/index.d.ts +1 -0
- package/dist/types-ts4.5/set-global-theme.d.ts +9 -3
- package/dist/types-ts4.5/tokens/atlassian-dark/utility/utility.d.ts +1 -1
- package/dist/types-ts4.5/tokens/atlassian-light/utility/utility.d.ts +1 -1
- package/dist/types-ts4.5/tokens/default/utility/utility.d.ts +1 -1
- package/dist/types-ts4.5/utils/color-utils.d.ts +27 -0
- package/dist/types-ts4.5/utils/custom-theme-loading-utils.d.ts +11 -0
- package/dist/types-ts4.5/utils/custom-theme-token-contrast-check.d.ts +20 -0
- package/dist/types-ts4.5/utils/generate-custom-color-ramp.d.ts +19 -0
- package/dist/types-ts4.5/utils/hash.d.ts +1 -0
- package/dist/types-ts4.5/utils/hct-color-utils/color-utils.d.ts +131 -0
- package/dist/types-ts4.5/utils/hct-color-utils/contrast.d.ts +78 -0
- package/dist/types-ts4.5/utils/hct-color-utils/hct.d.ts +137 -0
- package/dist/types-ts4.5/utils/hct-color-utils/index.d.ts +3 -0
- package/dist/types-ts4.5/utils/hct-color-utils/math-utils.d.ts +86 -0
- package/package.json +35 -36
- package/report.api.md +24 -1
- package/tmp/api-report-tmp.d.ts +0 -1132
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
4
|
+
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; }
|
|
5
|
+
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; }
|
|
6
|
+
import rawTokensDark from '../artifacts/tokens-raw/atlassian-dark';
|
|
7
|
+
import { deltaE, getContrastRatio, hexToHSL, hexToRgb, hexToRgbA, HSLToRGB, relativeLuminanceW3C, rgbToHex } from './color-utils';
|
|
8
|
+
import { additionalContrastChecker } from './custom-theme-token-contrast-check';
|
|
9
|
+
import { argbFromRgba, Contrast, Hct, rgbaFromArgb } from './hct-color-utils';
|
|
10
|
+
var lowLuminanceContrastRatios = [1.12, 1.33, 2.03, 2.73, 3.33, 4.27, 5.2, 6.62, 12.46, 15.98];
|
|
11
|
+
var highLuminanceContrastRatios = [1.08, 1.24, 1.55, 1.99, 2.45, 3.34, 4.64, 6.1, 10.19, 13.43];
|
|
12
|
+
export var getClosestColorIndex = function getClosestColorIndex(themeRamp, brandColor) {
|
|
13
|
+
// Iterate over themeRamp and find whichever color is closest to brandColor
|
|
14
|
+
var closestColorIndex = 0;
|
|
15
|
+
var closestColorDistance = null;
|
|
16
|
+
themeRamp.forEach(function (value, index) {
|
|
17
|
+
var distance = deltaE(hexToRgb(value), hexToRgb(brandColor));
|
|
18
|
+
if (closestColorDistance === null || distance < closestColorDistance) {
|
|
19
|
+
closestColorIndex = index;
|
|
20
|
+
closestColorDistance = distance;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return closestColorIndex;
|
|
24
|
+
};
|
|
25
|
+
export var generateColors = function generateColors(brandColor) {
|
|
26
|
+
// Determine luminance
|
|
27
|
+
var HSLBrandColorHue = hexToHSL(brandColor)[0];
|
|
28
|
+
var baseRgb = HSLToRGB(HSLBrandColorHue, 100, 60);
|
|
29
|
+
var isLowLuminance = relativeLuminanceW3C(baseRgb[0], baseRgb[1], baseRgb[2]) < 0.4;
|
|
30
|
+
// Choose right palette
|
|
31
|
+
var themeRatios = isLowLuminance ? lowLuminanceContrastRatios : highLuminanceContrastRatios;
|
|
32
|
+
var brandRgba = hexToRgbA(brandColor);
|
|
33
|
+
var hctColor = Hct.fromInt(argbFromRgba({
|
|
34
|
+
r: brandRgba[0],
|
|
35
|
+
g: brandRgba[1],
|
|
36
|
+
b: brandRgba[2],
|
|
37
|
+
a: brandRgba[3]
|
|
38
|
+
}));
|
|
39
|
+
var themeRamp = themeRatios.map(function (contrast) {
|
|
40
|
+
var rgbaColor = rgbaFromArgb(Hct.from(hctColor.hue, hctColor.chroma, Contrast.darker(100, contrast) + 0.25 // Material's utils provide an offset
|
|
41
|
+
).toInt());
|
|
42
|
+
return rgbToHex(rgbaColor.r, rgbaColor.g, rgbaColor.b);
|
|
43
|
+
});
|
|
44
|
+
var closestColorIndex = getClosestColorIndex(themeRamp, brandColor);
|
|
45
|
+
|
|
46
|
+
// Replace closet color with brandColor
|
|
47
|
+
var updatedThemeRamp = _toConsumableArray(themeRamp);
|
|
48
|
+
updatedThemeRamp[closestColorIndex] = brandColor;
|
|
49
|
+
return updatedThemeRamp;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Return the interaction tokens for a color, given its ramp position and the number of
|
|
54
|
+
* needed interaction states. Use higher-indexed colors (i.e. darker colors) if possible;
|
|
55
|
+
* if there's not enough room to shift up for the required number of interaction tokens,
|
|
56
|
+
* it goes as far as it can, then returns lighter colors lower down the ramp instead.
|
|
57
|
+
*
|
|
58
|
+
* Returns an array of the resulting colors
|
|
59
|
+
*/
|
|
60
|
+
function getInteractionStates(rampPosition, number, colors) {
|
|
61
|
+
var result = [];
|
|
62
|
+
for (var i = 1; i <= number; i++) {
|
|
63
|
+
if (rampPosition + i < colors.length) {
|
|
64
|
+
result.push(rampPosition + i);
|
|
65
|
+
} else {
|
|
66
|
+
result.push(rampPosition - (i - (colors.length - 1 - rampPosition)));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
export var generateTokenMap = function generateTokenMap(brandColor, mode, themeRamp) {
|
|
72
|
+
var colors = themeRamp || generateColors(brandColor);
|
|
73
|
+
var closestColorIndex = getClosestColorIndex(colors, brandColor);
|
|
74
|
+
var customThemeTokenMapLight = {};
|
|
75
|
+
var customThemeTokenMapDark = {};
|
|
76
|
+
var inputContrast = getContrastRatio(brandColor, '#FFFFFF');
|
|
77
|
+
// Branch based on brandColor's contrast against white
|
|
78
|
+
if (inputContrast >= 4.5) {
|
|
79
|
+
/**
|
|
80
|
+
* Generate interaction tokens for
|
|
81
|
+
* - color.background.brand.bold
|
|
82
|
+
* - color.background.selected.bold
|
|
83
|
+
*/
|
|
84
|
+
var _getInteractionStates = getInteractionStates(closestColorIndex, 2, colors),
|
|
85
|
+
_getInteractionStates2 = _slicedToArray(_getInteractionStates, 2),
|
|
86
|
+
brandBoldSelectedHoveredIndex = _getInteractionStates2[0],
|
|
87
|
+
brandBoldSelectedPressedIndex = _getInteractionStates2[1];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Generate interaction token for color.link:
|
|
91
|
+
* If inputted color replaces X1000
|
|
92
|
+
* - Pressed = X900
|
|
93
|
+
*
|
|
94
|
+
* If inputted color replaces X700-X900
|
|
95
|
+
* - Shift one 1 step darker
|
|
96
|
+
*/
|
|
97
|
+
var _getInteractionStates3 = getInteractionStates(closestColorIndex, 1, colors),
|
|
98
|
+
_getInteractionStates4 = _slicedToArray(_getInteractionStates3, 1),
|
|
99
|
+
linkPressed = _getInteractionStates4[0];
|
|
100
|
+
customThemeTokenMapLight = {
|
|
101
|
+
'color.text.brand': closestColorIndex,
|
|
102
|
+
'color.icon.brand': closestColorIndex,
|
|
103
|
+
'color.background.brand.bold': closestColorIndex,
|
|
104
|
+
'color.background.brand.bold.hovered': brandBoldSelectedHoveredIndex,
|
|
105
|
+
'color.background.brand.bold.pressed': brandBoldSelectedPressedIndex,
|
|
106
|
+
'color.border.brand': closestColorIndex,
|
|
107
|
+
'color.text.selected': closestColorIndex,
|
|
108
|
+
'color.icon.selected': closestColorIndex,
|
|
109
|
+
'color.background.selected.bold': closestColorIndex,
|
|
110
|
+
'color.background.selected.bold.hovered': brandBoldSelectedHoveredIndex,
|
|
111
|
+
'color.background.selected.bold.pressed': brandBoldSelectedPressedIndex,
|
|
112
|
+
'color.border.selected': closestColorIndex,
|
|
113
|
+
'color.link': closestColorIndex,
|
|
114
|
+
'color.link.pressed': linkPressed,
|
|
115
|
+
'color.chart.brand': 5,
|
|
116
|
+
'color.chart.brand.hovered': 6,
|
|
117
|
+
'color.background.selected': 0,
|
|
118
|
+
'color.background.selected.hovered': 1,
|
|
119
|
+
'color.background.selected.pressed': 2
|
|
120
|
+
};
|
|
121
|
+
} else {
|
|
122
|
+
customThemeTokenMapLight = {
|
|
123
|
+
'color.background.brand.bold': 6,
|
|
124
|
+
'color.background.brand.bold.hovered': 7,
|
|
125
|
+
'color.background.brand.bold.pressed': 8,
|
|
126
|
+
'color.border.brand': 6,
|
|
127
|
+
'color.background.selected.bold': 6,
|
|
128
|
+
'color.background.selected.bold.hovered': 7,
|
|
129
|
+
'color.background.selected.bold.pressed': 8,
|
|
130
|
+
'color.text.brand': 6,
|
|
131
|
+
'color.icon.brand': 6,
|
|
132
|
+
'color.chart.brand': 5,
|
|
133
|
+
'color.chart.brand.hovered': 6,
|
|
134
|
+
'color.text.selected': 6,
|
|
135
|
+
'color.icon.selected': 6,
|
|
136
|
+
'color.border.selected': 6,
|
|
137
|
+
'color.background.selected': 0,
|
|
138
|
+
'color.background.selected.hovered': 1,
|
|
139
|
+
'color.background.selected.pressed': 2,
|
|
140
|
+
'color.link': 6,
|
|
141
|
+
'color.link.pressed': 7
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (mode === 'light') {
|
|
145
|
+
return {
|
|
146
|
+
light: customThemeTokenMapLight
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Generate dark mode values using rule of symmetry
|
|
152
|
+
*/
|
|
153
|
+
Object.entries(customThemeTokenMapLight).forEach(function (_ref) {
|
|
154
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
155
|
+
key = _ref2[0],
|
|
156
|
+
value = _ref2[1];
|
|
157
|
+
customThemeTokenMapDark[key] = 9 - value;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* If the input brand color < 4.5, and it meets 4.5 contrast again inverse text color
|
|
162
|
+
* in dark mode, shift color.background.brand.bold to the brand color
|
|
163
|
+
*/
|
|
164
|
+
if (inputContrast < 4.5) {
|
|
165
|
+
var _rawTokensDark$find;
|
|
166
|
+
var inverseTextColor = (_rawTokensDark$find = rawTokensDark.find(function (token) {
|
|
167
|
+
return token.cleanName === 'color.text.inverse';
|
|
168
|
+
})) === null || _rawTokensDark$find === void 0 ? void 0 : _rawTokensDark$find.value;
|
|
169
|
+
if (getContrastRatio(inverseTextColor, brandColor) >= 4.5 && closestColorIndex >= 2) {
|
|
170
|
+
customThemeTokenMapDark['color.background.brand.bold'] = closestColorIndex;
|
|
171
|
+
customThemeTokenMapDark['color.background.brand.bold.hovered'] = closestColorIndex - 1;
|
|
172
|
+
customThemeTokenMapDark['color.background.brand.bold.pressed'] = closestColorIndex - 2;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (mode === 'dark') {
|
|
176
|
+
return {
|
|
177
|
+
dark: customThemeTokenMapDark
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
light: customThemeTokenMapLight,
|
|
182
|
+
dark: customThemeTokenMapDark
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
export var generateTokenMapWithContrastCheck = function generateTokenMapWithContrastCheck(brandColor, mode, themeRamp) {
|
|
186
|
+
var colors = themeRamp || generateColors(brandColor);
|
|
187
|
+
var tokenMaps = generateTokenMap(brandColor, mode, colors);
|
|
188
|
+
var result = {};
|
|
189
|
+
Object.entries(tokenMaps).forEach(function (_ref3) {
|
|
190
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
191
|
+
mode = _ref4[0],
|
|
192
|
+
map = _ref4[1];
|
|
193
|
+
if (mode === 'light' || mode === 'dark') {
|
|
194
|
+
result[mode] = _objectSpread(_objectSpread({}, map), additionalContrastChecker({
|
|
195
|
+
customThemeTokenMap: map,
|
|
196
|
+
mode: mode,
|
|
197
|
+
themeRamp: colors
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
return result;
|
|
202
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export var hash = function hash(str) {
|
|
2
|
+
var hash = 0;
|
|
3
|
+
for (var i = 0; i < str.length; i++) {
|
|
4
|
+
var char = str.charCodeAt(i);
|
|
5
|
+
hash = (hash << 5) - hash + char;
|
|
6
|
+
hash &= hash; // Convert to 32bit integer
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return new Uint32Array([hash])[0].toString(36);
|
|
10
|
+
};
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Below lines are copied from @material/material-color-utilities.
|
|
3
|
+
* Do not modify it.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @license
|
|
8
|
+
* Copyright 2021 Google LLC
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
11
|
+
* you may not use this file except in compliance with the License.
|
|
12
|
+
* You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
// This file is automatically generated. Do not modify it.
|
|
24
|
+
|
|
25
|
+
import * as mathUtils from './math-utils';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Color science utilities.
|
|
29
|
+
*
|
|
30
|
+
* Utility methods for color science constants and color space
|
|
31
|
+
* conversions that aren't HCT or CAM16.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
var SRGB_TO_XYZ = [[0.41233895, 0.35762064, 0.18051042], [0.2126, 0.7152, 0.0722], [0.01932141, 0.11916382, 0.95034478]];
|
|
35
|
+
var XYZ_TO_SRGB = [[3.2413774792388685, -1.5376652402851851, -0.49885366846268053], [-0.9691452513005321, 1.8758853451067872, 0.04156585616912061], [0.05562093689691305, -0.20395524564742123, 1.0571799111220335]];
|
|
36
|
+
var WHITE_POINT_D65 = [95.047, 100.0, 108.883];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Converts a color from RGB components to ARGB format.
|
|
40
|
+
*/
|
|
41
|
+
export function argbFromRgb(red, green, blue) {
|
|
42
|
+
return (255 << 24 | (red & 255) << 16 | (green & 255) << 8 | blue & 255) >>> 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Converts a color from linear RGB components to ARGB format.
|
|
47
|
+
*/
|
|
48
|
+
export function argbFromLinrgb(linrgb) {
|
|
49
|
+
var r = delinearized(linrgb[0]);
|
|
50
|
+
var g = delinearized(linrgb[1]);
|
|
51
|
+
var b = delinearized(linrgb[2]);
|
|
52
|
+
return argbFromRgb(r, g, b);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns the alpha component of a color in ARGB format.
|
|
57
|
+
*/
|
|
58
|
+
export function alphaFromArgb(argb) {
|
|
59
|
+
return argb >> 24 & 255;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns the red component of a color in ARGB format.
|
|
64
|
+
*/
|
|
65
|
+
export function redFromArgb(argb) {
|
|
66
|
+
return argb >> 16 & 255;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns the green component of a color in ARGB format.
|
|
71
|
+
*/
|
|
72
|
+
export function greenFromArgb(argb) {
|
|
73
|
+
return argb >> 8 & 255;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Returns the blue component of a color in ARGB format.
|
|
78
|
+
*/
|
|
79
|
+
export function blueFromArgb(argb) {
|
|
80
|
+
return argb & 255;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns whether a color in ARGB format is opaque.
|
|
85
|
+
*/
|
|
86
|
+
export function isOpaque(argb) {
|
|
87
|
+
return alphaFromArgb(argb) >= 255;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Converts a color from ARGB to XYZ.
|
|
92
|
+
*/
|
|
93
|
+
export function argbFromXyz(x, y, z) {
|
|
94
|
+
var matrix = XYZ_TO_SRGB;
|
|
95
|
+
var linearR = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z;
|
|
96
|
+
var linearG = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z;
|
|
97
|
+
var linearB = matrix[2][0] * x + matrix[2][1] * y + matrix[2][2] * z;
|
|
98
|
+
var r = delinearized(linearR);
|
|
99
|
+
var g = delinearized(linearG);
|
|
100
|
+
var b = delinearized(linearB);
|
|
101
|
+
return argbFromRgb(r, g, b);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Converts a color from XYZ to ARGB.
|
|
106
|
+
*/
|
|
107
|
+
export function xyzFromArgb(argb) {
|
|
108
|
+
var r = linearized(redFromArgb(argb));
|
|
109
|
+
var g = linearized(greenFromArgb(argb));
|
|
110
|
+
var b = linearized(blueFromArgb(argb));
|
|
111
|
+
return mathUtils.matrixMultiply([r, g, b], SRGB_TO_XYZ);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Converts an L* value to an ARGB representation.
|
|
116
|
+
*
|
|
117
|
+
* @param lstar L* in L*a*b*
|
|
118
|
+
* @return ARGB representation of grayscale color with lightness
|
|
119
|
+
* matching L*
|
|
120
|
+
*/
|
|
121
|
+
export function argbFromLstar(lstar) {
|
|
122
|
+
var y = yFromLstar(lstar);
|
|
123
|
+
var component = delinearized(y);
|
|
124
|
+
return argbFromRgb(component, component, component);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Computes the L* value of a color in ARGB representation.
|
|
129
|
+
*
|
|
130
|
+
* @param argb ARGB representation of a color
|
|
131
|
+
* @return L*, from L*a*b*, coordinate of the color
|
|
132
|
+
*/
|
|
133
|
+
export function lstarFromArgb(argb) {
|
|
134
|
+
var y = xyzFromArgb(argb)[1];
|
|
135
|
+
return 116.0 * labF(y / 100.0) - 16.0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Converts an L* value to a Y value.
|
|
140
|
+
*
|
|
141
|
+
* L* in L*a*b* and Y in XYZ measure the same quantity, luminance.
|
|
142
|
+
*
|
|
143
|
+
* L* measures perceptual luminance, a linear scale. Y in XYZ
|
|
144
|
+
* measures relative luminance, a logarithmic scale.
|
|
145
|
+
*
|
|
146
|
+
* @param lstar L* in L*a*b*
|
|
147
|
+
* @return Y in XYZ
|
|
148
|
+
*/
|
|
149
|
+
export function yFromLstar(lstar) {
|
|
150
|
+
return 100.0 * labInvf((lstar + 16.0) / 116.0);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Converts a Y value to an L* value.
|
|
155
|
+
*
|
|
156
|
+
* L* in L*a*b* and Y in XYZ measure the same quantity, luminance.
|
|
157
|
+
*
|
|
158
|
+
* L* measures perceptual luminance, a linear scale. Y in XYZ
|
|
159
|
+
* measures relative luminance, a logarithmic scale.
|
|
160
|
+
*
|
|
161
|
+
* @param y Y in XYZ
|
|
162
|
+
* @return L* in L*a*b*
|
|
163
|
+
*/
|
|
164
|
+
export function lstarFromY(y) {
|
|
165
|
+
return labF(y / 100.0) * 116.0 - 16.0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Linearizes an RGB component.
|
|
170
|
+
*
|
|
171
|
+
* @param rgbComponent 0 <= rgb_component <= 255, represents R/G/B
|
|
172
|
+
* channel
|
|
173
|
+
* @return 0.0 <= output <= 100.0, color channel converted to
|
|
174
|
+
* linear RGB space
|
|
175
|
+
*/
|
|
176
|
+
export function linearized(rgbComponent) {
|
|
177
|
+
var normalized = rgbComponent / 255.0;
|
|
178
|
+
if (normalized <= 0.040449936) {
|
|
179
|
+
return normalized / 12.92 * 100.0;
|
|
180
|
+
} else {
|
|
181
|
+
return Math.pow((normalized + 0.055) / 1.055, 2.4) * 100.0;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Delinearizes an RGB component.
|
|
187
|
+
*
|
|
188
|
+
* @param rgbComponent 0.0 <= rgb_component <= 100.0, represents
|
|
189
|
+
* linear R/G/B channel
|
|
190
|
+
* @return 0 <= output <= 255, color channel converted to regular
|
|
191
|
+
* RGB space
|
|
192
|
+
*/
|
|
193
|
+
export function delinearized(rgbComponent) {
|
|
194
|
+
var normalized = rgbComponent / 100.0;
|
|
195
|
+
var delinearized = 0.0;
|
|
196
|
+
if (normalized <= 0.0031308) {
|
|
197
|
+
delinearized = normalized * 12.92;
|
|
198
|
+
} else {
|
|
199
|
+
delinearized = 1.055 * Math.pow(normalized, 1.0 / 2.4) - 0.055;
|
|
200
|
+
}
|
|
201
|
+
return mathUtils.clampInt(0, 255, Math.round(delinearized * 255.0));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Returns the standard white point; white on a sunny day.
|
|
206
|
+
*
|
|
207
|
+
* @return The white point
|
|
208
|
+
*/
|
|
209
|
+
export function whitePointD65() {
|
|
210
|
+
return WHITE_POINT_D65;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* RGBA component
|
|
215
|
+
*
|
|
216
|
+
* @param r Red value should be between 0-255
|
|
217
|
+
* @param g Green value should be between 0-255
|
|
218
|
+
* @param b Blue value should be between 0-255
|
|
219
|
+
* @param a Alpha value should be between 0-255
|
|
220
|
+
*/
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Return RGBA from a given int32 color
|
|
224
|
+
*
|
|
225
|
+
* @param argb ARGB representation of a int32 color.
|
|
226
|
+
* @return RGBA representation of a int32 color.
|
|
227
|
+
*/
|
|
228
|
+
export function rgbaFromArgb(argb) {
|
|
229
|
+
var r = redFromArgb(argb);
|
|
230
|
+
var g = greenFromArgb(argb);
|
|
231
|
+
var b = blueFromArgb(argb);
|
|
232
|
+
var a = alphaFromArgb(argb);
|
|
233
|
+
return {
|
|
234
|
+
r: r,
|
|
235
|
+
g: g,
|
|
236
|
+
b: b,
|
|
237
|
+
a: a
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Return int32 color from a given RGBA component
|
|
243
|
+
*
|
|
244
|
+
* @param rgba RGBA representation of a int32 color.
|
|
245
|
+
* @returns ARGB representation of a int32 color.
|
|
246
|
+
*/
|
|
247
|
+
export function argbFromRgba(_ref) {
|
|
248
|
+
var r = _ref.r,
|
|
249
|
+
g = _ref.g,
|
|
250
|
+
b = _ref.b,
|
|
251
|
+
a = _ref.a;
|
|
252
|
+
var rValue = clampComponent(r);
|
|
253
|
+
var gValue = clampComponent(g);
|
|
254
|
+
var bValue = clampComponent(b);
|
|
255
|
+
var aValue = clampComponent(a);
|
|
256
|
+
return aValue << 24 | rValue << 16 | gValue << 8 | bValue;
|
|
257
|
+
}
|
|
258
|
+
function clampComponent(value) {
|
|
259
|
+
if (value < 0) {
|
|
260
|
+
return 0;
|
|
261
|
+
}
|
|
262
|
+
if (value > 255) {
|
|
263
|
+
return 255;
|
|
264
|
+
}
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
function labF(t) {
|
|
268
|
+
var e = 216.0 / 24389.0;
|
|
269
|
+
var kappa = 24389.0 / 27.0;
|
|
270
|
+
if (t > e) {
|
|
271
|
+
return Math.pow(t, 1.0 / 3.0);
|
|
272
|
+
} else {
|
|
273
|
+
return (kappa * t + 16) / 116;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function labInvf(ft) {
|
|
277
|
+
var e = 216.0 / 24389.0;
|
|
278
|
+
var kappa = 24389.0 / 27.0;
|
|
279
|
+
var ft3 = ft * ft * ft;
|
|
280
|
+
if (ft3 > e) {
|
|
281
|
+
return ft3;
|
|
282
|
+
} else {
|
|
283
|
+
return (116 * ft - 16) / kappa;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
/**
|
|
4
|
+
* Below lines are copied from @material/material-color-utilities.
|
|
5
|
+
* Do not modify it.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @license
|
|
10
|
+
* Copyright 2022 Google LLC
|
|
11
|
+
*
|
|
12
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
+
* you may not use this file except in compliance with the License.
|
|
14
|
+
* You may obtain a copy of the License at
|
|
15
|
+
*
|
|
16
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
+
*
|
|
18
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
* See the License for the specific language governing permissions and
|
|
22
|
+
* limitations under the License.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// material_color_utilities is designed to have a consistent API across
|
|
26
|
+
// platforms and modular components that can be moved around easily. Using a
|
|
27
|
+
// class as a namespace facilitates this.
|
|
28
|
+
//
|
|
29
|
+
// tslint:disable:class-as-namespace
|
|
30
|
+
|
|
31
|
+
import * as utils from './color-utils';
|
|
32
|
+
import * as math from './math-utils';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Utility methods for calculating contrast given two colors, or calculating a
|
|
36
|
+
* color given one color and a contrast ratio.
|
|
37
|
+
*
|
|
38
|
+
* Contrast ratio is calculated using XYZ's Y. When linearized to match human
|
|
39
|
+
* perception, Y becomes HCT's tone and L*a*b*'s' L*. Informally, this is the
|
|
40
|
+
* lightness of a color.
|
|
41
|
+
*
|
|
42
|
+
* Methods refer to tone, T in the the HCT color space.
|
|
43
|
+
* Tone is equivalent to L* in the L*a*b* color space, or L in the LCH color
|
|
44
|
+
* space.
|
|
45
|
+
*/
|
|
46
|
+
export var Contrast = /*#__PURE__*/function () {
|
|
47
|
+
function Contrast() {
|
|
48
|
+
_classCallCheck(this, Contrast);
|
|
49
|
+
}
|
|
50
|
+
_createClass(Contrast, null, [{
|
|
51
|
+
key: "ratioOfTones",
|
|
52
|
+
value:
|
|
53
|
+
/**
|
|
54
|
+
* Returns a contrast ratio, which ranges from 1 to 21.
|
|
55
|
+
*
|
|
56
|
+
* @param toneA Tone between 0 and 100. Values outside will be clamped.
|
|
57
|
+
* @param toneB Tone between 0 and 100. Values outside will be clamped.
|
|
58
|
+
*/
|
|
59
|
+
function ratioOfTones(toneA, toneB) {
|
|
60
|
+
toneA = math.clampDouble(0.0, 100.0, toneA);
|
|
61
|
+
toneB = math.clampDouble(0.0, 100.0, toneB);
|
|
62
|
+
return Contrast.ratioOfYs(utils.yFromLstar(toneA), utils.yFromLstar(toneB));
|
|
63
|
+
}
|
|
64
|
+
}, {
|
|
65
|
+
key: "ratioOfYs",
|
|
66
|
+
value: function ratioOfYs(y1, y2) {
|
|
67
|
+
var lighter = y1 > y2 ? y1 : y2;
|
|
68
|
+
var darker = lighter === y2 ? y1 : y2;
|
|
69
|
+
return (lighter + 5.0) / (darker + 5.0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Returns a tone >= tone parameter that ensures ratio parameter.
|
|
74
|
+
* Return value is between 0 and 100.
|
|
75
|
+
* Returns -1 if ratio cannot be achieved with tone parameter.
|
|
76
|
+
*
|
|
77
|
+
* @param tone Tone return value must contrast with.
|
|
78
|
+
* Range is 0 to 100. Invalid values will result in -1 being returned.
|
|
79
|
+
* @param ratio Contrast ratio of return value and tone.
|
|
80
|
+
* Range is 1 to 21, invalid values have undefined behavior.
|
|
81
|
+
*/
|
|
82
|
+
}, {
|
|
83
|
+
key: "lighter",
|
|
84
|
+
value: function lighter(tone, ratio) {
|
|
85
|
+
if (tone < 0.0 || tone > 100.0) {
|
|
86
|
+
return -1.0;
|
|
87
|
+
}
|
|
88
|
+
var darkY = utils.yFromLstar(tone);
|
|
89
|
+
var lightY = ratio * (darkY + 5.0) - 5.0;
|
|
90
|
+
var realContrast = Contrast.ratioOfYs(lightY, darkY);
|
|
91
|
+
var delta = Math.abs(realContrast - ratio);
|
|
92
|
+
if (realContrast < ratio && delta > 0.04) {
|
|
93
|
+
return -1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Ensure gamut mapping, which requires a 'range' on tone, will still result
|
|
97
|
+
// the correct ratio by darkening slightly.
|
|
98
|
+
var returnValue = utils.lstarFromY(lightY) + 0.4;
|
|
99
|
+
if (returnValue < 0 || returnValue > 100) {
|
|
100
|
+
return -1;
|
|
101
|
+
}
|
|
102
|
+
return returnValue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Returns a tone <= tone parameter that ensures ratio parameter.
|
|
107
|
+
* Return value is between 0 and 100.
|
|
108
|
+
* Returns -1 if ratio cannot be achieved with tone parameter.
|
|
109
|
+
*
|
|
110
|
+
* @param tone Tone return value must contrast with.
|
|
111
|
+
* Range is 0 to 100. Invalid values will result in -1 being returned.
|
|
112
|
+
* @param ratio Contrast ratio of return value and tone.
|
|
113
|
+
* Range is 1 to 21, invalid values have undefined behavior.
|
|
114
|
+
*/
|
|
115
|
+
}, {
|
|
116
|
+
key: "darker",
|
|
117
|
+
value: function darker(tone, ratio) {
|
|
118
|
+
if (tone < 0.0 || tone > 100.0) {
|
|
119
|
+
return -1.0;
|
|
120
|
+
}
|
|
121
|
+
var lightY = utils.yFromLstar(tone);
|
|
122
|
+
var darkY = (lightY + 5.0) / ratio - 5.0;
|
|
123
|
+
var realContrast = Contrast.ratioOfYs(lightY, darkY);
|
|
124
|
+
var delta = Math.abs(realContrast - ratio);
|
|
125
|
+
if (realContrast < ratio && delta > 0.04) {
|
|
126
|
+
return -1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Ensure gamut mapping, which requires a 'range' on tone, will still result
|
|
130
|
+
// the correct ratio by darkening slightly.
|
|
131
|
+
var returnValue = utils.lstarFromY(darkY) - 0.4;
|
|
132
|
+
if (returnValue < 0 || returnValue > 100) {
|
|
133
|
+
return -1;
|
|
134
|
+
}
|
|
135
|
+
return returnValue;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Returns a tone >= tone parameter that ensures ratio parameter.
|
|
140
|
+
* Return value is between 0 and 100.
|
|
141
|
+
* Returns 100 if ratio cannot be achieved with tone parameter.
|
|
142
|
+
*
|
|
143
|
+
* This method is unsafe because the returned value is guaranteed to be in
|
|
144
|
+
* bounds for tone, i.e. between 0 and 100. However, that value may not reach
|
|
145
|
+
* the ratio with tone. For example, there is no color lighter than T100.
|
|
146
|
+
*
|
|
147
|
+
* @param tone Tone return value must contrast with.
|
|
148
|
+
* Range is 0 to 100. Invalid values will result in 100 being returned.
|
|
149
|
+
* @param ratio Desired contrast ratio of return value and tone parameter.
|
|
150
|
+
* Range is 1 to 21, invalid values have undefined behavior.
|
|
151
|
+
*/
|
|
152
|
+
}, {
|
|
153
|
+
key: "lighterUnsafe",
|
|
154
|
+
value: function lighterUnsafe(tone, ratio) {
|
|
155
|
+
var lighterSafe = Contrast.lighter(tone, ratio);
|
|
156
|
+
return lighterSafe < 0.0 ? 100.0 : lighterSafe;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns a tone >= tone parameter that ensures ratio parameter.
|
|
161
|
+
* Return value is between 0 and 100.
|
|
162
|
+
* Returns 100 if ratio cannot be achieved with tone parameter.
|
|
163
|
+
*
|
|
164
|
+
* This method is unsafe because the returned value is guaranteed to be in
|
|
165
|
+
* bounds for tone, i.e. between 0 and 100. However, that value may not reach
|
|
166
|
+
* the [ratio with [tone]. For example, there is no color darker than T0.
|
|
167
|
+
*
|
|
168
|
+
* @param tone Tone return value must contrast with.
|
|
169
|
+
* Range is 0 to 100. Invalid values will result in 0 being returned.
|
|
170
|
+
* @param ratio Desired contrast ratio of return value and tone parameter.
|
|
171
|
+
* Range is 1 to 21, invalid values have undefined behavior.
|
|
172
|
+
*/
|
|
173
|
+
}, {
|
|
174
|
+
key: "darkerUnsafe",
|
|
175
|
+
value: function darkerUnsafe(tone, ratio) {
|
|
176
|
+
var darkerSafe = Contrast.darker(tone, ratio);
|
|
177
|
+
return darkerSafe < 0.0 ? 0.0 : darkerSafe;
|
|
178
|
+
}
|
|
179
|
+
}]);
|
|
180
|
+
return Contrast;
|
|
181
|
+
}();
|