@pagopa/io-app-design-system 5.1.3 → 5.2.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 (73) hide show
  1. package/lib/commonjs/components/index.js +22 -11
  2. package/lib/commonjs/components/index.js.map +1 -1
  3. package/lib/commonjs/components/listitems/ListItemRadio.js +18 -24
  4. package/lib/commonjs/components/listitems/ListItemRadio.js.map +1 -1
  5. package/lib/commonjs/components/listitems/ListItemTransaction.js +21 -22
  6. package/lib/commonjs/components/listitems/ListItemTransaction.js.map +1 -1
  7. package/lib/commonjs/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +84 -140
  8. package/lib/commonjs/components/modules/ModuleAttachment.js +5 -6
  9. package/lib/commonjs/components/modules/ModuleAttachment.js.map +1 -1
  10. package/lib/commonjs/components/modules/ModuleCheckout.js +15 -17
  11. package/lib/commonjs/components/modules/ModuleCheckout.js.map +1 -1
  12. package/lib/commonjs/components/modules/ModuleCredential.js +8 -9
  13. package/lib/commonjs/components/modules/ModuleCredential.js.map +1 -1
  14. package/lib/commonjs/components/modules/ModuleNavigation.js +11 -12
  15. package/lib/commonjs/components/modules/ModuleNavigation.js.map +1 -1
  16. package/lib/commonjs/components/modules/ModulePaymentNotice.js +13 -14
  17. package/lib/commonjs/components/modules/ModulePaymentNotice.js.map +1 -1
  18. package/lib/commonjs/components/skeleton/IOSkeleton.js +65 -0
  19. package/lib/commonjs/components/skeleton/IOSkeleton.js.map +1 -0
  20. package/lib/commonjs/components/skeleton/index.js +17 -0
  21. package/lib/commonjs/components/skeleton/index.js.map +1 -0
  22. package/lib/commonjs/core/IOColors.js +3 -1
  23. package/lib/commonjs/core/IOColors.js.map +1 -1
  24. package/lib/module/components/index.js +2 -1
  25. package/lib/module/components/index.js.map +1 -1
  26. package/lib/module/components/listitems/ListItemRadio.js +18 -24
  27. package/lib/module/components/listitems/ListItemRadio.js.map +1 -1
  28. package/lib/module/components/listitems/ListItemTransaction.js +24 -25
  29. package/lib/module/components/listitems/ListItemTransaction.js.map +1 -1
  30. package/lib/module/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +84 -140
  31. package/lib/module/components/modules/ModuleAttachment.js +5 -5
  32. package/lib/module/components/modules/ModuleAttachment.js.map +1 -1
  33. package/lib/module/components/modules/ModuleCheckout.js +16 -17
  34. package/lib/module/components/modules/ModuleCheckout.js.map +1 -1
  35. package/lib/module/components/modules/ModuleCredential.js +8 -9
  36. package/lib/module/components/modules/ModuleCredential.js.map +1 -1
  37. package/lib/module/components/modules/ModuleNavigation.js +12 -13
  38. package/lib/module/components/modules/ModuleNavigation.js.map +1 -1
  39. package/lib/module/components/modules/ModulePaymentNotice.js +14 -14
  40. package/lib/module/components/modules/ModulePaymentNotice.js.map +1 -1
  41. package/lib/module/components/skeleton/IOSkeleton.js +56 -0
  42. package/lib/module/components/skeleton/IOSkeleton.js.map +1 -0
  43. package/lib/module/components/skeleton/index.js +2 -0
  44. package/lib/module/components/skeleton/index.js.map +1 -0
  45. package/lib/module/core/IOColors.js +3 -1
  46. package/lib/module/core/IOColors.js.map +1 -1
  47. package/lib/typescript/components/index.d.ts +2 -1
  48. package/lib/typescript/components/index.d.ts.map +1 -1
  49. package/lib/typescript/components/listitems/ListItemRadio.d.ts.map +1 -1
  50. package/lib/typescript/components/listitems/ListItemTransaction.d.ts.map +1 -1
  51. package/lib/typescript/components/modules/ModuleAttachment.d.ts.map +1 -1
  52. package/lib/typescript/components/modules/ModuleCheckout.d.ts.map +1 -1
  53. package/lib/typescript/components/modules/ModuleCredential.d.ts.map +1 -1
  54. package/lib/typescript/components/modules/ModulePaymentNotice.d.ts.map +1 -1
  55. package/lib/typescript/components/skeleton/IOSkeleton.d.ts +23 -0
  56. package/lib/typescript/components/skeleton/IOSkeleton.d.ts.map +1 -0
  57. package/lib/typescript/components/skeleton/index.d.ts +2 -0
  58. package/lib/typescript/components/skeleton/index.d.ts.map +1 -0
  59. package/lib/typescript/core/IOColors.d.ts +1 -1
  60. package/lib/typescript/core/IOColors.d.ts.map +1 -1
  61. package/package.json +2 -3
  62. package/src/components/index.tsx +2 -1
  63. package/src/components/listitems/ListItemRadio.tsx +8 -15
  64. package/src/components/listitems/ListItemTransaction.tsx +11 -15
  65. package/src/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +84 -140
  66. package/src/components/modules/ModuleAttachment.tsx +3 -3
  67. package/src/components/modules/ModuleCheckout.tsx +6 -6
  68. package/src/components/modules/ModuleCredential.tsx +4 -4
  69. package/src/components/modules/ModuleNavigation.tsx +7 -7
  70. package/src/components/modules/ModulePaymentNotice.tsx +5 -5
  71. package/src/components/skeleton/IOSkeleton.tsx +107 -0
  72. package/src/components/skeleton/index.tsx +1 -0
  73. package/src/core/IOColors.ts +3 -0
