@chipmobilesdk/rn-theme 0.2.1 → 1.0.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 +91 -23
- package/NOTICE +9 -0
- package/README.md +297 -154
- package/package.json +49 -50
- package/skills/sdk-rn-theme/SKILL.md +45 -30
- package/src/color/categorical.ts +33 -0
- package/src/color/contrast.ts +230 -0
- package/src/color/parse.ts +120 -0
- package/src/color/roles.ts +262 -0
- package/src/index.ts +23 -17
- package/src/integration/navigationTheme.ts +51 -0
- package/src/presets/byTone.ts +28 -0
- package/src/presets/layout.ts +38 -0
- package/src/presets/themePresets.ts +101 -0
- package/src/theme/buildThemes.ts +178 -0
- package/src/theme/errors.ts +34 -0
- package/src/theme/overrides.ts +142 -0
- package/src/theme/validateThemeConfig.ts +171 -0
- package/src/tokens/defaults.ts +103 -46
- package/src/tokens/typography.ts +144 -64
- package/src/types/brand.ts +16 -0
- package/src/types/colors.ts +80 -11
- package/src/types/index.ts +44 -5
- package/src/types/theme.ts +161 -0
- package/src/types/tokens.ts +47 -5
- package/src/types/typography.ts +46 -10
- package/src/unistyles/createUnistylesConfig.ts +165 -177
- package/src/unistyles/themeMode.ts +28 -0
- package/src/vendor/mcu/LICENSE +191 -0
- package/src/vendor/mcu/hct/cam16.ts +419 -0
- package/src/vendor/mcu/hct/hct.ts +216 -0
- package/src/vendor/mcu/hct/hct_solver.ts +557 -0
- package/src/vendor/mcu/hct/viewing_conditions.ts +121 -0
- package/src/vendor/mcu/index.ts +5 -0
- package/src/vendor/mcu/palettes/tonal_palette.ts +172 -0
- package/src/vendor/mcu/utils/color_utils.ts +302 -0
- package/src/vendor/mcu/utils/math_utils.ts +148 -0
- package/src/types/style.ts +0 -26
- package/src/unistyles/types.ts +0 -24
- package/src/unistyles/validateThemeConfig.ts +0 -154
- package/src/utils/colorGeneration.ts +0 -87
- package/src/utils/colorMath.ts +0 -55
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// Vendored from material-foundation/material-color-utilities v0.4.0
|
|
19
|
+
// (commit dd62982dfdefdfc9232ce8d76e122fb1c6d188ae, typescript/). Modified:
|
|
20
|
+
// relative import specifiers drop the `.js` suffix so Metro and Jest resolve them.
|
|
21
|
+
import {Hct} from '../hct/hct';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A convenience class for retrieving colors that are constant in hue and
|
|
25
|
+
* chroma, but vary in tone.
|
|
26
|
+
*/
|
|
27
|
+
export class TonalPalette {
|
|
28
|
+
private readonly cache = new Map<number, number>();
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param argb ARGB representation of a color
|
|
32
|
+
* @return Tones matching that color's hue and chroma.
|
|
33
|
+
*/
|
|
34
|
+
static fromInt(argb: number): TonalPalette {
|
|
35
|
+
const hct = Hct.fromInt(argb);
|
|
36
|
+
return TonalPalette.fromHct(hct);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param hct Hct
|
|
41
|
+
* @return Tones matching that color's hue and chroma.
|
|
42
|
+
*/
|
|
43
|
+
static fromHct(hct: Hct) {
|
|
44
|
+
return new TonalPalette(hct.hue, hct.chroma, hct);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param hue HCT hue
|
|
49
|
+
* @param chroma HCT chroma
|
|
50
|
+
* @return Tones matching hue and chroma.
|
|
51
|
+
*/
|
|
52
|
+
static fromHueAndChroma(hue: number, chroma: number): TonalPalette {
|
|
53
|
+
const keyColor = new KeyColor(hue, chroma).create();
|
|
54
|
+
return new TonalPalette(hue, chroma, keyColor);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private constructor(
|
|
58
|
+
readonly hue: number, readonly chroma: number, readonly keyColor: Hct) {}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param tone HCT tone, measured from 0 to 100.
|
|
62
|
+
* @return ARGB representation of a color with that tone.
|
|
63
|
+
*/
|
|
64
|
+
tone(tone: number): number {
|
|
65
|
+
let argb = this.cache.get(tone);
|
|
66
|
+
if (argb === undefined) {
|
|
67
|
+
if (tone == 99 && Hct.isYellow(this.hue)) {
|
|
68
|
+
argb = this.averageArgb(this.tone(98), this.tone(100));
|
|
69
|
+
} else {
|
|
70
|
+
argb = Hct.from(this.hue, this.chroma, tone).toInt();
|
|
71
|
+
}
|
|
72
|
+
this.cache.set(tone, argb);
|
|
73
|
+
}
|
|
74
|
+
return argb;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @param tone HCT tone.
|
|
79
|
+
* @return HCT representation of a color with that tone.
|
|
80
|
+
*/
|
|
81
|
+
getHct(tone: number): Hct {
|
|
82
|
+
return Hct.fromInt(this.tone(tone));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private averageArgb(argb1: number, argb2: number): number {
|
|
86
|
+
const red1 = (argb1 >>> 16) & 0xff;
|
|
87
|
+
const green1 = (argb1 >>> 8) & 0xff;
|
|
88
|
+
const blue1 = argb1 & 0xff;
|
|
89
|
+
const red2 = (argb2 >>> 16) & 0xff;
|
|
90
|
+
const green2 = (argb2 >>> 8) & 0xff;
|
|
91
|
+
const blue2 = argb2 & 0xff;
|
|
92
|
+
const red = Math.round((red1 + red2) / 2);
|
|
93
|
+
const green = Math.round((green1 + green2) / 2);
|
|
94
|
+
const blue = Math.round((blue1 + blue2) / 2);
|
|
95
|
+
return (255 << 24 | (red & 255) << 16 | (green & 255) << 8 |
|
|
96
|
+
(blue & 255)) >>>
|
|
97
|
+
0;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Key color is a color that represents the hue and chroma of a tonal palette
|
|
103
|
+
*/
|
|
104
|
+
class KeyColor {
|
|
105
|
+
// Cache that maps tone to max chroma to avoid duplicated HCT calculation.
|
|
106
|
+
private readonly chromaCache = new Map<number, number>();
|
|
107
|
+
private readonly maxChromaValue = 200.0;
|
|
108
|
+
|
|
109
|
+
constructor(readonly hue: number, readonly requestedChroma: number) {}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Creates a key color from a [hue] and a [chroma].
|
|
113
|
+
* The key color is the first tone, starting from T50, matching the given hue
|
|
114
|
+
* and chroma.
|
|
115
|
+
*
|
|
116
|
+
* @return Key color [Hct]
|
|
117
|
+
*/
|
|
118
|
+
create(): Hct {
|
|
119
|
+
// Pivot around T50 because T50 has the most chroma available, on
|
|
120
|
+
// average. Thus it is most likely to have a direct answer.
|
|
121
|
+
const pivotTone = 50;
|
|
122
|
+
const toneStepSize = 1;
|
|
123
|
+
// Epsilon to accept values slightly higher than the requested chroma.
|
|
124
|
+
const epsilon = 0.01;
|
|
125
|
+
|
|
126
|
+
// Binary search to find the tone that can provide a chroma that is closest
|
|
127
|
+
// to the requested chroma.
|
|
128
|
+
let lowerTone = 0;
|
|
129
|
+
let upperTone = 100;
|
|
130
|
+
while (lowerTone < upperTone) {
|
|
131
|
+
const midTone = Math.floor((lowerTone + upperTone) / 2);
|
|
132
|
+
const isAscending =
|
|
133
|
+
this.maxChroma(midTone) < this.maxChroma(midTone + toneStepSize);
|
|
134
|
+
const sufficientChroma =
|
|
135
|
+
this.maxChroma(midTone) >= this.requestedChroma - epsilon;
|
|
136
|
+
|
|
137
|
+
if (sufficientChroma) {
|
|
138
|
+
// Either range [lowerTone, midTone] or [midTone, upperTone] has
|
|
139
|
+
// the answer, so search in the range that is closer the pivot tone.
|
|
140
|
+
if (Math.abs(lowerTone - pivotTone) < Math.abs(upperTone - pivotTone)) {
|
|
141
|
+
upperTone = midTone;
|
|
142
|
+
} else {
|
|
143
|
+
if (lowerTone === midTone) {
|
|
144
|
+
return Hct.from(this.hue, this.requestedChroma, lowerTone);
|
|
145
|
+
}
|
|
146
|
+
lowerTone = midTone;
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
// As there is no sufficient chroma in the midTone, follow the direction
|
|
150
|
+
// to the chroma peak.
|
|
151
|
+
if (isAscending) {
|
|
152
|
+
lowerTone = midTone + toneStepSize;
|
|
153
|
+
} else {
|
|
154
|
+
// Keep midTone for potential chroma peak.
|
|
155
|
+
upperTone = midTone;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return Hct.from(this.hue, this.requestedChroma, lowerTone);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Find the maximum chroma for a given tone
|
|
164
|
+
private maxChroma(tone: number): number {
|
|
165
|
+
if (this.chromaCache.has(tone)) {
|
|
166
|
+
return this.chromaCache.get(tone)!;
|
|
167
|
+
}
|
|
168
|
+
const chroma = Hct.from(this.hue, this.maxChromaValue, tone).chroma;
|
|
169
|
+
this.chromaCache.set(tone, chroma);
|
|
170
|
+
return chroma;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// Vendored from material-foundation/material-color-utilities v0.4.0
|
|
19
|
+
// (commit dd62982dfdefdfc9232ce8d76e122fb1c6d188ae, typescript/). Modified:
|
|
20
|
+
// relative import specifiers drop the `.js` suffix so Metro and Jest resolve them.
|
|
21
|
+
// This file is automatically generated. Do not modify it.
|
|
22
|
+
|
|
23
|
+
import * as mathUtils from './math_utils';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Color science utilities.
|
|
27
|
+
*
|
|
28
|
+
* Utility methods for color science constants and color space
|
|
29
|
+
* conversions that aren't HCT or CAM16.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const SRGB_TO_XYZ = [
|
|
33
|
+
[0.41233895, 0.35762064, 0.18051042],
|
|
34
|
+
[0.2126, 0.7152, 0.0722],
|
|
35
|
+
[0.01932141, 0.11916382, 0.95034478],
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const XYZ_TO_SRGB = [
|
|
39
|
+
[
|
|
40
|
+
3.2413774792388685,
|
|
41
|
+
-1.5376652402851851,
|
|
42
|
+
-0.49885366846268053,
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
-0.9691452513005321,
|
|
46
|
+
1.8758853451067872,
|
|
47
|
+
0.04156585616912061,
|
|
48
|
+
],
|
|
49
|
+
[
|
|
50
|
+
0.05562093689691305,
|
|
51
|
+
-0.20395524564742123,
|
|
52
|
+
1.0571799111220335,
|
|
53
|
+
],
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
const WHITE_POINT_D65 = [95.047, 100.0, 108.883];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Converts a color from RGB components to ARGB format.
|
|
60
|
+
*/
|
|
61
|
+
export function argbFromRgb(red: number, green: number, blue: number): number {
|
|
62
|
+
return (255 << 24 | (red & 255) << 16 | (green & 255) << 8 | blue & 255) >>>
|
|
63
|
+
0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Converts a color from linear RGB components to ARGB format.
|
|
68
|
+
*/
|
|
69
|
+
export function argbFromLinrgb(linrgb: number[]): number {
|
|
70
|
+
const r = delinearized(linrgb[0]);
|
|
71
|
+
const g = delinearized(linrgb[1]);
|
|
72
|
+
const b = delinearized(linrgb[2]);
|
|
73
|
+
return argbFromRgb(r, g, b);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Returns the alpha component of a color in ARGB format.
|
|
78
|
+
*/
|
|
79
|
+
export function alphaFromArgb(argb: number): number {
|
|
80
|
+
return argb >> 24 & 255;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns the red component of a color in ARGB format.
|
|
85
|
+
*/
|
|
86
|
+
export function redFromArgb(argb: number): number {
|
|
87
|
+
return argb >> 16 & 255;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Returns the green component of a color in ARGB format.
|
|
92
|
+
*/
|
|
93
|
+
export function greenFromArgb(argb: number): number {
|
|
94
|
+
return argb >> 8 & 255;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Returns the blue component of a color in ARGB format.
|
|
99
|
+
*/
|
|
100
|
+
export function blueFromArgb(argb: number): number {
|
|
101
|
+
return argb & 255;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Returns whether a color in ARGB format is opaque.
|
|
106
|
+
*/
|
|
107
|
+
export function isOpaque(argb: number): boolean {
|
|
108
|
+
return alphaFromArgb(argb) >= 255;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Converts a color from ARGB to XYZ.
|
|
113
|
+
*/
|
|
114
|
+
export function argbFromXyz(x: number, y: number, z: number): number {
|
|
115
|
+
const matrix = XYZ_TO_SRGB;
|
|
116
|
+
const linearR = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z;
|
|
117
|
+
const linearG = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z;
|
|
118
|
+
const linearB = matrix[2][0] * x + matrix[2][1] * y + matrix[2][2] * z;
|
|
119
|
+
const r = delinearized(linearR);
|
|
120
|
+
const g = delinearized(linearG);
|
|
121
|
+
const b = delinearized(linearB);
|
|
122
|
+
return argbFromRgb(r, g, b);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Converts a color from XYZ to ARGB.
|
|
127
|
+
*/
|
|
128
|
+
export function xyzFromArgb(argb: number): number[] {
|
|
129
|
+
const r = linearized(redFromArgb(argb));
|
|
130
|
+
const g = linearized(greenFromArgb(argb));
|
|
131
|
+
const b = linearized(blueFromArgb(argb));
|
|
132
|
+
return mathUtils.matrixMultiply([r, g, b], SRGB_TO_XYZ);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Converts a color represented in Lab color space into an ARGB
|
|
137
|
+
* integer.
|
|
138
|
+
*/
|
|
139
|
+
export function argbFromLab(l: number, a: number, b: number): number {
|
|
140
|
+
const whitePoint = WHITE_POINT_D65;
|
|
141
|
+
const fy = (l + 16.0) / 116.0;
|
|
142
|
+
const fx = a / 500.0 + fy;
|
|
143
|
+
const fz = fy - b / 200.0;
|
|
144
|
+
const xNormalized = labInvf(fx);
|
|
145
|
+
const yNormalized = labInvf(fy);
|
|
146
|
+
const zNormalized = labInvf(fz);
|
|
147
|
+
const x = xNormalized * whitePoint[0];
|
|
148
|
+
const y = yNormalized * whitePoint[1];
|
|
149
|
+
const z = zNormalized * whitePoint[2];
|
|
150
|
+
return argbFromXyz(x, y, z);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Converts a color from ARGB representation to L*a*b*
|
|
155
|
+
* representation.
|
|
156
|
+
*
|
|
157
|
+
* @param argb the ARGB representation of a color
|
|
158
|
+
* @return a Lab object representing the color
|
|
159
|
+
*/
|
|
160
|
+
export function labFromArgb(argb: number): number[] {
|
|
161
|
+
const linearR = linearized(redFromArgb(argb));
|
|
162
|
+
const linearG = linearized(greenFromArgb(argb));
|
|
163
|
+
const linearB = linearized(blueFromArgb(argb));
|
|
164
|
+
const matrix = SRGB_TO_XYZ;
|
|
165
|
+
const x =
|
|
166
|
+
matrix[0][0] * linearR + matrix[0][1] * linearG + matrix[0][2] * linearB;
|
|
167
|
+
const y =
|
|
168
|
+
matrix[1][0] * linearR + matrix[1][1] * linearG + matrix[1][2] * linearB;
|
|
169
|
+
const z =
|
|
170
|
+
matrix[2][0] * linearR + matrix[2][1] * linearG + matrix[2][2] * linearB;
|
|
171
|
+
const whitePoint = WHITE_POINT_D65;
|
|
172
|
+
const xNormalized = x / whitePoint[0];
|
|
173
|
+
const yNormalized = y / whitePoint[1];
|
|
174
|
+
const zNormalized = z / whitePoint[2];
|
|
175
|
+
const fx = labF(xNormalized);
|
|
176
|
+
const fy = labF(yNormalized);
|
|
177
|
+
const fz = labF(zNormalized);
|
|
178
|
+
const l = 116.0 * fy - 16;
|
|
179
|
+
const a = 500.0 * (fx - fy);
|
|
180
|
+
const b = 200.0 * (fy - fz);
|
|
181
|
+
return [l, a, b];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Converts an L* value to an ARGB representation.
|
|
186
|
+
*
|
|
187
|
+
* @param lstar L* in L*a*b*
|
|
188
|
+
* @return ARGB representation of grayscale color with lightness
|
|
189
|
+
* matching L*
|
|
190
|
+
*/
|
|
191
|
+
export function argbFromLstar(lstar: number): number {
|
|
192
|
+
const y = yFromLstar(lstar);
|
|
193
|
+
const component = delinearized(y);
|
|
194
|
+
return argbFromRgb(component, component, component);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Computes the L* value of a color in ARGB representation.
|
|
199
|
+
*
|
|
200
|
+
* @param argb ARGB representation of a color
|
|
201
|
+
* @return L*, from L*a*b*, coordinate of the color
|
|
202
|
+
*/
|
|
203
|
+
export function lstarFromArgb(argb: number): number {
|
|
204
|
+
const y = xyzFromArgb(argb)[1];
|
|
205
|
+
return 116.0 * labF(y / 100.0) - 16.0;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Converts an L* value to a Y value.
|
|
210
|
+
*
|
|
211
|
+
* L* in L*a*b* and Y in XYZ measure the same quantity, luminance.
|
|
212
|
+
*
|
|
213
|
+
* L* measures perceptual luminance, a linear scale. Y in XYZ
|
|
214
|
+
* measures relative luminance, a logarithmic scale.
|
|
215
|
+
*
|
|
216
|
+
* @param lstar L* in L*a*b*
|
|
217
|
+
* @return Y in XYZ
|
|
218
|
+
*/
|
|
219
|
+
export function yFromLstar(lstar: number): number {
|
|
220
|
+
return 100.0 * labInvf((lstar + 16.0) / 116.0);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Converts a Y value to an L* value.
|
|
225
|
+
*
|
|
226
|
+
* L* in L*a*b* and Y in XYZ measure the same quantity, luminance.
|
|
227
|
+
*
|
|
228
|
+
* L* measures perceptual luminance, a linear scale. Y in XYZ
|
|
229
|
+
* measures relative luminance, a logarithmic scale.
|
|
230
|
+
*
|
|
231
|
+
* @param y Y in XYZ
|
|
232
|
+
* @return L* in L*a*b*
|
|
233
|
+
*/
|
|
234
|
+
export function lstarFromY(y: number): number {
|
|
235
|
+
return labF(y / 100.0) * 116.0 - 16.0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Linearizes an RGB component.
|
|
240
|
+
*
|
|
241
|
+
* @param rgbComponent 0 <= rgb_component <= 255, represents R/G/B
|
|
242
|
+
* channel
|
|
243
|
+
* @return 0.0 <= output <= 100.0, color channel converted to
|
|
244
|
+
* linear RGB space
|
|
245
|
+
*/
|
|
246
|
+
export function linearized(rgbComponent: number): number {
|
|
247
|
+
const normalized = rgbComponent / 255.0;
|
|
248
|
+
if (normalized <= 0.040449936) {
|
|
249
|
+
return normalized / 12.92 * 100.0;
|
|
250
|
+
} else {
|
|
251
|
+
return Math.pow((normalized + 0.055) / 1.055, 2.4) * 100.0;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Delinearizes an RGB component.
|
|
257
|
+
*
|
|
258
|
+
* @param rgbComponent 0.0 <= rgb_component <= 100.0, represents
|
|
259
|
+
* linear R/G/B channel
|
|
260
|
+
* @return 0 <= output <= 255, color channel converted to regular
|
|
261
|
+
* RGB space
|
|
262
|
+
*/
|
|
263
|
+
export function delinearized(rgbComponent: number): number {
|
|
264
|
+
const normalized = rgbComponent / 100.0;
|
|
265
|
+
let delinearized = 0.0;
|
|
266
|
+
if (normalized <= 0.0031308) {
|
|
267
|
+
delinearized = normalized * 12.92;
|
|
268
|
+
} else {
|
|
269
|
+
delinearized = 1.055 * Math.pow(normalized, 1.0 / 2.4) - 0.055;
|
|
270
|
+
}
|
|
271
|
+
return mathUtils.clampInt(0, 255, Math.round(delinearized * 255.0));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Returns the standard white point; white on a sunny day.
|
|
276
|
+
*
|
|
277
|
+
* @return The white point
|
|
278
|
+
*/
|
|
279
|
+
export function whitePointD65(): number[] {
|
|
280
|
+
return WHITE_POINT_D65;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function labF(t: number): number {
|
|
284
|
+
const e = 216.0 / 24389.0;
|
|
285
|
+
const kappa = 24389.0 / 27.0;
|
|
286
|
+
if (t > e) {
|
|
287
|
+
return Math.pow(t, 1.0 / 3.0);
|
|
288
|
+
} else {
|
|
289
|
+
return (kappa * t + 16) / 116;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function labInvf(ft: number): number {
|
|
294
|
+
const e = 216.0 / 24389.0;
|
|
295
|
+
const kappa = 24389.0 / 27.0;
|
|
296
|
+
const ft3 = ft * ft * ft;
|
|
297
|
+
if (ft3 > e) {
|
|
298
|
+
return ft3;
|
|
299
|
+
} else {
|
|
300
|
+
return (116 * ft - 16) / kappa;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2021 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// Vendored from material-foundation/material-color-utilities v0.4.0
|
|
19
|
+
// (commit dd62982dfdefdfc9232ce8d76e122fb1c6d188ae, typescript/). Modified:
|
|
20
|
+
// relative import specifiers drop the `.js` suffix so Metro and Jest resolve them.
|
|
21
|
+
// This file is automatically generated. Do not modify it.
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Utility methods for mathematical operations.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The signum function.
|
|
29
|
+
*
|
|
30
|
+
* @return 1 if num > 0, -1 if num < 0, and 0 if num = 0
|
|
31
|
+
*/
|
|
32
|
+
export function signum(num: number): number {
|
|
33
|
+
if (num < 0) {
|
|
34
|
+
return -1;
|
|
35
|
+
} else if (num === 0) {
|
|
36
|
+
return 0;
|
|
37
|
+
} else {
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The linear interpolation function.
|
|
44
|
+
*
|
|
45
|
+
* @return start if amount = 0 and stop if amount = 1
|
|
46
|
+
*/
|
|
47
|
+
export function lerp(start: number, stop: number, amount: number): number {
|
|
48
|
+
return (1.0 - amount) * start + amount * stop;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Clamps an integer between two integers.
|
|
53
|
+
*
|
|
54
|
+
* @return input when min <= input <= max, and either min or max
|
|
55
|
+
* otherwise.
|
|
56
|
+
*/
|
|
57
|
+
export function clampInt(min: number, max: number, input: number): number {
|
|
58
|
+
if (input < min) {
|
|
59
|
+
return min;
|
|
60
|
+
} else if (input > max) {
|
|
61
|
+
return max;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return input;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Clamps an integer between two floating-point numbers.
|
|
69
|
+
*
|
|
70
|
+
* @return input when min <= input <= max, and either min or max
|
|
71
|
+
* otherwise.
|
|
72
|
+
*/
|
|
73
|
+
export function clampDouble(min: number, max: number, input: number): number {
|
|
74
|
+
if (input < min) {
|
|
75
|
+
return min;
|
|
76
|
+
} else if (input > max) {
|
|
77
|
+
return max;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return input;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Sanitizes a degree measure as an integer.
|
|
85
|
+
*
|
|
86
|
+
* @return a degree measure between 0 (inclusive) and 360
|
|
87
|
+
* (exclusive).
|
|
88
|
+
*/
|
|
89
|
+
export function sanitizeDegreesInt(degrees: number): number {
|
|
90
|
+
degrees = degrees % 360;
|
|
91
|
+
if (degrees < 0) {
|
|
92
|
+
degrees = degrees + 360;
|
|
93
|
+
}
|
|
94
|
+
return degrees;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Sanitizes a degree measure as a floating-point number.
|
|
99
|
+
*
|
|
100
|
+
* @return a degree measure between 0.0 (inclusive) and 360.0
|
|
101
|
+
* (exclusive).
|
|
102
|
+
*/
|
|
103
|
+
export function sanitizeDegreesDouble(degrees: number): number {
|
|
104
|
+
degrees = degrees % 360.0;
|
|
105
|
+
if (degrees < 0) {
|
|
106
|
+
degrees = degrees + 360.0;
|
|
107
|
+
}
|
|
108
|
+
return degrees;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Sign of direction change needed to travel from one angle to
|
|
113
|
+
* another.
|
|
114
|
+
*
|
|
115
|
+
* For angles that are 180 degrees apart from each other, both
|
|
116
|
+
* directions have the same travel distance, so either direction is
|
|
117
|
+
* shortest. The value 1.0 is returned in this case.
|
|
118
|
+
*
|
|
119
|
+
* @param from The angle travel starts from, in degrees.
|
|
120
|
+
* @param to The angle travel ends at, in degrees.
|
|
121
|
+
* @return -1 if decreasing from leads to the shortest travel
|
|
122
|
+
* distance, 1 if increasing from leads to the shortest travel
|
|
123
|
+
* distance.
|
|
124
|
+
*/
|
|
125
|
+
export function rotationDirection(from: number, to: number): number {
|
|
126
|
+
const increasingDifference = sanitizeDegreesDouble(to - from);
|
|
127
|
+
return increasingDifference <= 180.0 ? 1.0 : -1.0;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Distance of two points on a circle, represented using degrees.
|
|
132
|
+
*/
|
|
133
|
+
export function differenceDegrees(a: number, b: number): number {
|
|
134
|
+
return 180.0 - Math.abs(Math.abs(a - b) - 180.0);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Multiplies a 1x3 row vector with a 3x3 matrix.
|
|
139
|
+
*/
|
|
140
|
+
export function matrixMultiply(row: number[], matrix: number[][]): number[] {
|
|
141
|
+
const a =
|
|
142
|
+
row[0] * matrix[0][0] + row[1] * matrix[0][1] + row[2] * matrix[0][2];
|
|
143
|
+
const b =
|
|
144
|
+
row[0] * matrix[1][0] + row[1] * matrix[1][1] + row[2] * matrix[1][2];
|
|
145
|
+
const c =
|
|
146
|
+
row[0] * matrix[2][0] + row[1] * matrix[2][1] + row[2] * matrix[2][2];
|
|
147
|
+
return [a, b, c];
|
|
148
|
+
}
|
package/src/types/style.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { BrandColors } from './brand';
|
|
2
|
-
import type { ThemeColors } from './colors';
|
|
3
|
-
import type { RadiusTokens, ShadowTokens, SpacingTokens, ZIndexTokens } from './tokens';
|
|
4
|
-
import type { Typography, TypographyConfig } from './typography';
|
|
5
|
-
|
|
6
|
-
export type DeepPartial<T> = {
|
|
7
|
-
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export interface StyleTheme {
|
|
11
|
-
color: ThemeColors;
|
|
12
|
-
typography: Typography;
|
|
13
|
-
spacing: SpacingTokens;
|
|
14
|
-
radius: RadiusTokens;
|
|
15
|
-
shadow: ShadowTokens;
|
|
16
|
-
zIndex: ZIndexTokens;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface StyleConfig {
|
|
20
|
-
brandColors: BrandColors;
|
|
21
|
-
typographyConfig?: TypographyConfig;
|
|
22
|
-
overrides?: {
|
|
23
|
-
light?: DeepPartial<StyleTheme>;
|
|
24
|
-
dark?: DeepPartial<StyleTheme>;
|
|
25
|
-
};
|
|
26
|
-
}
|
package/src/unistyles/types.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import 'react-native-unistyles';
|
|
2
|
-
import type { StyleTheme } from '../types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Use this interface for module augmentation in your host application
|
|
6
|
-
* so that react-native-unistyles is aware of the theme token shapes.
|
|
7
|
-
*
|
|
8
|
-
* Example (src/unistyles/setup.ts):
|
|
9
|
-
* ```ts
|
|
10
|
-
* import type { UnistylesThemeFromBrand } from '@chipmobilesdk/rn-theme';
|
|
11
|
-
*
|
|
12
|
-
* declare module 'react-native-unistyles' {
|
|
13
|
-
* export interface UnistylesThemes extends UnistylesThemeFromBrand {}
|
|
14
|
-
* }
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export interface UnistylesThemeFromBrand {
|
|
18
|
-
light: StyleTheme;
|
|
19
|
-
dark: StyleTheme;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare module 'react-native-unistyles' {
|
|
23
|
-
export interface UnistylesThemes extends UnistylesThemeFromBrand { }
|
|
24
|
-
}
|