@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.
Files changed (42) hide show
  1. package/CHANGELOG.md +91 -23
  2. package/NOTICE +9 -0
  3. package/README.md +297 -154
  4. package/package.json +49 -50
  5. package/skills/sdk-rn-theme/SKILL.md +45 -30
  6. package/src/color/categorical.ts +33 -0
  7. package/src/color/contrast.ts +230 -0
  8. package/src/color/parse.ts +120 -0
  9. package/src/color/roles.ts +262 -0
  10. package/src/index.ts +23 -17
  11. package/src/integration/navigationTheme.ts +51 -0
  12. package/src/presets/byTone.ts +28 -0
  13. package/src/presets/layout.ts +38 -0
  14. package/src/presets/themePresets.ts +101 -0
  15. package/src/theme/buildThemes.ts +178 -0
  16. package/src/theme/errors.ts +34 -0
  17. package/src/theme/overrides.ts +142 -0
  18. package/src/theme/validateThemeConfig.ts +171 -0
  19. package/src/tokens/defaults.ts +103 -46
  20. package/src/tokens/typography.ts +144 -64
  21. package/src/types/brand.ts +16 -0
  22. package/src/types/colors.ts +80 -11
  23. package/src/types/index.ts +44 -5
  24. package/src/types/theme.ts +161 -0
  25. package/src/types/tokens.ts +47 -5
  26. package/src/types/typography.ts +46 -10
  27. package/src/unistyles/createUnistylesConfig.ts +165 -177
  28. package/src/unistyles/themeMode.ts +28 -0
  29. package/src/vendor/mcu/LICENSE +191 -0
  30. package/src/vendor/mcu/hct/cam16.ts +419 -0
  31. package/src/vendor/mcu/hct/hct.ts +216 -0
  32. package/src/vendor/mcu/hct/hct_solver.ts +557 -0
  33. package/src/vendor/mcu/hct/viewing_conditions.ts +121 -0
  34. package/src/vendor/mcu/index.ts +5 -0
  35. package/src/vendor/mcu/palettes/tonal_palette.ts +172 -0
  36. package/src/vendor/mcu/utils/color_utils.ts +302 -0
  37. package/src/vendor/mcu/utils/math_utils.ts +148 -0
  38. package/src/types/style.ts +0 -26
  39. package/src/unistyles/types.ts +0 -24
  40. package/src/unistyles/validateThemeConfig.ts +0 -154
  41. package/src/utils/colorGeneration.ts +0 -87
  42. 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
+ }
@@ -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
- }
@@ -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
- }