@@ -1395,86 +1395,64 @@ exports[`Test List Item Components - Experimental Enabled ListItemTransaction S
1395
1395
  }
1396
1396
  >
1397
1397
  <View
1398
- collapsable={false}
1399
1398
  style={
1400
- {
1401
- "opacity": 0.5,
1402
- }
1403
- }
1404
- >
1405
- <View
1406
- height={44}
1407
- radius={8}
1408
- style={
1399
+ [
1409
1400
  {
1410
- "backgroundColor": "#efefef",
1401
+ "backgroundColor": "#E8EBF1",
1402
+ "borderCurve": "continuous",
1411
1403
  "borderRadius": 8,
1412
1404
  "height": 44,
1413
1405
  "width": 44,
1414
- }
1415
- }
1416
- width={44}
1417
- />
1418
- </View>
1406
+ },
1407
+ {
1408
+ "opacity": 0.75,
1409
+ },
1410
+ ]
1411
+ }
1412
+ />
1419
1413
  </View>
1420
1414
  <View
1421
1415
  style={
1422
1416
  {
1423
- "flex": 1,
1417
+ "display": "flex",
1418
+ "flexDirection": "column",
1419
+ "flexGrow": 1,
1420
+ "gap": 4,
1424
1421
  }
1425
1422
  }
1426
1423
  >
1427
1424
  <View
1428
- collapsable={false}
1429
1425
  style={
1430
- {
1431
- "opacity": 0.5,
1432
- }
1433
- }
1434
- >
1435
- <View
1436
- height={16}
1437
- radius={8}
1438
- style={
1426
+ [
1439
1427
  {
1440
- "backgroundColor": "#efefef",
1428
+ "backgroundColor": "#E8EBF1",
1429
+ "borderCurve": "continuous",
1441
1430
  "borderRadius": 8,
1442
1431
  "height": 16,
1443
1432
  "width": 62,
1444
- }
1445
- }
1446
- width={62}
1447
- />
1448
- </View>
1449
- <View
1450
- style={
1451
- {
1452
- "height": 4,
1453
- }
1433
+ },
1434
+ {
1435
+ "opacity": 0.75,
1436
+ },
1437
+ ]
1454
1438
  }
1455
1439
  />
1456
1440
  <View
1457
- collapsable={false}
1458
1441
  style={
1459
- {
1460
- "opacity": 0.5,
1461
- }
1462
- }
1463
- >
1464
- <View
1465
- height={16}
1466
- radius={8}
1467
- style={
1442
+ [
1468
1443
  {
1469
- "backgroundColor": "#efefef",
1444
+ "backgroundColor": "#E8EBF1",
1445
+ "borderCurve": "continuous",
1470
1446
  "borderRadius": 8,
1471
1447
  "height": 16,
1472
1448
  "width": 107,
1473
- }
1474
- }
1475
- width={107}
1476
- />
1477
- </View>
1449
+ },
1450
+ {
1451
+ "opacity": 0.75,
1452
+ },
1453
+ ]
1454
+ }
1455
+ />
1478
1456
  </View>
1479
1457
  <View
1480
1458
  style={
@@ -1484,27 +1462,21 @@ exports[`Test List Item Components - Experimental Enabled ListItemTransaction S
1484
1462
  }
