@expokit/cli 0.4.3 → 0.5.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 (242) hide show
  1. package/README.md +30 -3
  2. package/bin/expo-kit.js +749 -288
  3. package/bin/lib.mjs +313 -4
  4. package/package.json +1 -1
  5. package/registry/_docs/action-sheet.json +1 -1
  6. package/registry/_docs/alert.json +6 -0
  7. package/registry/_docs/bottom-sheet.json +6 -0
  8. package/registry/_docs/bullet.json +6 -0
  9. package/registry/_docs/dialog.json +1 -1
  10. package/registry/_docs/drawer.json +3 -3
  11. package/registry/_docs/flip-calendar.json +106 -0
  12. package/registry/_docs/glass-search-bar.json +1 -1
  13. package/registry/_docs/grain.json +6 -1
  14. package/registry/_docs/isometric-bar.json +6 -0
  15. package/registry/_docs/liquidglass-tab.json +1 -1
  16. package/registry/_docs/password-input.json +1 -1
  17. package/registry/_docs/paywall.json +144 -0
  18. package/registry/_docs/pixel-bar.json +6 -0
  19. package/registry/_docs/polar-area.json +6 -0
  20. package/registry/_docs/qr-code-button.json +9 -3
  21. package/registry/_docs/ruler-time-picker.json +147 -0
  22. package/registry/_docs/scratch-card.json +7 -1
  23. package/registry/_docs/search-bar.json +1 -1
  24. package/registry/_docs/select.json +2 -2
  25. package/registry/_docs/slide-to-confirm.json +2 -2
  26. package/registry/_docs/spinner.json +1 -1
  27. package/registry/_docs/stateful-button.json +2 -2
  28. package/registry/_docs/swipe-deck.json +1 -1
  29. package/registry/_docs/time-picker.json +2 -2
  30. package/registry/_docs/timeline-chart.json +6 -0
  31. package/registry/_docs/toast.json +15 -3
  32. package/registry/_docs/treemap.json +6 -0
  33. package/registry/_docs/waterfall.json +6 -0
  34. package/registry/accordion/files/src/components/ui/accordion.tsx +6 -4
  35. package/registry/accordion/files/src/lib/kit.tsx +462 -12
  36. package/registry/accordion.json +1 -0
  37. package/registry/action-sheet/files/src/components/ui/action-sheet.tsx +50 -58
  38. package/registry/action-sheet/files/src/lib/kit.tsx +462 -12
  39. package/registry/action-sheet.json +1 -0
  40. package/registry/alert/files/src/components/ui/alert.tsx +20 -13
  41. package/registry/alert/files/src/lib/kit.tsx +462 -12
  42. package/registry/alert.json +3 -4
  43. package/registry/assistant-app.json +1 -0
  44. package/registry/avatar/files/src/components/ui/avatar.tsx +89 -74
  45. package/registry/avatar/files/src/lib/kit.tsx +462 -12
  46. package/registry/avatar.json +1 -0
  47. package/registry/badge/files/src/components/ui/badge.tsx +36 -36
  48. package/registry/badge/files/src/lib/kit.tsx +462 -12
  49. package/registry/badge.json +1 -0
  50. package/registry/bottom-nav/files/src/components/ui/bottom-nav.tsx +39 -44
  51. package/registry/bottom-nav/files/src/lib/kit.tsx +462 -12
  52. package/registry/bottom-nav.json +5 -0
  53. package/registry/bottom-sheet/files/src/components/ui/bottom-sheet.tsx +357 -300
  54. package/registry/bottom-sheet/files/src/lib/kit.tsx +462 -12
  55. package/registry/bottom-sheet.json +5 -1
  56. package/registry/bullet.json +1 -0
  57. package/registry/button/files/src/components/ui/button.tsx +23 -34
  58. package/registry/button/files/src/lib/kit.tsx +462 -12
  59. package/registry/button-3d/files/src/components/ui/button-3d.tsx +6 -9
  60. package/registry/button-3d/files/src/lib/kit.tsx +462 -12
  61. package/registry/button-3d.json +1 -0
  62. package/registry/button.json +1 -0
  63. package/registry/calendar/files/src/components/ui/calendar.tsx +77 -79
  64. package/registry/calendar/files/src/lib/kit.tsx +462 -12
  65. package/registry/calendar.json +1 -0
  66. package/registry/card/files/src/components/ui/card.tsx +7 -6
  67. package/registry/card/files/src/lib/kit.tsx +462 -12
  68. package/registry/card-stack.json +1 -0
  69. package/registry/card.json +1 -0
  70. package/registry/carousel.json +1 -0
  71. package/registry/chat.json +7 -0
  72. package/registry/checkbox/files/src/components/ui/checkbox.tsx +4 -4
  73. package/registry/checkbox/files/src/lib/kit.tsx +462 -12
  74. package/registry/checkbox.json +1 -0
  75. package/registry/checkout.json +1 -0
  76. package/registry/chip-group/files/src/components/ui/chip-group.tsx +24 -24
  77. package/registry/chip-group/files/src/lib/kit.tsx +462 -12
  78. package/registry/chip-group.json +1 -0
  79. package/registry/confetti/files/src/components/ui/confetti.tsx +15 -14
  80. package/registry/confetti.json +3 -6
  81. package/registry/coupon/files/src/components/ui/coupon.tsx +47 -52
  82. package/registry/coupon/files/src/components/ui/flip-card.tsx +9 -14
  83. package/registry/coupon/files/src/components/ui/tilt-card.tsx +80 -101
  84. package/registry/coupon/files/src/lib/kit.tsx +462 -12
  85. package/registry/coupon/files/src/lib/ticket-shape.tsx +54 -44
  86. package/registry/coupon.json +1 -0
  87. package/registry/cube-pager.json +1 -0
  88. package/registry/dashboard.json +1 -0
  89. package/registry/date-picker/files/src/components/ui/calendar.tsx +77 -79
  90. package/registry/date-picker/files/src/components/ui/date-picker.tsx +64 -71
  91. package/registry/date-picker/files/src/lib/kit.tsx +462 -12
  92. package/registry/date-picker.json +1 -0
  93. package/registry/dialog/files/src/components/ui/dialog.tsx +66 -68
  94. package/registry/dialog/files/src/lib/kit.tsx +462 -12
  95. package/registry/dialog.json +1 -0
  96. package/registry/donut-shop.json +1 -0
  97. package/registry/drawer/files/src/components/ui/drawer.tsx +76 -88
  98. package/registry/drawer/files/src/lib/kit.tsx +462 -12
  99. package/registry/drawer.json +1 -0
  100. package/registry/fab.json +1 -0
  101. package/registry/fintech-app.json +1 -0
  102. package/registry/flip-calendar/files/src/components/ui/flip-calendar.tsx +632 -0
  103. package/registry/flip-calendar/files/src/lib/kit.tsx +672 -0
  104. package/registry/flip-calendar.json +24 -0
  105. package/registry/flip-card/files/src/components/ui/flip-card.tsx +9 -14
  106. package/registry/flip-card/files/src/lib/kit.tsx +462 -12
  107. package/registry/flip-card.json +1 -0
  108. package/registry/floating-input/files/src/components/ui/floating-input.tsx +33 -33
  109. package/registry/floating-input/files/src/lib/kit.tsx +462 -12
  110. package/registry/floating-input.json +1 -0
  111. package/registry/food-app.json +1 -0
  112. package/registry/gift-card.json +1 -0
  113. package/registry/glass-button.json +5 -0
  114. package/registry/glass-nav-bar.json +1 -0
  115. package/registry/glass-search-bar.json +1 -0
  116. package/registry/glass-segmented.json +1 -0
  117. package/registry/glass-sheet.json +1 -0
  118. package/registry/glass-tab-bar.json +5 -0
  119. package/registry/glass.json +1 -0
  120. package/registry/grain/files/src/components/ui/grain.tsx +16 -14
  121. package/registry/grain.json +8 -6
  122. package/registry/inbox.json +1 -0
  123. package/registry/isometric-bar.json +1 -0
  124. package/registry/kit/files/src/lib/kit.tsx +462 -12
  125. package/registry/kit.json +1 -0
  126. package/registry/liquidglass-tab/files/src/app/_layout.tsx +0 -1
  127. package/registry/liquidglass-tab/files/src/components/GlassTabBar.tsx +29 -16
  128. package/registry/liquidglass-tab/files/src/components/TabScreen.tsx +33 -19
  129. package/registry/liquidglass-tab/files/src/lib/tab-icons.ts +1 -1
  130. package/registry/liquidglass-tab.json +1 -0
  131. package/registry/list-item/files/src/components/ui/list-item.tsx +43 -43
  132. package/registry/list-item/files/src/lib/kit.tsx +462 -12
  133. package/registry/list-item.json +1 -0
  134. package/registry/loyalty-card.json +1 -0
  135. package/registry/morphing-button-group.json +1 -0
  136. package/registry/number-ticker.json +1 -0
  137. package/registry/offers.json +1 -0
  138. package/registry/onboarding.json +1 -0
  139. package/registry/orb-reveal.json +1 -0
  140. package/registry/otp-input/files/src/components/ui/otp-input.tsx +49 -30
  141. package/registry/otp-input/files/src/lib/kit.tsx +462 -12
  142. package/registry/otp-input.json +1 -0
  143. package/registry/parallax-layers.json +1 -0
  144. package/registry/parallax-scroll.json +1 -0
  145. package/registry/password-input/files/src/components/ui/floating-input.tsx +33 -33
  146. package/registry/password-input/files/src/components/ui/password-input.tsx +29 -25
  147. package/registry/password-input/files/src/lib/kit.tsx +462 -12
  148. package/registry/password-input.json +1 -0
  149. package/registry/payment-card/files/src/components/ui/flip-card.tsx +9 -14
  150. package/registry/payment-card/files/src/components/ui/payment-card.tsx +26 -20
  151. package/registry/payment-card/files/src/components/ui/tilt-card.tsx +80 -101
  152. package/registry/payment-card/files/src/lib/kit.tsx +462 -12
  153. package/registry/payment-card.json +1 -0
  154. package/registry/paywall.json +23 -0
  155. package/registry/pixel-bar.json +1 -0
  156. package/registry/polar-area.json +1 -0
  157. package/registry/profile.json +1 -0
  158. package/registry/progress/files/src/components/ui/progress.tsx +31 -29
  159. package/registry/progress/files/src/lib/kit.tsx +462 -12
  160. package/registry/progress-steps/files/src/components/ui/progress-steps.tsx +21 -21
  161. package/registry/progress-steps/files/src/lib/kit.tsx +462 -12
  162. package/registry/progress-steps.json +1 -0
  163. package/registry/progress.json +1 -0
  164. package/registry/qr-code-button.json +1 -0
  165. package/registry/radio-group/files/src/components/ui/radio-group.tsx +19 -19
  166. package/registry/radio-group/files/src/lib/kit.tsx +462 -12
  167. package/registry/radio-group.json +1 -0
  168. package/registry/rating.json +1 -0
  169. package/registry/ring-carousel.json +1 -0
  170. package/registry/ruler-time-picker/files/src/components/ui/ruler-time-picker.tsx +832 -0
  171. package/registry/ruler-time-picker/files/src/lib/kit.tsx +672 -0
  172. package/registry/ruler-time-picker.json +26 -0
  173. package/registry/scratch-card.json +1 -0
  174. package/registry/search-bar/files/src/components/ui/search-bar.tsx +28 -28
  175. package/registry/search-bar/files/src/lib/kit.tsx +462 -12
  176. package/registry/search-bar.json +1 -0
  177. package/registry/search-results.json +4 -0
  178. package/registry/segmented-control/files/src/components/ui/segmented-control.tsx +11 -17
  179. package/registry/segmented-control/files/src/lib/kit.tsx +462 -12
  180. package/registry/segmented-control.json +1 -0
  181. package/registry/select/files/src/components/ui/select.tsx +107 -104
  182. package/registry/select/files/src/lib/kit.tsx +462 -12
  183. package/registry/select.json +6 -0
  184. package/registry/settings.json +1 -0
  185. package/registry/sign-in.json +1 -0
  186. package/registry/skeleton/files/src/components/ui/skeleton.tsx +149 -80
  187. package/registry/skeleton/files/src/lib/kit.tsx +462 -12
  188. package/registry/skeleton.json +1 -0
  189. package/registry/slide-to-confirm.json +1 -0
  190. package/registry/slider/files/src/components/ui/slider.tsx +106 -108
  191. package/registry/slider/files/src/lib/kit.tsx +462 -12
  192. package/registry/slider.json +5 -0
  193. package/registry/spin-wheel.json +1 -0
  194. package/registry/spinner/files/src/components/ui/spinner.tsx +39 -29
  195. package/registry/spinner/files/src/lib/kit.tsx +462 -12
  196. package/registry/spinner.json +6 -0
  197. package/registry/stateful-button/files/src/components/ui/stateful-button.tsx +39 -32
  198. package/registry/stateful-button/files/src/lib/kit.tsx +462 -12
  199. package/registry/stateful-button.json +5 -0
  200. package/registry/stepper/files/src/components/ui/stepper.tsx +40 -38
  201. package/registry/stepper/files/src/lib/kit.tsx +462 -12
  202. package/registry/stepper.json +1 -0
  203. package/registry/swipe-deck.json +1 -0
  204. package/registry/swipeable-row.json +4 -0
  205. package/registry/switch/files/src/components/ui/switch.tsx +41 -47
  206. package/registry/switch/files/src/lib/kit.tsx +462 -12
  207. package/registry/switch.json +1 -0
  208. package/registry/tabs/files/src/components/ui/tabs.tsx +61 -64
  209. package/registry/tabs/files/src/lib/kit.tsx +462 -12
  210. package/registry/tabs.json +1 -0
  211. package/registry/text-animation/files/src/components/ui/text-animation.tsx +55 -42
  212. package/registry/text-animation/files/src/lib/kit.tsx +462 -12
  213. package/registry/text-animation.json +7 -0
  214. package/registry/textarea/files/src/components/ui/textarea.tsx +10 -10
  215. package/registry/textarea/files/src/lib/kit.tsx +462 -12
  216. package/registry/textarea.json +1 -0
  217. package/registry/ticket-card.json +1 -0
  218. package/registry/ticket-shape/files/src/lib/kit.tsx +462 -12
  219. package/registry/ticket-shape/files/src/lib/ticket-shape.tsx +54 -44
  220. package/registry/ticket-shape.json +1 -0
  221. package/registry/tilt-card/files/src/components/ui/tilt-card.tsx +80 -101
  222. package/registry/tilt-card/files/src/lib/kit.tsx +462 -12
  223. package/registry/tilt-card.json +1 -0
  224. package/registry/time-picker/files/src/components/ui/time-picker.tsx +136 -131
  225. package/registry/time-picker/files/src/lib/kit.tsx +462 -12
  226. package/registry/time-picker.json +1 -0
  227. package/registry/timeline/files/src/components/ui/avatar.tsx +89 -74
  228. package/registry/timeline/files/src/components/ui/timeline.tsx +49 -57
  229. package/registry/timeline/files/src/lib/kit.tsx +462 -12
  230. package/registry/timeline-chart.json +1 -0
  231. package/registry/timeline.json +1 -0
  232. package/registry/toast/files/src/components/ui/toast.tsx +543 -465
  233. package/registry/toast/files/src/lib/kit.tsx +462 -12
  234. package/registry/toast.json +7 -5
  235. package/registry/treemap.json +1 -0
  236. package/registry/waterfall.json +1 -0
  237. package/registry/wheel-list.json +1 -0
  238. package/schema/components.schema.json +1 -0
  239. package/registry/alert/files/src/components/ui/button.tsx +0 -303
  240. package/registry/confetti/files/src/lib/kit.tsx +0 -222
  241. package/registry/grain/files/src/lib/kit.tsx +0 -222
  242. package/registry/toast/files/src/components/ui/button.tsx +0 -303
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useRef, useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import {
3
3
  AccessibilityInfo,
4
4
  Animated,
@@ -32,20 +32,20 @@ export type SpinnerSize = 'sm' | 'md' | 'lg' | 'xl';
32
32
  export type SpinnerLabelPosition = 'none' | 'right' | 'bottom';
33
33
 
34
34
  export interface SpinnerProps {
35
- variant?: SpinnerVariant;
35
+ variant?: SpinnerVariant | undefined;
36
36
  /** 'sm' 16 · 'md' 24 · 'lg' 36 · 'xl' 52 — or any number of points. */
37
- size?: SpinnerSize | number;
37
+ size?: SpinnerSize | number | undefined;
38
38
  /** Indicator colour (default: theme accent). */
39
- color?: string;
39
+ color?: string | undefined;
40
40
  /** Speed multiplier: 2 is twice as fast. */
41
- speed?: number;
42
- /** Read by screen readers, and shown when `labelPosition` is set. */
43
- label?: string;
41
+ speed?: number | undefined;
42
+ /** Read by screen readers, and shown when `labelPosition` is set (default: the kit's `labels.loading`). */
43
+ label?: string | undefined;
44
44
  /** Show `label` beside or under the spinner with an animated ellipsis (default 'none': screen readers only). */
45
- labelPosition?: SpinnerLabelPosition;
45
+ labelPosition?: SpinnerLabelPosition | undefined;
46
46
  /** Faint guide behind the motion: the full circle (ring, orbit, arc), the rail (line) or ghost bars (bars). */
47
- track?: boolean;
48
- style?: StyleProp<ViewStyle>;
47
+ track?: boolean | undefined;
48
+ style?: StyleProp<ViewStyle> | undefined;
49
49
  }
50
50
 
51
51
  const SIZES: Record<SpinnerSize, number> = { sm: 16, md: 24, lg: 36, xl: 52 };
@@ -79,7 +79,7 @@ function useReduceMotion() {
79
79
 
80
80
  /** Looping value 0 → 1. Each spinner part interpolates it. */
81
81
  function useLoop(duration: number, easing: (t: number) => number, native: boolean, running = true) {
82
- const v = useRef(new Animated.Value(0)).current;
82
+ const [v] = useState(() => new Animated.Value(0));
83
83
  useEffect(() => {
84
84
  v.setValue(0);
85
85
  if (!running) return;
@@ -107,15 +107,17 @@ const sine = Easing.inOut(Easing.sin);
107
107
  function eased(points: number[], values: number[], ease: (t: number) => number, steps = 12) {
108
108
  const inputRange: number[] = [];
109
109
  const outputRange: number[] = [];
110
+ const p = (i: number) => points[i] ?? 0;
111
+ const v = (i: number) => values[i] ?? 0;
110
112
  for (let i = 0; i < points.length - 1; i++) {
111
113
  for (let k = 0; k < steps; k++) {
112
114
  const t = k / steps;
113
- inputRange.push(points[i] + (points[i + 1] - points[i]) * t);
114
- outputRange.push(values[i] + (values[i + 1] - values[i]) * ease(t));
115
+ inputRange.push(p(i) + (p(i + 1) - p(i)) * t);
116
+ outputRange.push(v(i) + (v(i + 1) - v(i)) * ease(t));
115
117
  }
116
118
  }
117
- inputRange.push(points[points.length - 1]);
118
- outputRange.push(values[values.length - 1]);
119
+ inputRange.push(p(points.length - 1));
120
+ outputRange.push(v(values.length - 1));
119
121
  return { inputRange, outputRange };
120
122
  }
121
123
 
@@ -156,12 +158,13 @@ export function Spinner({
156
158
  size = 'md',
157
159
  color,
158
160
  speed = 1,
159
- label = 'Loading',
161
+ label: labelProp,
160
162
  labelPosition = 'none',
161
163
  track = false,
162
164
  style,
163
165
  }: SpinnerProps) {
164
- const { colors } = useKit();
166
+ const { colors, labels } = useKit();
167
+ const label = labelProp ?? labels.loading;
165
168
  const reduce = useReduceMotion();
166
169
  const px = typeof size === 'number' ? size : SIZES[size];
167
170
  const tint = color ?? colors.accent;
@@ -326,10 +329,10 @@ function Bars({ size, color, speed, track, reduce }: BodyProps) {
326
329
  const corner = radius.capsule(w);
327
330
  return (
328
331
  <View style={[styles.row, { gap: w * 0.6, height: h }]}>
329
- {BAR_RATE.map((rate, i) => {
332
+ {BARS.map(({ rate, phase, rest }, i) => {
330
333
  const scaleY = reduce
331
- ? BAR_REST[i]
332
- : t.interpolate(curve((u) => 0.28 + 0.72 * Math.abs(Math.sin(Math.PI * (rate * u + BAR_PHASE[i]))), 32));
334
+ ? rest
335
+ : t.interpolate(curve((u) => 0.28 + 0.72 * Math.abs(Math.sin(Math.PI * (rate * u + phase))), 32));
333
336
  return (
334
337
  <View key={i} style={{ width: w, height: h }}>
335
338
  {track ? <View style={[StyleSheet.absoluteFill, { borderRadius: corner, backgroundColor: alpha(color, 0.14) }]} /> : null}
@@ -340,9 +343,12 @@ function Bars({ size, color, speed, track, reduce }: BodyProps) {
340
343
  </View>
341
344
  );
342
345
  }
343
- const BAR_RATE = [1, 2, 1, 2];
344
- const BAR_PHASE = [0, 0.2, 0.55, 0.35];
345
- const BAR_REST = [0.5, 0.9, 0.35, 0.7];
346
+ const BARS = [
347
+ { rate: 1, phase: 0, rest: 0.5 },
348
+ { rate: 2, phase: 0.2, rest: 0.9 },
349
+ { rate: 1, phase: 0.55, rest: 0.35 },
350
+ { rate: 2, phase: 0.35, rest: 0.7 },
351
+ ];
346
352
 
347
353
  /** Two rings ripple out of a breathing core and fade (native scale/opacity). */
348
354
  function Pulse({ size, color, speed, track, reduce }: BodyProps) {
@@ -402,13 +408,17 @@ function Orbit({ size, color, speed, track, reduce }: BodyProps) {
402
408
  borderColor: alpha(color, track ? 0.28 : 0.16),
403
409
  }}
404
410
  />
405
- {[0.08, 0.04, 0].map((lag, i) => (
411
+ {[
412
+ { lag: 0.08, opacity: 0.2, scale: 0.6 },
413
+ { lag: 0.04, opacity: 0.4, scale: 0.8 },
414
+ { lag: 0, opacity: 1, scale: 1 },
415
+ ].map(({ lag, opacity, scale }) => (
406
416
  <Animated.View
407
417
  key={lag}
408
418
  style={[
409
419
  StyleSheet.absoluteFill,
410
420
  {
411
- opacity: [0.2, 0.4, 1][i],
421
+ opacity,
412
422
  transform: [
413
423
  { rotate: reduce ? `${45 - lag * 300}deg` : t.interpolate(curveDeg((u) => angle(u - lag), 36)) },
414
424
  ],
@@ -424,7 +434,7 @@ function Orbit({ size, color, speed, track, reduce }: BodyProps) {
424
434
  height: dot,
425
435
  borderRadius: dot / 2,
426
436
  backgroundColor: color,
427
- transform: [{ scale: [0.6, 0.8, 1][i] }],
437
+ transform: [{ scale }],
428
438
  }}
429
439
  />
430
440
  </Animated.View>
@@ -443,7 +453,7 @@ function Bounce({ size, color, speed, reduce }: BodyProps) {
443
453
  const squash = (u: number) => Math.max(0, 1 - Math.min(u, 1 - u) / 0.1);
444
454
  return (
445
455
  <View style={[styles.row, { width: size, height: size, gap: dot / 2, alignItems: 'flex-end', paddingBottom: size * 0.16 }]}>
446
- {[0, 1, 2].map((i) => {
456
+ {[1, 0.55, 0.15].map((rest, i) => {
447
457
  const at = (u: number) => wrap(u - i * 0.14);
448
458
  const sy = (u: number) => 1 - 0.32 * squash(at(u));
449
459
  return (
@@ -455,7 +465,7 @@ function Bounce({ size, color, speed, reduce }: BodyProps) {
455
465
  borderRadius: dot / 2,
456
466
  backgroundColor: color,
457
467
  transform: reduce
458
- ? [{ translateY: -lift * [1, 0.55, 0.15][i] }]
468
+ ? [{ translateY: -lift * rest }]
459
469
  : [
460
470
  // Shift down by the squash so the dot stays on the floor.
461
471
  { translateY: t.interpolate(curve((u) => -lift * height(at(u)) + (dot * (1 - sy(u))) / 2, 40)) },
@@ -579,7 +589,7 @@ function Arc({ size, color, speed, track, reduce }: BodyProps) {
579
589
  const c1 = 2 * Math.PI * r1;
580
590
  const c2 = 2 * Math.PI * r2;
581
591
  const ring = (r: number, dash: string | undefined, opacity = 1) => (
582
- <Circle cx={size / 2} cy={size / 2} r={r} stroke={color} strokeOpacity={opacity} strokeWidth={stroke} strokeLinecap="round" strokeDasharray={dash} fill="none" />
592
+ <Circle cx={size / 2} cy={size / 2} r={r} stroke={color} strokeOpacity={opacity} strokeWidth={stroke} strokeLinecap="round" {...(dash ? { strokeDasharray: dash } : null)} fill="none" />
583
593
  );
584
594
  const spin = (v: Animated.Value, dir: 1 | -1) => v.interpolate({ inputRange: [0, 1], outputRange: ['0deg', `${360 * dir}deg`] });
585
595
  return (