@react-navigation/elements 3.0.0-alpha.23 → 3.0.0-alpha.25

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.
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
 
3
- import { useLinkProps, useTheme } from '@react-navigation/native';
3
+ import { MaterialSymbol, SFSymbol, useLinkProps, useTheme } from '@react-navigation/native';
4
4
  import * as React from 'react';
5
- import { Platform, StyleSheet } from 'react-native';
5
+ import { Image, Platform, StyleSheet, View } from 'react-native';
6
6
  import { Color } from "./Color.js";
7
7
  import { PlatformPressable } from "./PlatformPressable.js";
8
8
  import { Text } from "./Text.js";
9
- import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  const BUTTON_RADIUS = 40;
11
+ const ICON_SIZE = 14;
11
12
  export function Button(props) {
12
13
  if ('screen' in props || 'action' in props) {
13
14
  // @ts-expect-error: This is already type-checked by the prop types
@@ -47,7 +48,9 @@ function ButtonLink({
47
48
  function ButtonBase({
48
49
  variant = 'tinted',
49
50
  color: customColor,
51
+ icon,
50
52
  android_ripple,
53
+ disabled,
51
54
  style,
52
55
  children,
53
56
  ...rest
@@ -74,11 +77,20 @@ function ButtonBase({
74
77
  textColor = Color.foreground(backgroundColor);
75
78
  break;
76
79
  }
80
+ if (disabled) {
81
+ textColor = dark ? 'rgba(235, 235, 245, 0.3)' : 'rgba(60, 60, 67, 0.3)';
82
+ if (variant !== 'plain') {
83
+ backgroundColor = dark ? 'rgba(118, 118, 128, 0.24)' : 'rgba(118, 118, 128, 0.12)';
84
+ }
85
+ }
86
+ const rippleColor = Color(textColor)?.fade(0.88).string() ?? (variant === 'filled' || dark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(0, 0, 0, 0.12)');
87
+ const iconNode = renderIcon(icon, textColor, ICON_SIZE);
77
88
  return /*#__PURE__*/_jsx(PlatformPressable, {
78
89
  ...rest,
90
+ disabled: disabled,
79
91
  android_ripple: {
80
- radius: BUTTON_RADIUS,
81
- color: Color(textColor)?.fade(0.85).string() ?? 'rgba(0, 0, 0, 0.1)',
92
+ foreground: true,
93
+ color: rippleColor,
82
94
  ...android_ripple
83
95
  },
84
96
  pressOpacity: Platform.OS === 'ios' ? undefined : 1,
@@ -88,20 +100,81 @@ function ButtonBase({
88
100
  style: [{
89
101
  backgroundColor
90
102
  }, styles.button, style],
91
- children: /*#__PURE__*/_jsx(Text, {
92
- style: [{
93
- color: textColor
94
- }, fonts.regular, styles.text],
95
- children: children
103
+ children: /*#__PURE__*/_jsxs(View, {
104
+ style: styles.content,
105
+ children: [iconNode && /*#__PURE__*/_jsx(View, {
106
+ style: styles.icon,
107
+ children: iconNode
108
+ }), /*#__PURE__*/_jsx(Text, {
109
+ style: [{
110
+ color: textColor
111
+ }, fonts.regular, styles.text],
112
+ children: children
113
+ })]
96
114
  })
97
115
  });
98
116
  }
117
+ function renderIcon(icon, color, size) {
118
+ if (!icon) {
119
+ return null;
120
+ }
121
+ const iconValue = typeof icon === 'function' ? icon({
122
+ color,
123
+ size
124
+ }) : icon;
125
+ if (/*#__PURE__*/React.isValidElement(iconValue)) {
126
+ return iconValue;
127
+ }
128
+ if (typeof iconValue === 'object' && iconValue != null && 'type' in iconValue) {
129
+ switch (iconValue.type) {
130
+ case 'image':
131
+ return /*#__PURE__*/_jsx(Image, {
132
+ source: iconValue.source,
133
+ style: {
134
+ width: size,
135
+ height: size,
136
+ tintColor: iconValue.tinted === false ? undefined : color
137
+ }
138
+ });
139
+ case 'sfSymbol':
140
+ return /*#__PURE__*/_jsx(SFSymbol, {
141
+ name: iconValue.name,
142
+ size: size,
143
+ color: color
144
+ });
145
+ case 'materialSymbol':
146
+ return /*#__PURE__*/_jsx(MaterialSymbol, {
147
+ name: iconValue.name,
148
+ variant: iconValue.variant,
149
+ weight: iconValue.weight,
150
+ size: size,
151
+ color: color
152
+ });
153
+ default:
154
+ {
155
+ const _exhaustiveCheck = iconValue;
156
+ return _exhaustiveCheck;
157
+ }
158
+ }
159
+ }
160
+ return null;
161
+ }
99
162
  const styles = StyleSheet.create({
100
163
  button: {
101
164
  paddingHorizontal: 24,
102
165
  paddingVertical: 10,
103
166
  borderRadius: BUTTON_RADIUS,
104
- borderCurve: 'continuous'
167
+ borderCurve: 'continuous',
168
+ overflow: 'hidden'
169
+ },
170
+ content: {
171
+ flexDirection: 'row',
172
+ alignItems: 'center',
173
+ justifyContent: 'center',
174
+ gap: 8
175
+ },
176
+ icon: {
177
+ marginLeft: -6
105
178
  },
106
179
  text: {
107
180
  fontSize: 14,
@@ -1 +1 @@
1
- {"version":3,"names":["useLinkProps","useTheme","React","Platform","StyleSheet","Color","PlatformPressable","Text","jsx","_jsx","BUTTON_RADIUS","Button","props","ButtonLink","ButtonBase","screen","params","action","href","onPress","rest","e","variant","color","customColor","android_ripple","style","children","dark","colors","fonts","primary","backgroundColor","textColor","fade","string","foreground","radius","pressOpacity","OS","undefined","hoverEffect","styles","button","regular","text","create","paddingHorizontal","paddingVertical","borderRadius","borderCurve","fontSize","lineHeight","letterSpacing","textAlign"],"sourceRoot":"../../src","sources":["Button.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["MaterialSymbol","SFSymbol","useLinkProps","useTheme","React","Image","Platform","StyleSheet","View","Color","PlatformPressable","Text","jsx","_jsx","jsxs","_jsxs","BUTTON_RADIUS","ICON_SIZE","Button","props","ButtonLink","ButtonBase","screen","params","action","href","onPress","rest","e","variant","color","customColor","icon","android_ripple","disabled","style","children","dark","colors","fonts","primary","backgroundColor","textColor","fade","string","foreground","rippleColor","iconNode","renderIcon","pressOpacity","OS","undefined","hoverEffect","styles","button","content","regular","text","size","iconValue","isValidElement","type","source","width","height","tintColor","tinted","name","weight","_exhaustiveCheck","create","paddingHorizontal","paddingVertical","borderRadius","borderCurve","overflow","flexDirection","alignItems","justifyContent","gap","marginLeft","fontSize","lineHeight","letterSpacing","textAlign"],"sourceRoot":"../../src","sources":["Button.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
 
3
- // eslint-disable-next-line no-restricted-imports
4
- import OriginalColor from 'color';
5
3
  import { Platform } from 'react-native';
6
4
  import { DynamicColorIOS, PlatformColor } from './PlatformColor';
7
5
  export function Color(value) {
8
- if (typeof value === 'string' && !value.startsWith('var(')) {
9
- return OriginalColor(value);
6
+ if (typeof value === 'string') {
7
+ const parsed = parse(value);
8
+ if (parsed) {
9
+ return build(parsed);
10
+ }
10
11
  }
11
12
  return undefined;
12
13
  }
@@ -42,14 +43,466 @@ Color.foreground = color => {
42
43
  });
43
44
  }
44
45
  }
45
- } else if (typeof color === 'string' && !color.startsWith('var(')) {
46
- const processed = OriginalColor(color);
47
- if (processed.isLight()) {
48
- return processed.darken(0.71).string();
46
+ } else if (typeof color === 'string') {
47
+ const parsed = parse(color);
48
+ if (parsed && isLight(parsed)) {
49
+ return darken(parsed, 0.71).string();
49
50
  }
50
51
  }
51
52
  return '#fff';
52
53
  };
54
+ function build(parsed) {
55
+ function alpha(amount) {
56
+ if (amount === undefined) {
57
+ return clamp(parsed.parts[3], 0, 1);
58
+ }
59
+ const newParts = parsed.parts.slice();
60
+ newParts[3] = amount;
61
+ return build({
62
+ type: parsed.type,
63
+ parts: newParts
64
+ });
65
+ }
66
+ function fade(amount) {
67
+ const newParts = parsed.parts.slice();
68
+ newParts[3] = parsed.parts[3] * (1 - amount);
69
+ return build({
70
+ type: parsed.type,
71
+ parts: newParts
72
+ });
73
+ }
74
+ function string() {
75
+ return stringify(parsed);
76
+ }
77
+ return {
78
+ alpha,
79
+ fade,
80
+ string
81
+ };
82
+ }
83
+ function parse(color) {
84
+ if (color.toLowerCase() === 'transparent') {
85
+ return {
86
+ type: 'rgb',
87
+ parts: [0, 0, 0, 0]
88
+ };
89
+ }
90
+ const named = NAMED_COLORS[color.toLowerCase()];
91
+ if (named) {
92
+ return {
93
+ type: 'rgb',
94
+ parts: [...named, 1]
95
+ };
96
+ }
97
+ const hex = color.match(/^#([\da-f]+)$/i);
98
+ if (hex) {
99
+ // Normalize 3-digit (#rgb) and 4-digit (#rgba) hex to 6-digit (#rrggbb) and 8-digit (#rrggbbaa)
100
+ const digits = hex[1].length === 3 || hex[1].length === 4 ? Array.from(hex[1], d => d + d).join('') : hex[1];
101
+ if (digits.length !== 6 && digits.length !== 8) {
102
+ return undefined;
103
+ }
104
+ return {
105
+ type: 'rgb',
106
+ parts: [parseInt(digits.slice(0, 2), 16), parseInt(digits.slice(2, 4), 16), parseInt(digits.slice(4, 6), 16), digits.length === 8 ? parseInt(digits.slice(6, 8), 16) / 255 : 1]
107
+ };
108
+ }
109
+ const matched = color.match(/^([a-z]+)\(([^)]*)\)$/i);
110
+ if (!matched) {
111
+ return undefined;
112
+ }
113
+
114
+ // Get the color function name (e.g., "rgb", "hsl", "lab", etc.) and the color values
115
+ const fnName = matched[1].toLowerCase();
116
+ const argStr = matched[2];
117
+ const type = fnName === 'rgba' ? 'rgb' : fnName === 'hsla' ? 'hsl' : COLOR_TYPES.find(t => t === fnName);
118
+ if (!type) {
119
+ return undefined;
120
+ }
121
+
122
+ // Get values and optional alpha value based on the color format
123
+ // e.g. CSS L4 (rgb(255 0 0 / 0.5) or rgb(255 0 0 / 50%)) or CSS L3 (rgba(255, 0, 0, 0.5))
124
+ const slashIdx = argStr.indexOf('/');
125
+ const valuesStr = slashIdx >= 0 ? argStr.slice(0, slashIdx) : argStr;
126
+ let alphaStr = slashIdx >= 0 ? argStr.slice(slashIdx + 1).trim() : undefined;
127
+ const tokens = valuesStr.split(/[,\s]+/).filter(Boolean);
128
+ if (alphaStr === undefined && tokens.length === 4) {
129
+ alphaStr = tokens.pop();
130
+ }
131
+ if (tokens.length !== 3) {
132
+ return undefined;
133
+ }
134
+ const percent = max => value => parsePercent(value, max);
135
+ const parsers = {
136
+ rgb: [percent(255), percent(255), percent(255)],
137
+ hsl: [parseAngle, percent(100), percent(100)],
138
+ hwb: [parseAngle, percent(100), percent(100)],
139
+ lab: [percent(100), percent(125), percent(125)],
140
+ lch: [percent(100), percent(150), parseAngle],
141
+ oklch: [percent(1), percent(0.4), parseAngle],
142
+ oklab: [percent(1), percent(0.4), percent(0.4)]
143
+ };
144
+ try {
145
+ const parts = parsers[type].map((parseChannel, index) => parseChannel(tokens[index]));
146
+ const a = alphaStr === undefined ? 1 : parseAlpha(alphaStr);
147
+ parts.push(a);
148
+ return {
149
+ type,
150
+ parts
151
+ };
152
+ } catch {
153
+ return undefined;
154
+ }
155
+ }
156
+ function stringify(color) {
157
+ const [p0, p1, p2, rawA] = color.parts;
158
+ const a = trim(clamp(rawA, 0, 1));
159
+
160
+ // Legacy CSS L3: name(v1, v2, v3) / namea(v1, v2, v3, alpha)
161
+ const legacy = (name, v1, v2, v3) => a < 1 ? `${name}a(${v1}, ${v2}, ${v3}, ${a})` : `${name}(${v1}, ${v2}, ${v3})`;
162
+
163
+ // Modern CSS L4: name(v1 v2 v3) / name(v1 v2 v3 / alpha)
164
+ const modern = (name, v1, v2, v3) => a < 1 ? `${name}(${v1} ${v2} ${v3} / ${a})` : `${name}(${v1} ${v2} ${v3})`;
165
+ switch (color.type) {
166
+ case 'rgb':
167
+ return legacy('rgb', clamp(Math.round(p0), 0, 255), clamp(Math.round(p1), 0, 255), clamp(Math.round(p2), 0, 255));
168
+ case 'hsl':
169
+ return legacy('hsl', trim(p0), `${trim(clamp(p1, 0, 100))}%`, `${trim(clamp(p2, 0, 100))}%`);
170
+ case 'hwb':
171
+ return modern('hwb', trim(p0), `${trim(clamp(p1, 0, 100))}%`, `${trim(clamp(p2, 0, 100))}%`);
172
+ case 'lab':
173
+ return modern('lab', trim(clamp(p0, 0, 100)), trim(clamp(p1, -125, 125)), trim(clamp(p2, -125, 125)));
174
+ case 'oklab':
175
+ return modern('oklab', trim(clamp(p0, 0, 1)), trim(clamp(p1, -0.4, 0.4)), trim(clamp(p2, -0.4, 0.4)));
176
+ case 'lch':
177
+ return modern('lch', trim(clamp(p0, 0, 100)), trim(clamp(p1, 0, 150)), trim(p2));
178
+ case 'oklch':
179
+ return modern('oklch', trim(clamp(p0, 0, 1)), trim(clamp(p1, 0, 0.4)), trim(p2));
180
+ default:
181
+ {
182
+ const _exhaustiveCheck = color.type;
183
+ return _exhaustiveCheck;
184
+ }
185
+ }
186
+ }
187
+ function darken(color, amount) {
188
+ const factor = 1 - amount;
189
+ const parts = color.parts.slice();
190
+ switch (color.type) {
191
+ case 'lab':
192
+ case 'lch':
193
+ case 'oklab':
194
+ case 'oklch':
195
+ parts[0] *= factor;
196
+ return build({
197
+ type: color.type,
198
+ parts
199
+ });
200
+ case 'hsl':
201
+ parts[2] *= factor;
202
+ return build({
203
+ type: 'hsl',
204
+ parts
205
+ });
206
+ case 'rgb':
207
+ case 'hwb':
208
+ {
209
+ const [r, g, b] = color.type === 'hwb' ? hwbToRgb(parts[0], parts[1], parts[2]) : parts;
210
+ const [h, s, l] = rgbToHsl(r, g, b);
211
+ return build({
212
+ type: 'hsl',
213
+ parts: [h, s, l * factor, parts[3]]
214
+ });
215
+ }
216
+ default:
217
+ {
218
+ const _exhaustiveCheck = color.type;
219
+ return _exhaustiveCheck;
220
+ }
221
+ }
222
+ }
223
+
224
+ // YIQ luma midpoint (0-255)
225
+ // https://en.wikipedia.org/wiki/YIQ
226
+ const YIQ_LIGHT_THRESHOLD = 128;
227
+
228
+ // Rec. 601 luma coefficients (sum to 1.0)
229
+ const YIQ_WEIGHT_R = 0.299;
230
+ const YIQ_WEIGHT_G = 0.587;
231
+ const YIQ_WEIGHT_B = 0.114;
232
+ function isLight(color) {
233
+ let rgb;
234
+ switch (color.type) {
235
+ case 'lab':
236
+ case 'lch':
237
+ return color.parts[0] > 50;
238
+ case 'oklab':
239
+ case 'oklch':
240
+ return color.parts[0] > 0.5;
241
+ case 'rgb':
242
+ rgb = [color.parts[0], color.parts[1], color.parts[2]];
243
+ break;
244
+ case 'hsl':
245
+ rgb = hslToRgb(color.parts[0], color.parts[1], color.parts[2]);
246
+ break;
247
+ case 'hwb':
248
+ rgb = hwbToRgb(color.parts[0], color.parts[1], color.parts[2]);
249
+ break;
250
+ default:
251
+ {
252
+ const _exhaustiveCheck = color.type;
253
+ return _exhaustiveCheck;
254
+ }
255
+ }
256
+ const yiq = YIQ_WEIGHT_R * rgb[0] + YIQ_WEIGHT_G * rgb[1] + YIQ_WEIGHT_B * rgb[2];
257
+ return yiq > YIQ_LIGHT_THRESHOLD;
258
+ }
259
+ function trim(n) {
260
+ return Number(n.toFixed(3));
261
+ }
262
+ function clamp(n, min, max) {
263
+ return n < min ? min : n > max ? max : n;
264
+ }
265
+ function parseNumber(s) {
266
+ const n = Number(s);
267
+ if (s === '' || Number.isNaN(n)) {
268
+ throw new Error(`Invalid number: ${s}`);
269
+ }
270
+ return n;
271
+ }
272
+ function parsePercent(s, max) {
273
+ if (s.endsWith('%')) {
274
+ return parseNumber(s.slice(0, -1)) / 100 * max;
275
+ }
276
+ return parseNumber(s);
277
+ }
278
+ function parseAngle(s) {
279
+ let degrees;
280
+ if (s.endsWith('grad')) {
281
+ degrees = parseNumber(s.slice(0, -4)) * 0.9;
282
+ } else if (s.endsWith('turn')) {
283
+ degrees = parseNumber(s.slice(0, -4)) * 360;
284
+ } else if (s.endsWith('rad')) {
285
+ degrees = parseNumber(s.slice(0, -3)) * 180 / Math.PI;
286
+ } else if (s.endsWith('deg')) {
287
+ degrees = parseNumber(s.slice(0, -3));
288
+ } else {
289
+ degrees = parseNumber(s);
290
+ }
291
+ return (degrees % 360 + 360) % 360;
292
+ }
293
+ function parseAlpha(s) {
294
+ return s.endsWith('%') ? parseNumber(s.slice(0, -1)) / 100 : parseNumber(s);
295
+ }
296
+ function rgbToHsl(r, g, b) {
297
+ r /= 255;
298
+ g /= 255;
299
+ b /= 255;
300
+ const max = Math.max(r, g, b);
301
+ const min = Math.min(r, g, b);
302
+ const l = (max + min) / 2;
303
+ if (max === min) {
304
+ return [0, 0, l * 100];
305
+ }
306
+ const d = max - min;
307
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
308
+ let h;
309
+ if (max === r) {
310
+ h = (g - b) / d + (g < b ? 6 : 0);
311
+ } else if (max === g) {
312
+ h = (b - r) / d + 2;
313
+ } else {
314
+ h = (r - g) / d + 4;
315
+ }
316
+ return [h * 60, s * 100, l * 100];
317
+ }
318
+ function hslToRgb(h, s, l) {
319
+ s /= 100;
320
+ l /= 100;
321
+ const chroma = (1 - Math.abs(2 * l - 1)) * s;
322
+ const huePrime = (h % 360 + 360) % 360 / 60;
323
+ const secondary = chroma * (1 - Math.abs(huePrime % 2 - 1));
324
+ const lightnessOffset = l - chroma / 2;
325
+ let redPrime;
326
+ let greenPrime;
327
+ let bluePrime;
328
+ if (huePrime < 1) {
329
+ [redPrime, greenPrime, bluePrime] = [chroma, secondary, 0];
330
+ } else if (huePrime < 2) {
331
+ [redPrime, greenPrime, bluePrime] = [secondary, chroma, 0];
332
+ } else if (huePrime < 3) {
333
+ [redPrime, greenPrime, bluePrime] = [0, chroma, secondary];
334
+ } else if (huePrime < 4) {
335
+ [redPrime, greenPrime, bluePrime] = [0, secondary, chroma];
336
+ } else if (huePrime < 5) {
337
+ [redPrime, greenPrime, bluePrime] = [secondary, 0, chroma];
338
+ } else {
339
+ [redPrime, greenPrime, bluePrime] = [chroma, 0, secondary];
340
+ }
341
+ return [(redPrime + lightnessOffset) * 255, (greenPrime + lightnessOffset) * 255, (bluePrime + lightnessOffset) * 255];
342
+ }
343
+ function hwbToRgb(h, w, b) {
344
+ const whiteRatio = w / 100;
345
+ const blackRatio = b / 100;
346
+ if (whiteRatio + blackRatio >= 1) {
347
+ const gray = whiteRatio / (whiteRatio + blackRatio) * 255;
348
+ return [gray, gray, gray];
349
+ }
350
+ const [pureRed, pureGreen, pureBlue] = hslToRgb(h, 100, 50);
351
+ const factor = 1 - whiteRatio - blackRatio;
352
+ return [pureRed * factor + whiteRatio * 255, pureGreen * factor + whiteRatio * 255, pureBlue * factor + whiteRatio * 255];
353
+ }
354
+ const COLOR_TYPES = ['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklch', 'oklab'];
355
+ const NAMED_COLORS = {
356
+ aliceblue: [240, 248, 255],
357
+ antiquewhite: [250, 235, 215],
358
+ aqua: [0, 255, 255],
359
+ aquamarine: [127, 255, 212],
360
+ azure: [240, 255, 255],
361
+ beige: [245, 245, 220],
362
+ bisque: [255, 228, 196],
363
+ black: [0, 0, 0],
364
+ blanchedalmond: [255, 235, 205],
365
+ blue: [0, 0, 255],
366
+ blueviolet: [138, 43, 226],
367
+ brown: [165, 42, 42],
368
+ burntsienna: [234, 126, 93],
369
+ burlywood: [222, 184, 135],
370
+ cadetblue: [95, 158, 160],
371
+ chartreuse: [127, 255, 0],
372
+ chocolate: [210, 105, 30],
373
+ coral: [255, 127, 80],
374
+ cornflowerblue: [100, 149, 237],
375
+ cornsilk: [255, 248, 220],
376
+ crimson: [220, 20, 60],
377
+ cyan: [0, 255, 255],
378
+ darkblue: [0, 0, 139],
379
+ darkcyan: [0, 139, 139],
380
+ darkgoldenrod: [184, 134, 11],
381
+ darkgray: [169, 169, 169],
382
+ darkgreen: [0, 100, 0],
383
+ darkgrey: [169, 169, 169],
384
+ darkkhaki: [189, 183, 107],
385
+ darkmagenta: [139, 0, 139],
386
+ darkolivegreen: [85, 107, 47],
387
+ darkorange: [255, 140, 0],
388
+ darkorchid: [153, 50, 204],
389
+ darkred: [139, 0, 0],
390
+ darksalmon: [233, 150, 122],
391
+ darkseagreen: [143, 188, 143],
392
+ darkslateblue: [72, 61, 139],
393
+ darkslategray: [47, 79, 79],
394
+ darkslategrey: [47, 79, 79],
395
+ darkturquoise: [0, 206, 209],
396
+ darkviolet: [148, 0, 211],
397
+ deeppink: [255, 20, 147],
398
+ deepskyblue: [0, 191, 255],
399
+ dimgray: [105, 105, 105],
400
+ dimgrey: [105, 105, 105],
401
+ dodgerblue: [30, 144, 255],
402
+ firebrick: [178, 34, 34],
403
+ floralwhite: [255, 250, 240],
404
+ forestgreen: [34, 139, 34],
405
+ fuchsia: [255, 0, 255],
406
+ gainsboro: [220, 220, 220],
407
+ ghostwhite: [248, 248, 255],
408
+ gold: [255, 215, 0],
409
+ goldenrod: [218, 165, 32],
410
+ gray: [128, 128, 128],
411
+ green: [0, 128, 0],
412
+ greenyellow: [173, 255, 47],
413
+ grey: [128, 128, 128],
414
+ honeydew: [240, 255, 240],
415
+ hotpink: [255, 105, 180],
416
+ indianred: [205, 92, 92],
417
+ indigo: [75, 0, 130],
418
+ ivory: [255, 255, 240],
419
+ khaki: [240, 230, 140],
420
+ lavender: [230, 230, 250],
421
+ lavenderblush: [255, 240, 245],
422
+ lawngreen: [124, 252, 0],
423
+ lemonchiffon: [255, 250, 205],
424
+ lightblue: [173, 216, 230],
425
+ lightcoral: [240, 128, 128],
426
+ lightcyan: [224, 255, 255],
427
+ lightgoldenrodyellow: [250, 250, 210],
428
+ lightgray: [211, 211, 211],
429
+ lightgreen: [144, 238, 144],
430
+ lightgrey: [211, 211, 211],
431
+ lightpink: [255, 182, 193],
432
+ lightsalmon: [255, 160, 122],
433
+ lightseagreen: [32, 178, 170],
434
+ lightskyblue: [135, 206, 250],
435
+ lightslategray: [119, 136, 153],
436
+ lightslategrey: [119, 136, 153],
437
+ lightsteelblue: [176, 196, 222],
438
+ lightyellow: [255, 255, 224],
439
+ lime: [0, 255, 0],
440
+ limegreen: [50, 205, 50],
441
+ linen: [250, 240, 230],
442
+ magenta: [255, 0, 255],
443
+ maroon: [128, 0, 0],
444
+ mediumaquamarine: [102, 205, 170],
445
+ mediumblue: [0, 0, 205],
446
+ mediumorchid: [186, 85, 211],
447
+ mediumpurple: [147, 112, 219],
448
+ mediumseagreen: [60, 179, 113],
449
+ mediumslateblue: [123, 104, 238],
450
+ mediumspringgreen: [0, 250, 154],
451
+ mediumturquoise: [72, 209, 204],
452
+ mediumvioletred: [199, 21, 133],
453
+ midnightblue: [25, 25, 112],
454
+ mintcream: [245, 255, 250],
455
+ mistyrose: [255, 228, 225],
456
+ moccasin: [255, 228, 181],
457
+ navajowhite: [255, 222, 173],
458
+ navy: [0, 0, 128],
459
+ oldlace: [253, 245, 230],
460
+ olive: [128, 128, 0],
461
+ olivedrab: [107, 142, 35],
462
+ orange: [255, 165, 0],
463
+ orangered: [255, 69, 0],
464
+ orchid: [218, 112, 214],
465
+ palegoldenrod: [238, 232, 170],
466
+ palegreen: [152, 251, 152],
467
+ paleturquoise: [175, 238, 238],
468
+ palevioletred: [219, 112, 147],
469
+ papayawhip: [255, 239, 213],
470
+ peachpuff: [255, 218, 185],
471
+ peru: [205, 133, 63],
472
+ pink: [255, 192, 203],
473
+ plum: [221, 160, 221],
474
+ powderblue: [176, 224, 230],
475
+ purple: [128, 0, 128],
476
+ rebeccapurple: [102, 51, 153],
477
+ red: [255, 0, 0],
478
+ rosybrown: [188, 143, 143],
479
+ royalblue: [65, 105, 225],
480
+ saddlebrown: [139, 69, 19],
481
+ salmon: [250, 128, 114],
482
+ sandybrown: [244, 164, 96],
483
+ seagreen: [46, 139, 87],
484
+ seashell: [255, 245, 238],
485
+ sienna: [160, 82, 45],
486
+ silver: [192, 192, 192],
487
+ skyblue: [135, 206, 235],
488
+ slateblue: [106, 90, 205],
489
+ slategray: [112, 128, 144],
490
+ slategrey: [112, 128, 144],
491
+ snow: [255, 250, 250],
492
+ springgreen: [0, 255, 127],
493
+ steelblue: [70, 130, 180],
494
+ tan: [210, 180, 140],
495
+ teal: [0, 128, 128],
496
+ thistle: [216, 191, 216],
497
+ tomato: [255, 99, 71],
498
+ turquoise: [64, 224, 208],
499
+ violet: [238, 130, 238],
500
+ wheat: [245, 222, 179],
501
+ white: [255, 255, 255],
502
+ whitesmoke: [245, 245, 245],
503
+ yellow: [255, 255, 0],
504
+ yellowgreen: [154, 205, 50]
505
+ };
53
506
  const ANDROID_COLOR_MAP = {
54
507
  system_background_dark: 'system_on_background_dark',
55
508
  system_background_light: 'system_on_background_light',