1485
1463
  >
1486
1464
  <View
1487
- collapsable={false}
1488
1465
  style={
1489
- {
1490
- "opacity": 0.5,
1491
- }
1492
- }
1493
- >
1494
- <View
1495
- height={24}
1496
- radius={8}
1497
- style={
1466
+ [
1498
1467
  {
1499
- "backgroundColor": "#efefef",
1468
+ "backgroundColor": "#E8EBF1",
1469
+ "borderCurve": "continuous",
1500
1470
  "borderRadius": 8,
1501
1471
  "height": 24,
1502
1472
  "width": 70,
1503
- }
1504
- }
1505
- width={70}
1506
- />
1507
- </View>
1473
+ },
1474
+ {
1475
+ "opacity": 0.75,
1476
+ },
1477
+ ]
1478
+ }
1479
+ />
1508
1480
  </View>
1509
1481
  </View>
1510
1482
  </View>
@@ -2978,86 +2950,64 @@ exports[`Test List Item Components ListItemTransaction Snapshot 1`] = `
2978
2950
  }
2979
2951
  >
2980
2952
  <View
2981
- collapsable={false}
2982
2953
  style={
2983
- {
2984
- "opacity": 0.5,
2985
- }
2986
- }
2987
- >
2988
- <View
2989
- height={44}
2990
- radius={8}
2991
- style={
2954
+ [
2992
2955
  {
2993
- "backgroundColor": "#efefef",
2956
+ "backgroundColor": "#E8EBF1",
2957
+ "borderCurve": "continuous",
2994
2958
  "borderRadius": 8,
2995
2959
  "height": 44,
2996
2960
  "width": 44,
2997
- }
2998
- }
2999
- width={44}
3000
- />
3001
- </View>
2961
+ },
2962
+ {
2963
+ "opacity": 0.75,
2964
+ },
2965
+ ]
2966
+ }
2967
+ />
3002
2968
  </View>
3003
2969
  <View
3004
2970
  style={
3005
2971
  {
3006
- "flex": 1,
2972
+ "display": "flex",
2973
+ "flexDirection": "column",
2974
+ "flexGrow": 1,
2975
+ "gap": 4,
3007
2976
  }
3008
2977
  }
3009
2978
  >
3010
2979
  <View
3011
- collapsable={false}
3012
2980
  style={
3013
- {
3014
- "opacity": 0.5,
3015
- }
3016
- }
3017
- >
3018
- <View
3019
- height={16}
3020
- radius={8}
3021
- style={
2981
+ [
3022
2982
  {
3023
- "backgroundColor": "#efefef",
2983
+ "backgroundColor": "#E8EBF1",
2984
+ "borderCurve": "continuous",
3024
2985
  "borderRadius": 8,
3025
2986
  "height": 16,
3026
2987
  "width": 62,
3027
- }
3028
- }
3029
- width={62}
3030
- />
3031
- </View>
3032
- <View
3033
- style={
3034
- {
3035
- "height": 4,
3036
- }
2988
+ },
2989
+ {
2990
+ "opacity": 0.75,
2991
+ },
2992
+ ]
3037
2993
  }
3038
2994
  />
3039
2995
  <View
3040
- collapsable={false}
3041
2996
  style={
3042
- {
3043
- "opacity": 0.5,
3044
- }
3045
- }
3046
- >
3047
- <View
3048
- height={16}
3049
- radius={8}
3050
- style={
2997
+ [
3051
2998
  {
3052
- "backgroundColor": "#efefef",
2999
+ "backgroundColor": "#E8EBF1",
3000
+ "borderCurve": "continuous",
3053
3001
  "borderRadius": 8,
3054
3002
  "height": 16,
3055
3003
  "width": 107,
3056
- }
3057
- }
3058
- width={107}
3059
- />
3060
- </View>
3004
+ },
3005
+ {
3006
+ "opacity": 0.75,
3007
+ },
3008
+ ]
3009
+ }
3010
+ />
3061
3011
  </View>
3062
3012
  <View
3063
3013
  style={
@@ -3067,27 +3017,21 @@ exports[`Test List Item Components ListItemTransaction Snapshot 1`] = `
3067
3017
  }
