@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.
package/src/Color.tsx CHANGED
@@ -1,5 +1,3 @@
1
- // eslint-disable-next-line no-restricted-imports
2
- import OriginalColor from 'color';
3
1
  import { type ColorValue, Platform } from 'react-native';
4
2
 
5
3
  import { DynamicColorIOS, PlatformColor } from './PlatformColor';
@@ -8,13 +6,21 @@ type ColorType = {
8
6
  alpha(amount: number): ColorType;
9
7
  alpha(): number;
10
8
  fade(amount: number): ColorType;
11
- darken(amount: number): ColorType;
12
9
  string(): string;
13
10
  };
14
11
 
12
+ type ParsedColor = {
13
+ parts: number[];
14
+ type: (typeof COLOR_TYPES)[number];
15
+ };
16
+
15
17
  export function Color(value: ColorValue): ColorType | undefined {
16
- if (typeof value === 'string' && !value.startsWith('var(')) {
17
- return OriginalColor(value);
18
+ if (typeof value === 'string') {
19
+ const parsed = parse(value);
20
+
21
+ if (parsed) {
22
+ return build(parsed);
23
+ }
18
24
  }
19
25
 
20
26
  return undefined;
@@ -80,17 +86,599 @@ Color.foreground = (color: ColorValue): ColorValue => {
80
86
  });
81
87
  }
82
88
  }
83
- } else if (typeof color === 'string' && !color.startsWith('var(')) {
84
- const processed = OriginalColor(color);
89
+ } else if (typeof color === 'string') {
90
+ const parsed = parse(color);
85
91
 
86
- if (processed.isLight()) {
87
- return processed.darken(0.71).string();
92
+ if (parsed && isLight(parsed)) {
93
+ return darken(parsed, 0.71).string();
88
94
  }
89
95
  }
90
96
 
91
97
  return '#fff';
92
98
  };
93
99
 