3068
3018
  >
3069
3019
  <View
3070
- collapsable={false}
3071
3020
  style={
3072
- {
3073
- "opacity": 0.5,
3074
- }
3075
- }
3076
- >
3077
- <View
3078
- height={24}
3079
- radius={8}
3080
- style={
3021
+ [
3081
3022
  {
3082
- "backgroundColor": "#efefef",
3023
+ "backgroundColor": "#E8EBF1",
3024
+ "borderCurve": "continuous",
3083
3025
  "borderRadius": 8,
3084
3026
  "height": 24,
3085
3027
  "width": 70,
3086
- }
3087
- }
3088
- width={70}
3089
- />
3090
- </View>
3028
+ },
3029
+ {
3030
+ "opacity": 0.75,
3031
+ },
3032
+ ]
3033
+ }
3034
+ />
3091
3035
  </View>
3092
3036
  </View>
3093
3037
  </View>
@@ -1,11 +1,11 @@
1
1
  import React, { useCallback } from "react";
2
2
  import { GestureResponderEvent, PressableProps } from "react-native";
3
- import Placeholder from "rn-placeholder";
4
3
  import { IOListItemVisualParams, useIOTheme } from "../../core";
5
4
  import { WithTestID } from "../../utils/types";
6
5
  import { Badge } from "../badge";
7
6
  import { Icon } from "../icons";
8
7
  import { LoadingSpinner } from "../loadingSpinner";
8
+ import { IOSkeleton } from "../skeleton";
9
9
  import { HStack, VStack } from "../stack";
10
10
  import { Body } from "../typography";
11
11
  import { ModuleStatic } from "./ModuleStatic";
@@ -165,8 +165,8 @@ const ModuleAttachmentSkeleton = ({
165
165
  accessibilityState={{ busy: true }}
166
166
  startBlock={
167
167
  <VStack space={4}>
168
- <Placeholder.Box animate="fade" radius={8} width={114} height={16} />
169
- <Placeholder.Box animate="fade" radius={16} width={42} height={20} />
168
+ <IOSkeleton shape="rectangle" radius={8} width={114} height={16} />
169
+ <IOSkeleton shape="rectangle" radius={16} width={42} height={20} />
170
170
  </VStack>
171
171
  }
172
172
  />
@@ -6,7 +6,6 @@ import {
6
6
  StyleSheet,
7
7
  View
8
8
  } from "react-native";
9
- import Placeholder from "rn-placeholder";
10
9
  import {
11
10
  IOSelectionListItemVisualParams,
12
11
  IOSpacingScale,
@@ -14,8 +13,9 @@ import {
14
13
  } from "../../core";
15
14
  import { ButtonLink } from "../buttons";
16
15
  import { IOLogoPaymentType, LogoPayment } from "../logos";
16
+ import { IOSkeleton } from "../skeleton";
17
17
  import { HStack, VStack } from "../stack";
18
- import { H6, BodySmall } from "../typography";
18
+ import { BodySmall, H6 } from "../typography";
19
19
  import { ModuleStatic } from "./ModuleStatic";
20
20
  import { PressableModuleBase } from "./PressableModuleBase";
21
21
 
@@ -112,15 +112,15 @@ const ModuleCheckoutSkeleton = ({
112
112
  accessibilityState={{ busy: true }}
113
113
  startBlock={
114
114
  <HStack space={8} style={{ alignItems: "center" }}>
115
- <Placeholder.Box animate="fade" radius={8} height={24} width={24} />
115
+ <IOSkeleton shape="square" size={24} radius={8} />
116
116
  <VStack space={8}>
117
- <Placeholder.Box animate="fade" radius={8} height={20} width={170} />
118
- <Placeholder.Box animate="fade" radius={8} height={16} width={110} />
117
+ <IOSkeleton shape="rectangle" width={170} height={20} radius={8} />
118
+ <IOSkeleton shape="rectangle" width={110} height={16} radius={8} />
119
119
  </VStack>
120
120
  </HStack>
121
121
  }
122
122
  endBlock={
123
- <Placeholder.Box animate="fade" width={64} height={16} radius={8} />
123
+ <IOSkeleton shape="rectangle" width={64} height={16} radius={8} />
124
124
  }
125
125
  />
126
126
  );
@@ -5,7 +5,6 @@ import {
5
5
  ImageURISource,
6
6
  StyleSheet
7
7
  } from "react-native";
8
- import Placeholder from "rn-placeholder";
9
8
  import {
10
9
  IOListItemVisualParams,
11
10
  IOSelectionListItemVisualParams,
@@ -18,6 +17,7 @@ import { WithTestID } from "../../utils/types";
18
17
  import { Badge } from "../badge";
19
18
  import { IOIcons, Icon } from "../icons";
20
19
  import { LoadingSpinner } from "../loadingSpinner";
20
+ import { IOSkeleton } from "../skeleton";
21
21
  import { HStack } from "../stack/Stack";
22
22
  import { BodySmall } from "../typography";
23
23
  import { ModuleStatic } from "./ModuleStatic";
@@ -159,12 +159,12 @@ const ModuleCredentialSkeleton = ({
159
159
  style={{ alignItems: "center" }}
160
160
  space={IOVisualCostants.iconMargin as IOSpacer}
161
161
  >
162
- <Placeholder.Box animate="fade" width={24} height={24} radius={8} />
163
- <Placeholder.Box animate="fade" width={96} height={16} radius={8} />
162
+ <IOSkeleton shape="square" size={24} radius={8} />
163
+ <IOSkeleton shape="rectangle" width={96} height={16} radius={8} />
164
164
  </HStack>
165
165
  }
166
166
  endBlock={
167
- <Placeholder.Box animate="fade" width={64} height={24} radius={16} />
167
+ <IOSkeleton shape="rectangle" width={64} height={24} radius={16} />
168
168
  }
169
169
  />
170
170
  );
@@ -6,7 +6,6 @@ import {
6
6
  StyleSheet,
7
7
  View
8
8
  } from "react-native";
9
- import Placeholder from "rn-placeholder";
10
9
  import {
11
10
  IOListItemVisualParams,
12
11
  IOSelectionListItemVisualParams,
@@ -14,12 +13,13 @@ import {
14
13
  IOVisualCostants,
15
14
  useIOTheme
16
15
  } from "../../core";
16
+ import { useIOFontDynamicScale } from "../../utils/accessibility";
17
17
  import { WithTestID } from "../../utils/types";
18
18
  import { Badge } from "../badge";
19
19
  import { IOIcons, Icon } from "../icons";
20
+ import { IOSkeleton } from "../skeleton";
20
21
  import { HStack, VStack } from "../stack";
21
- import { LabelMini, BodySmall } from "../typography";
22
- import { useIOFontDynamicScale } from "../../utils/accessibility";
22
+ import { BodySmall, LabelMini } from "../typography";
23
23
  import { ModuleStatic } from "./ModuleStatic";
24
24
  import {
25
25
  PressableModuleBase,
@@ -128,15 +128,15 @@ const ModuleNavigationSkeleton = ({
128
128
  style={{ alignItems: "center" }}
129
129
  space={IOVisualCostants.iconMargin as IOSpacer}
130
130
  >
131
- <Placeholder.Box animate="fade" width={24} height={24} radius={8} />
131
+ <IOSkeleton shape="square" size={24} radius={8} />
132
132
  <VStack space={4}>
133
- <Placeholder.Box animate="fade" width={96} height={16} radius={8} />
134
- <Placeholder.Box animate="fade" width={160} height={12} radius={8} />
133
+ <IOSkeleton shape="rectangle" width={96} height={16} radius={8} />
134
+ <IOSkeleton shape="rectangle" width={160} height={12} radius={8} />
135
135
  </VStack>
136
136
  </HStack>
137
137
  }
138
138
  endBlock={
139
- <Placeholder.Box animate="fade" width={64} height={24} radius={16} />
139
+ <IOSkeleton shape="rectangle" width={64} height={24} radius={16} />
140
140
  }
141
141
  />
142
142
  );
@@ -1,12 +1,12 @@
1
1
  import * as React from "react";
2
2
  import { GestureResponderEvent, StyleSheet, View } from "react-native";
3
- import Placeholder from "rn-placeholder";
4
3
  import { IOListItemVisualParams, IOSpacer, useIOTheme } from "../../core";
5
4
  import { WithTestID } from "../../utils/types";
6
5
  import { Badge } from "../badge";
7
6
  import { Icon } from "../icons";
7
+ import { IOSkeleton } from "../skeleton";
8
8
  import { HStack, VStack } from "../stack";
9
- import { Body, H6, BodySmall } from "../typography";
9
+ import { Body, BodySmall, H6 } from "../typography";
10
10
  import { ModuleStatic } from "./ModuleStatic";
11
11
  import { PressableModuleBase } from "./PressableModuleBase";
12
12
 
@@ -172,12 +172,12 @@ const ModulePaymentNoticeSkeleton = ({
172
172
  accessibilityState={{ busy: true }}
173
173
  startBlock={
174
174
  <VStack space={4}>
175
- <Placeholder.Box animate="fade" radius={8} width={120} height={12} />
176
- <Placeholder.Box animate="fade" radius={8} width={180} height={16} />
175
+ <IOSkeleton shape="rectangle" width={120} height={12} radius={8} />
176
+ <IOSkeleton shape="rectangle" width={180} height={16} radius={8} />
177
177
  </VStack>
178
178
  }
179
179
  endBlock={
180
- <Placeholder.Box animate="fade" radius={16} width={64} height={24} />
180
+ <IOSkeleton shape="rectangle" width={64} height={24} radius={16} />
181
181
  }
182
182
  />
183
183
  );
@@ -0,0 +1,107 @@
1
+ import React, { useEffect, useMemo } from "react";
2
+ import { ColorValue, DimensionValue, ViewStyle } from "react-native";
3
+ import Animated, {
4
+ cancelAnimation,
5
+ Easing,
6
+ useAnimatedStyle,
7
+ useReducedMotion,
8
+ useSharedValue,
9
+ withRepeat,
10
+ withSequence,
11
+ withTiming
12
+ } from "react-native-reanimated";
13
+ import { IOColors, useIOTheme } from "../../core";
14
+ import { WithTestID } from "../../utils/types";
15
+
16
+ const ANIMATION_DURATION = 1250;
17
+ const [OPACITY_MIN, OPACITY_MAX] = [0.35, 0.75];
18
+ const OPACITY_REDUCED_MOTION = (OPACITY_MAX + OPACITY_MIN) / 2;
19
+
20
+ type IOSkeletonSquare = {
21
+ shape: "square";
22
+ size: number;
23
+ radius?: number;
24
+ width?: never;
25
+ height?: never;
26
+ };
27
+
28
+ type IOSkeletonRectangle = {
29
+ shape: "rectangle";
30
+ width: DimensionValue;
31
+ height: number;
32
+ radius?: number;
33
+ size?: never;
34
+ };
35
+
36
+ export type IOSkeleton = WithTestID<
37
+ (IOSkeletonSquare | IOSkeletonRectangle) & {
38
+ color?: ColorValue;
39
+ }
40
+ >;
41
+
42
+ export const IOSkeleton = ({
43
+ shape,
44
+ size,
45
+ width,
46
+ height,
47
+ radius: borderRadius,
48
+ color,
49
+ testID
50
+ }: IOSkeleton) => {
51
+ const reduceMotion = useReducedMotion();
52
+ const theme = useIOTheme();
53
+
54
+ const opacity = useSharedValue(
55
+ reduceMotion ? OPACITY_REDUCED_MOTION : OPACITY_MAX
56
+ );
57
+
58
+ const backgroundColor = color ?? IOColors[theme["skeleton-background"]];
59
+
60
+ const baseStyle: ViewStyle = useMemo(
61
+ () => ({
62
+ backgroundColor,
63
+ width: shape === "square" ? size : width,
64
+ height: shape === "square" ? size : height,
65
+ borderRadius,
66
+ borderCurve: "continuous"
67
+ }),
68
+ [backgroundColor, shape, size, width, height, borderRadius]
69
+ );
70
+
71
+ useEffect(() => {
72
+ if (reduceMotion) {
73
+ // eslint-disable-next-line functional/immutable-data
74
+ opacity.value = OPACITY_REDUCED_MOTION;
75
+ return;
76
+ }
77
+
78
+ const animationSequence = withRepeat(
79
+ withSequence(
80
+ withTiming(OPACITY_MIN, {
81
+ duration: ANIMATION_DURATION / 2,
82
+ easing: Easing.inOut(Easing.sin)
83
+ }),
84
+ withTiming(OPACITY_MAX, {
85
+ duration: ANIMATION_DURATION / 2,
86
+ easing: Easing.inOut(Easing.sin)
87
+ })
88
+ ),
89
+ -1,
90
+ true
91
+ );
92
+
93
+ // eslint-disable-next-line functional/immutable-data
94
+ opacity.value = animationSequence;
95
+
96
+ return () => {
97
+ cancelAnimation(opacity);
98
+ };
99
+ // eslint-disable-next-line react-hooks/exhaustive-deps
100
+ }, [reduceMotion]);
101
+
102
+ const animatedStyle = useAnimatedStyle(() => ({
103
+ opacity: opacity.value
104
+ }));
105
+
106
+ return <Animated.View testID={testID} style={[baseStyle, animatedStyle]} />;
107
+ };
@@ -0,0 +1 @@
1
+ export * from "./IOSkeleton";
@@ -244,6 +244,7 @@ const themeKeys = [
244
244
  "divider-default",
245
245
  "divider-bottomBar",
246
246
  "pdfViewer-background",
247
+ "skeleton-background",
247
248
  // Tab Item
248
249
  "tab-item-border-default",
249
250
  "tab-item-foreground-default",
@@ -313,6 +314,7 @@ export const IOThemeLight: IOTheme = {
313
314
  "divider-default": "grey-200",
314
315
  "divider-bottomBar": "grey-200",
315
316
  "pdfViewer-background": "grey-700",
317
+ "skeleton-background": "grey-100",
316
318
  // Tab Item
317
319
  "tab-item-border-default": "grey-300",
318
320
  "tab-item-foreground-default": "black",
@@ -381,6 +383,7 @@ export const IOThemeDark: IOTheme = {
381
383
  "divider-header": "grey-850",
382
384
  "divider-default": "grey-850",
383
385
  "divider-bottomBar": "grey-850",
386
+ "skeleton-background": "grey-850",
384
387
  // Status
385
388
  errorIcon: "error-400",
386
389
  errorText: "error-400",