100
+ function build(parsed: ParsedColor): ColorType {
101
+ function alpha(amount: number): ColorType;
102
+ function alpha(): number;
103
+ function alpha(amount?: number): ColorType | number {
104
+ if (amount === undefined) {
105
+ return clamp(parsed.parts[3], 0, 1);
106
+ }
107
+
108
+ const newParts = parsed.parts.slice();
109
+
110
+ newParts[3] = amount;
111
+
112
+ return build({ type: parsed.type, parts: newParts });
113
+ }
114
+
115
+ function fade(amount: number): ColorType {
116
+ const newParts = parsed.parts.slice();
117
+
118
+ newParts[3] = parsed.parts[3] * (1 - amount);
119
+
120
+ return build({ type: parsed.type, parts: newParts });
121
+ }
122
+
123
+ function string(): string {
124
+ return stringify(parsed);
125
+ }
126
+
127
+ return {
128
+ alpha,
129
+ fade,
130
+ string,
131
+ };
132
+ }
133
+
134
+ function parse(color: string): ParsedColor | undefined {
135
+ if (color.toLowerCase() === 'transparent') {
136
+ return { type: 'rgb', parts: [0, 0, 0, 0] };
137
+ }
138
+
139
+ const named = NAMED_COLORS[color.toLowerCase()];
140
+
141
+ if (named) {
142
+ return { type: 'rgb', parts: [...named, 1] };
143
+ }
144
+
145
+ const hex = color.match(/^#([\da-f]+)$/i);
146
+
147
+ if (hex) {
148
+ // Normalize 3-digit (#rgb) and 4-digit (#rgba) hex to 6-digit (#rrggbb) and 8-digit (#rrggbbaa)
149
+ const digits =
150
+ hex[1].length === 3 || hex[1].length === 4
151
+ ? Array.from(hex[1], (d) => d + d).join('')
152
+ : hex[1];
153
+
154
+ if (digits.length !== 6 && digits.length !== 8) {
155
+ return undefined;
156
+ }
157
+
158
+ return {
159
+ type: 'rgb',
160
+ parts: [
161
+ parseInt(digits.slice(0, 2), 16),
162
+ parseInt(digits.slice(2, 4), 16),
163
+ parseInt(digits.slice(4, 6), 16),
164
+ digits.length === 8 ? parseInt(digits.slice(6, 8), 16) / 255 : 1,
165
+ ],
166
+ };
167
+ }
168
+
169
+ const matched = color.match(/^([a-z]+)\(([^)]*)\)$/i);
170
+
171
+ if (!matched) {
172
+ return undefined;
173
+ }
174
+
175
+ // Get the color function name (e.g., "rgb", "hsl", "lab", etc.) and the color values
176
+ const fnName = matched[1].toLowerCase();
177
+ const argStr = matched[2];
178
+
179
+ const type =
180
+ fnName === 'rgba'
181
+ ? 'rgb'
182
+ : fnName === 'hsla'
183
+ ? 'hsl'
184
+ : COLOR_TYPES.find((t) => t === fnName);
185
+
186
+ if (!type) {
187
+ return undefined;
188
+ }
189
+
190
+ // Get values and optional alpha value based on the color format
191
+ // 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))
192
+ const slashIdx = argStr.indexOf('/');
193
+ const valuesStr = slashIdx >= 0 ? argStr.slice(0, slashIdx) : argStr;
194
+
195
+ let alphaStr = slashIdx >= 0 ? argStr.slice(slashIdx + 1).trim() : undefined;
196
+
197
+ const tokens = valuesStr.split(/[,\s]+/).filter(Boolean);
198
+
199
+ if (alphaStr === undefined && tokens.length === 4) {
200
+ alphaStr = tokens.pop();
201
+ }
202
+
203
+ if (tokens.length !== 3) {
204
+ return undefined;
205
+ }
206
+
207
+ const percent = (max: number) => (value: string) => parsePercent(value, max);
208
+
209
+ const parsers = {
210
+ rgb: [percent(255), percent(255), percent(255)],
211
+ hsl: [parseAngle, percent(100), percent(100)],
212
+ hwb: [parseAngle, percent(100), percent(100)],
213
+ lab: [percent(100), percent(125), percent(125)],
214
+ lch: [percent(100), percent(150), parseAngle],
215
+ oklch: [percent(1), percent(0.4), parseAngle],
216
+ oklab: [percent(1), percent(0.4), percent(0.4)],
217
+ };
218
+
219
+ try {
220
+ const parts = parsers[type].map((parseChannel, index) =>
221
+ parseChannel(tokens[index])
222
+ );
223
+
224
+ const a = alphaStr === undefined ? 1 : parseAlpha(alphaStr);
225
+
226
+ parts.push(a);
227
+
228
+ return { type, parts };
229
+ } catch {
230
+ return undefined;
231
+ }
232
+ }
233
+
234
+ function stringify(color: ParsedColor): string {
235
+ const [p0, p1, p2, rawA] = color.parts;
236
+ const a = trim(clamp(rawA, 0, 1));
237
+
238
+ // Legacy CSS L3: name(v1, v2, v3) / namea(v1, v2, v3, alpha)
239
+ const legacy = (
240
+ name: string,
241
+ v1: string | number,
242
+ v2: string | number,
243
+ v3: string | number
244
+ ) =>
245
+ a < 1
246
+ ? `${name}a(${v1}, ${v2}, ${v3}, ${a})`
247
+ : `${name}(${v1}, ${v2}, ${v3})`;
248
+
249
+ // Modern CSS L4: name(v1 v2 v3) / name(v1 v2 v3 / alpha)
250
+ const modern = (
251
+ name: string,
252
+ v1: string | number,
253
+ v2: string | number,
254
+ v3: string | number
255
+ ) =>
256
+ a < 1 ? `${name}(${v1} ${v2} ${v3} / ${a})` : `${name}(${v1} ${v2} ${v3})`;
257
+
258
+ switch (color.type) {
259
+ case 'rgb':
260
+ return legacy(
261
+ 'rgb',
262
+ clamp(Math.round(p0), 0, 255),
263
+ clamp(Math.round(p1), 0, 255),
264
+ clamp(Math.round(p2), 0, 255)
265
+ );
266
+ case 'hsl':
267
+ return legacy(
268
+ 'hsl',
269
+ trim(p0),
270
+ `${trim(clamp(p1, 0, 100))}%`,
271
+ `${trim(clamp(p2, 0, 100))}%`
272
+ );
273
+ case 'hwb':
274
+ return modern(
275
+ 'hwb',
276
+ trim(p0),
277
+ `${trim(clamp(p1, 0, 100))}%`,
278
+ `${trim(clamp(p2, 0, 100))}%`
279
+ );
280
+ case 'lab':
281
+ return modern(
282
+ 'lab',
283
+ trim(clamp(p0, 0, 100)),
284
+ trim(clamp(p1, -125, 125)),
285
+ trim(clamp(p2, -125, 125))
286
+ );
287
+ case 'oklab':
288
+ return modern(
289
+ 'oklab',
290
+ trim(clamp(p0, 0, 1)),
291
+ trim(clamp(p1, -0.4, 0.4)),
292
+ trim(clamp(p2, -0.4, 0.4))
293
+ );
294
+ case 'lch':
295
+ return modern(
296
+ 'lch',
297
+ trim(clamp(p0, 0, 100)),
298
+ trim(clamp(p1, 0, 150)),
299
+ trim(p2)
300
+ );
301
+ case 'oklch':
302
+ return modern(
303
+ 'oklch',
304
+ trim(clamp(p0, 0, 1)),
305
+ trim(clamp(p1, 0, 0.4)),
306
+ trim(p2)
307
+ );
308
+ default: {
309
+ const _exhaustiveCheck: never = color.type;
310
+
311
+ return _exhaustiveCheck;
312
+ }
313
+ }
314
+ }
315
+
316
+ function darken(color: ParsedColor, amount: number): ColorType {
317
+ const factor = 1 - amount;
318
+ const parts = color.parts.slice();
319
+
320
+ switch (color.type) {
321
+ case 'lab':
322
+ case 'lch':
323
+ case 'oklab':
324
+ case 'oklch':
325
+ parts[0] *= factor;
326
+
327
+ return build({ type: color.type, parts });
328
+ case 'hsl':
329
+ parts[2] *= factor;
330
+
331
+ return build({ type: 'hsl', parts });
332
+ case 'rgb':
333
+ case 'hwb': {
334
+ const [r, g, b] =
335
+ color.type === 'hwb' ? hwbToRgb(parts[0], parts[1], parts[2]) : parts;
336
+
337
+ const [h, s, l] = rgbToHsl(r, g, b);
338
+
339
+ return build({ type: 'hsl', parts: [h, s, l * factor, parts[3]] });
340
+ }
341
+ default: {
342
+ const _exhaustiveCheck: never = color.type;
343
+
344
+ return _exhaustiveCheck;
345
+ }
346
+ }
347
+ }
348
+
349
+ // YIQ luma midpoint (0-255)
350
+ // https://en.wikipedia.org/wiki/YIQ
351
+ const YIQ_LIGHT_THRESHOLD = 128;
352
+
353
+ // Rec. 601 luma coefficients (sum to 1.0)
354
+ const YIQ_WEIGHT_R = 0.299;
355
+ const YIQ_WEIGHT_G = 0.587;
356
+ const YIQ_WEIGHT_B = 0.114;
357
+
358
+ function isLight(color: ParsedColor): boolean {
359
+ let rgb: [number, number, number];
360
+
361
+ switch (color.type) {
362
+ case 'lab':
363
+ case 'lch':
364
+ return color.parts[0] > 50;
365
+ case 'oklab':
366
+ case 'oklch':
367
+ return color.parts[0] > 0.5;
368
+ case 'rgb':
369
+ rgb = [color.parts[0], color.parts[1], color.parts[2]];
370
+ break;
371
+ case 'hsl':
372
+ rgb = hslToRgb(color.parts[0], color.parts[1], color.parts[2]);
373
+ break;
374
+ case 'hwb':
375
+ rgb = hwbToRgb(color.parts[0], color.parts[1], color.parts[2]);
376
+ break;
377
+ default: {
378
+ const _exhaustiveCheck: never = color.type;
379
+
380
+ return _exhaustiveCheck;
381
+ }
382
+ }
383
+
384
+ const yiq =
385
+ YIQ_WEIGHT_R * rgb[0] + YIQ_WEIGHT_G * rgb[1] + YIQ_WEIGHT_B * rgb[2];
386
+
387
+ return yiq > YIQ_LIGHT_THRESHOLD;
388
+ }
389
+
390
+ function trim(n: number): number {
391
+ return Number(n.toFixed(3));
392
+ }
393
+
394
+ function clamp(n: number, min: number, max: number): number {
395
+ return n < min ? min : n > max ? max : n;
396
+ }
397
+
398
+ function parseNumber(s: string): number {
399
+ const n = Number(s);
400
+
401
+ if (s === '' || Number.isNaN(n)) {
402
+ throw new Error(`Invalid number: ${s}`);
403
+ }
404
+
405
+ return n;
406
+ }
407
+
408
+ function parsePercent(s: string, max: number): number {
409
+ if (s.endsWith('%')) {
410
+ return (parseNumber(s.slice(0, -1)) / 100) * max;
411
+ }
412
+
413
+ return parseNumber(s);
414
+ }
415
+
416
+ function parseAngle(s: string): number {
417
+ let degrees: number;
418
+
419
+ if (s.endsWith('grad')) {
420
+ degrees = parseNumber(s.slice(0, -4)) * 0.9;
421
+ } else if (s.endsWith('turn')) {
422
+ degrees = parseNumber(s.slice(0, -4)) * 360;
423
+ } else if (s.endsWith('rad')) {
424
+ degrees = (parseNumber(s.slice(0, -3)) * 180) / Math.PI;
425
+ } else if (s.endsWith('deg')) {
426
+ degrees = parseNumber(s.slice(0, -3));
427
+ } else {
428
+ degrees = parseNumber(s);
429
+ }
430
+
431
+ return ((degrees % 360) + 360) % 360;
432
+ }
433
+
434
+ function parseAlpha(s: string): number {
435
+ return s.endsWith('%') ? parseNumber(s.slice(0, -1)) / 100 : parseNumber(s);
436
+ }
437
+
438
+ function rgbToHsl(r: number, g: number, b: number): [number, number, number] {
439
+ r /= 255;
440
+ g /= 255;
441
+ b /= 255;
442
+
443
+ const max = Math.max(r, g, b);
444
+ const min = Math.min(r, g, b);
445
+ const l = (max + min) / 2;
446
+
447
+ if (max === min) {
448
+ return [0, 0, l * 100];
449
+ }
450
+
451
+ const d = max - min;
452
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
453
+ let h: number;
454
+
455
+ if (max === r) {
456
+ h = (g - b) / d + (g < b ? 6 : 0);
457
+ } else if (max === g) {
458
+ h = (b - r) / d + 2;
459
+ } else {
460
+ h = (r - g) / d + 4;
461
+ }
462
+
463
+ return [h * 60, s * 100, l * 100];
464
+ }
465
+
466
+ function hslToRgb(h: number, s: number, l: number): [number, number, number] {
467
+ s /= 100;
468
+ l /= 100;
469
+
470
+ const chroma = (1 - Math.abs(2 * l - 1)) * s;
471
+ const huePrime = (((h % 360) + 360) % 360) / 60;
472
+ const secondary = chroma * (1 - Math.abs((huePrime % 2) - 1));
473
+ const lightnessOffset = l - chroma / 2;
474
+
475
+ let redPrime: number;
476
+ let greenPrime: number;
477
+ let bluePrime: number;
478
+
479
+ if (huePrime < 1) {
480
+ [redPrime, greenPrime, bluePrime] = [chroma, secondary, 0];
481
+ } else if (huePrime < 2) {
482
+ [redPrime, greenPrime, bluePrime] = [secondary, chroma, 0];
483
+ } else if (huePrime < 3) {
484
+ [redPrime, greenPrime, bluePrime] = [0, chroma, secondary];
485
+ } else if (huePrime < 4) {
486
+ [redPrime, greenPrime, bluePrime] = [0, secondary, chroma];
487
+ } else if (huePrime < 5) {
488
+ [redPrime, greenPrime, bluePrime] = [secondary, 0, chroma];
489
+ } else {
490
+ [redPrime, greenPrime, bluePrime] = [chroma, 0, secondary];
491
+ }
492
+
493
+ return [
494
+ (redPrime + lightnessOffset) * 255,
495
+ (greenPrime + lightnessOffset) * 255,
496
+ (bluePrime + lightnessOffset) * 255,
497
+ ];
498
+ }
499
+
500
+ function hwbToRgb(h: number, w: number, b: number): [number, number, number] {
501
+ const whiteRatio = w / 100;
502
+ const blackRatio = b / 100;
503
+
504
+ if (whiteRatio + blackRatio >= 1) {
505
+ const gray = (whiteRatio / (whiteRatio + blackRatio)) * 255;
506
+
507
+ return [gray, gray, gray];
508
+ }
509
+
510
+ const [pureRed, pureGreen, pureBlue] = hslToRgb(h, 100, 50);
511
+ const factor = 1 - whiteRatio - blackRatio;
512
+
513
+ return [
514
+ pureRed * factor + whiteRatio * 255,
515
+ pureGreen * factor + whiteRatio * 255,
516
+ pureBlue * factor + whiteRatio * 255,
517
+ ];
518
+ }
519
+
520
+ const COLOR_TYPES = [
521
+ 'rgb',
522
+ 'hsl',
523
+ 'hwb',
524
+ 'lab',
525
+ 'lch',
526
+ 'oklch',
527
+ 'oklab',
528
+ ] as const;
529
+
530
+ const NAMED_COLORS: Record<string, [number, number, number]> = {
531
+ aliceblue: [240, 248, 255],
532
+ antiquewhite: [250, 235, 215],
533
+ aqua: [0, 255, 255],
534
+ aquamarine: [127, 255, 212],
535
+ azure: [240, 255, 255],
536
+ beige: [245, 245, 220],
537
+ bisque: [255, 228, 196],
538
+ black: [0, 0, 0],
539
+ blanchedalmond: [255, 235, 205],
540
+ blue: [0, 0, 255],
541
+ blueviolet: [138, 43, 226],
542
+ brown: [165, 42, 42],
543
+ burntsienna: [234, 126, 93],
544
+ burlywood: [222, 184, 135],
545
+ cadetblue: [95, 158, 160],
546
+ chartreuse: [127, 255, 0],
547
+ chocolate: [210, 105, 30],
548
+ coral: [255, 127, 80],
549
+ cornflowerblue: [100, 149, 237],
550
+ cornsilk: [255, 248, 220],
551
+ crimson: [220, 20, 60],
552
+ cyan: [0, 255, 255],
553
+ darkblue: [0, 0, 139],
554
+ darkcyan: [0, 139, 139],
555
+ darkgoldenrod: [184, 134, 11],
556
+ darkgray: [169, 169, 169],
557
+ darkgreen: [0, 100, 0],
558
+ darkgrey: [169, 169, 169],
559
+ darkkhaki: [189, 183, 107],
560
+ darkmagenta: [139, 0, 139],
561
+ darkolivegreen: [85, 107, 47],
562
+ darkorange: [255, 140, 0],
563
+ darkorchid: [153, 50, 204],
564
+ darkred: [139, 0, 0],
565
+ darksalmon: [233, 150, 122],
566
+ darkseagreen: [143, 188, 143],
567
+ darkslateblue: [72, 61, 139],
568
+ darkslategray: [47, 79, 79],
569
+ darkslategrey: [47, 79, 79],
570
+ darkturquoise: [0, 206, 209],
571
+ darkviolet: [148, 0, 211],
572
+ deeppink: [255, 20, 147],
573
+ deepskyblue: [0, 191, 255],
574
+ dimgray: [105, 105, 105],
575
+ dimgrey: [105, 105, 105],
576
+ dodgerblue: [30, 144, 255],
577
+ firebrick: [178, 34, 34],
578
+ floralwhite: [255, 250, 240],
579
+ forestgreen: [34, 139, 34],
580
+ fuchsia: [255, 0, 255],
581
+ gainsboro: [220, 220, 220],
582
+ ghostwhite: [248, 248, 255],
583
+ gold: [255, 215, 0],
584
+ goldenrod: [218, 165, 32],
585
+ gray: [128, 128, 128],
586
+ green: [0, 128, 0],
587
+ greenyellow: [173, 255, 47],
588
+ grey: [128, 128, 128],
589
+ honeydew: [240, 255, 240],
590
+ hotpink: [255, 105, 180],
591
+ indianred: [205, 92, 92],
592
+ indigo: [75, 0, 130],
593
+ ivory: [255, 255, 240],
594
+ khaki: [240, 230, 140],
595
+ lavender: [230, 230, 250],
596
+ lavenderblush: [255, 240, 245],
597
+ lawngreen: [124, 252, 0],
598
+ lemonchiffon: [255, 250, 205],
599
+ lightblue: [173, 216, 230],
600
+ lightcoral: [240, 128, 128],
601
+ lightcyan: [224, 255, 255],
602
+ lightgoldenrodyellow: [250, 250, 210],
603
+ lightgray: [211, 211, 211],
604
+ lightgreen: [144, 238, 144],
605
+ lightgrey: [211, 211, 211],
606
+ lightpink: [255, 182, 193],
607
+ lightsalmon: [255, 160, 122],
608
+ lightseagreen: [32, 178, 170],
609
+ lightskyblue: [135, 206, 250],
610
+ lightslategray: [119, 136, 153],
611
+ lightslategrey: [119, 136, 153],
612
+ lightsteelblue: [176, 196, 222],
613
+ lightyellow: [255, 255, 224],
614
+ lime: [0, 255, 0],
615
+ limegreen: [50, 205, 50],
616
+ linen: [250, 240, 230],
617
+ magenta: [255, 0, 255],
618
+ maroon: [128, 0, 0],
619
+ mediumaquamarine: [102, 205, 170],
620
+ mediumblue: [0, 0, 205],
621
+ mediumorchid: [186, 85, 211],
622
+ mediumpurple: [147, 112, 219],
623
+ mediumseagreen: [60, 179, 113],
624
+ mediumslateblue: [123, 104, 238],
625
+ mediumspringgreen: [0, 250, 154],
626
+ mediumturquoise: [72, 209, 204],
627
+ mediumvioletred: [199, 21, 133],
628
+ midnightblue: [25, 25, 112],
629
+ mintcream: [245, 255, 250],
630
+ mistyrose: [255, 228, 225],
631
+ moccasin: [255, 228, 181],
632
+ navajowhite: [255, 222, 173],
633
+ navy: [0, 0, 128],
634
+ oldlace: [253, 245, 230],
635
+ olive: [128, 128, 0],
636
+ olivedrab: [107, 142, 35],
637
+ orange: [255, 165, 0],
638
+ orangered: [255, 69, 0],
639
+ orchid: [218, 112, 214],
640
+ palegoldenrod: [238, 232, 170],
641
+ palegreen: [152, 251, 152],
642
+ paleturquoise: [175, 238, 238],
643
+ palevioletred: [219, 112, 147],
644
+ papayawhip: [255, 239, 213],
645
+ peachpuff: [255, 218, 185],
646
+ peru: [205, 133, 63],
647
+ pink: [255, 192, 203],
648
+ plum: [221, 160, 221],
649
+ powderblue: [176, 224, 230],
650
+ purple: [128, 0, 128],
651
+ rebeccapurple: [102, 51, 153],
652
+ red: [255, 0, 0],
653
+ rosybrown: [188, 143, 143],
654
+ royalblue: [65, 105, 225],
655
+ saddlebrown: [139, 69, 19],
656
+ salmon: [250, 128, 114],
657
+ sandybrown: [244, 164, 96],
658
+ seagreen: [46, 139, 87],
659
+ seashell: [255, 245, 238],
660
+ sienna: [160, 82, 45],
661
+ silver: [192, 192, 192],
662
+ skyblue: [135, 206, 235],
663
+ slateblue: [106, 90, 205],
664
+ slategray: [112, 128, 144],
665
+ slategrey: [112, 128, 144],
666
+ snow: [255, 250, 250],
667
+ springgreen: [0, 255, 127],
668
+ steelblue: [70, 130, 180],
669
+ tan: [210, 180, 140],
670
+ teal: [0, 128, 128],
671
+ thistle: [216, 191, 216],
672
+ tomato: [255, 99, 71],
673
+ turquoise: [64, 224, 208],
674
+ violet: [238, 130, 238],
675
+ wheat: [245, 222, 179],
676
+ white: [255, 255, 255],
677
+ whitesmoke: [245, 245, 245],
678
+ yellow: [255, 255, 0],
679
+ yellowgreen: [154, 205, 50],
680
+ };
681
+
94
682
  const ANDROID_COLOR_MAP: Record<string, string> = {
95
683
  system_background_dark: 'system_on_background_dark',
96
684
  system_background_light: 'system_on_background_light',
@@ -1,4 +1,4 @@
1
- import { useTheme } from '@react-navigation/native';
1
+ import { IsFocusedContext, useTheme } from '@react-navigation/native';
2
2
  import * as React from 'react';
3
3
  import {
4
4
  Animated,
@@ -118,10 +118,22 @@ export function PlatformPressable({
118
118
  onPressOut?.(e);
119
119
  };
120
120
 
121
+ let focusable: boolean | undefined;
122
+
123
+ if (disabled) {
124
+ focusable = false;
125
+ } else if (Platform.isTV) {
126
+ // On `react-native-tvos`, the focus engine doesn't respect `aria-hidden` on screens
127
+ // So we hide them from TV focus engine for unfocused screens
128
+ focusable = React.use(IsFocusedContext);
129
+ }
130
+
121
131
  return (
122
132
  <AnimatedPressable
123
133
  ref={ref}
124
134
  accessible
135
+ disabled={disabled}
136
+ focusable={focusable}
125
137
  role={Platform.OS === 'web' && rest.href != null ? 'link' : 'button'}
126
138
  onPress={disabled ? undefined : handlePress}
127
139
  onPressIn={disabled ? undefined : handlePressIn}