@pagopa/io-app-design-system 4.0.1 → 4.1.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 (40) hide show
  1. package/lib/commonjs/components/alert/Alert.js +34 -7
  2. package/lib/commonjs/components/alert/Alert.js.map +1 -1
  3. package/lib/commonjs/components/banner/Banner.js +35 -20
  4. package/lib/commonjs/components/banner/Banner.js.map +1 -1
  5. package/lib/commonjs/components/banner/__test__/__snapshots__/banner.test.tsx.snap +36 -190
  6. package/lib/commonjs/components/featureInfo/FeatureInfo.js +27 -26
  7. package/lib/commonjs/components/featureInfo/FeatureInfo.js.map +1 -1
  8. package/lib/commonjs/components/spacer/Spacer.js +1 -1
  9. package/lib/commonjs/components/spacer/Spacer.js.map +1 -1
  10. package/lib/commonjs/components/stack/Stack.js +17 -14
  11. package/lib/commonjs/components/stack/Stack.js.map +1 -1
  12. package/lib/commonjs/core/IOColors.js.map +1 -1
  13. package/lib/module/components/alert/Alert.js +36 -9
  14. package/lib/module/components/alert/Alert.js.map +1 -1
  15. package/lib/module/components/banner/Banner.js +40 -25
  16. package/lib/module/components/banner/Banner.js.map +1 -1
  17. package/lib/module/components/banner/__test__/__snapshots__/banner.test.tsx.snap +36 -190
  18. package/lib/module/components/featureInfo/FeatureInfo.js +29 -28
  19. package/lib/module/components/featureInfo/FeatureInfo.js.map +1 -1
  20. package/lib/module/components/spacer/Spacer.js +1 -1
  21. package/lib/module/components/spacer/Spacer.js.map +1 -1
  22. package/lib/module/components/stack/Stack.js +17 -14
  23. package/lib/module/components/stack/Stack.js.map +1 -1
  24. package/lib/module/core/IOColors.js.map +1 -1
  25. package/lib/typescript/components/alert/Alert.d.ts.map +1 -1
  26. package/lib/typescript/components/banner/Banner.d.ts.map +1 -1
  27. package/lib/typescript/components/featureInfo/FeatureInfo.d.ts.map +1 -1
  28. package/lib/typescript/components/spacer/Spacer.d.ts +0 -1
  29. package/lib/typescript/components/spacer/Spacer.d.ts.map +1 -1
  30. package/lib/typescript/components/stack/Stack.d.ts +9 -6
  31. package/lib/typescript/components/stack/Stack.d.ts.map +1 -1
  32. package/lib/typescript/core/IOColors.d.ts.map +1 -1
  33. package/package.json +1 -1
  34. package/src/components/alert/Alert.tsx +46 -15
  35. package/src/components/banner/Banner.tsx +55 -27
  36. package/src/components/banner/__test__/__snapshots__/banner.test.tsx.snap +36 -190
  37. package/src/components/featureInfo/FeatureInfo.tsx +26 -28
  38. package/src/components/spacer/Spacer.tsx +2 -4
  39. package/src/components/stack/Stack.tsx +24 -16
  40. package/src/core/IOColors.ts +1 -0
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useState } from "react";
2
2
  import {
3
+ ColorValue,
3
4
  GestureResponderEvent,
4
5
  NativeSyntheticEvent,
5
6
  PixelRatio,
@@ -17,13 +18,9 @@ import Animated, {
17
18
  useSharedValue,
18
19
  withSpring
19
20
  } from "react-native-reanimated";
20
- import { IOVisualCostants } from "../../core";
21
+ import { IOVisualCostants, useIOThemeContext } from "../../core";
21
22
  import { IOScaleValues, IOSpringValues } from "../../core/IOAnimations";
22
- import {
23
- IOColors,
24
- IOColorsStatusBackground,
25
- IOColorsStatusForeground
26
- } from "../../core/IOColors";
23
+ import { IOColors, hexToRgba } from "../../core/IOColors";
27
24
  import { IOAlertRadius } from "../../core/IOShapes";
28
25
  import { IOAlertSpacing } from "../../core/IOSpacing";
29
26
  import { WithTestID } from "../../utils/types";
@@ -75,38 +72,66 @@ type AlertType = AlertProps & AlertActionProps;
75
72
 
76
73
  type VariantStates = {
77
74
  icon: IOIcons;
78
- background: IOColorsStatusBackground;
79
- foreground: IOColorsStatusForeground;
75
+ background: ColorValue;
76
+ foreground: IOColors;
80
77
  };
81
78
 
82
79
  // COMPONENT CONFIGURATION
83
80
 
84
- const mapVariantStates: Record<
81
+ const mapVariantStatesLightMode: Record<
85
82
  NonNullable<AlertType["variant"]>,
86
83
  VariantStates
87
84
  > = {
88
85
  error: {
89
86
  icon: "errorFilled",
90
- background: "error-100",
87
+ background: IOColors["error-100"],
91
88
  foreground: "error-850"
92
89
  },
93
90
  warning: {
94
91
  icon: "warningFilled",
95
- background: "warning-100",
92
+ background: IOColors["warning-100"],
96
93
  foreground: "warning-850"
97
94
  },
98
95
  info: {
99
96
  icon: "infoFilled",
100
- background: "info-100",
97
+ background: IOColors["info-100"],
101
98
  foreground: "info-850"
102
99
  },
103
100
  success: {
104
101
  icon: "success",
105
- background: "success-100",
102
+ background: IOColors["success-100"],
106
103
  foreground: "success-850"
107
104
  }
108
105
  };
109
106
 
107
+ const bgOpacityDarkMode = 0.2;
108
+
109
+ const mapVariantStatesDarkMode: Record<
110
+ NonNullable<AlertType["variant"]>,
111
+ VariantStates
112
+ > = {
113
+ error: {
114
+ icon: "errorFilled",
115
+ background: hexToRgba(IOColors["error-400"], bgOpacityDarkMode),
116
+ foreground: "error-100"
117
+ },
118
+ warning: {
119
+ icon: "warningFilled",
120
+ background: hexToRgba(IOColors["warning-400"], bgOpacityDarkMode),
121
+ foreground: "warning-100"
122
+ },
123
+ info: {
124
+ icon: "infoFilled",
125
+ background: hexToRgba(IOColors["info-400"], bgOpacityDarkMode),
126
+ foreground: "info-100"
127
+ },
128
+ success: {
129
+ icon: "success",
130
+ background: hexToRgba(IOColors["success-400"], bgOpacityDarkMode),
131
+ foreground: "success-100"
132
+ }
133
+ };
134
+
110
135
  export const Alert = React.forwardRef<View, AlertType>(
111
136
  (
112
137
  {
@@ -121,6 +146,7 @@ export const Alert = React.forwardRef<View, AlertType>(
121
146
  }: AlertType,
122
147
  viewRef
123
148
  ): JSX.Element => {
149
+ const { themeType } = useIOThemeContext();
124
150
  const isPressed: SharedValue<number> = useSharedValue(0);
125
151
 
126
152
  const [isMultiline, setIsMultiline] = useState(false);
@@ -164,6 +190,11 @@ export const Alert = React.forwardRef<View, AlertType>(
164
190
  isPressed.value = 0;
165
191
  }, [isPressed]);
166
192
 
193
+ const mapVariantStates =
194
+ themeType === "light"
195
+ ? mapVariantStatesLightMode
196
+ : mapVariantStatesDarkMode;
197
+
167
198
  const renderMainBlock = () => (
168
199
  <>
169
200
  <View
@@ -226,7 +257,7 @@ export const Alert = React.forwardRef<View, AlertType>(
226
257
  style={[
227
258
  styles.container,
228
259
  fullWidth ? styles.spacingFullWidth : styles.spacingDefault,
229
- { backgroundColor: IOColors[mapVariantStates[variant].background] }
260
+ { backgroundColor: mapVariantStates[variant].background }
230
261
  ]}
231
262
  testID={testID}
232
263
  accessible={false}
@@ -254,7 +285,7 @@ export const Alert = React.forwardRef<View, AlertType>(
254
285
  style={[
255
286
  styles.container,
256
287
  fullWidth ? styles.spacingFullWidth : styles.spacingDefault,
257
- { backgroundColor: IOColors[mapVariantStates[variant].background] },
288
+ { backgroundColor: mapVariantStates[variant].background },
258
289
  // Disable pressed animation when component is full width
259
290
  !fullWidth && pressedAnimationStyle
260
291
  ]}
@@ -8,8 +8,9 @@ import {
8
8
  ViewStyle
9
9
  } from "react-native";
10
10
  import Animated, {
11
- Extrapolate,
11
+ Extrapolation,
12
12
  interpolate,
13
+ SharedValue,
13
14
  useAnimatedStyle,
14
15
  useDerivedValue,
15
16
  useSharedValue,
@@ -22,26 +23,26 @@ import {
22
23
  IOBannerSmallVSpacing,
23
24
  IOScaleValues,
24
25
  IOSpringValues,
25
- IOStyles
26
+ IOStyles,
27
+ useIOExperimentalDesign,
28
+ useIOTheme,
29
+ useIOThemeContext
26
30
  } from "../../core";
27
- import { IOColors } from "../../core/IOColors";
31
+ import { hexToRgba, IOColors } from "../../core/IOColors";
28
32
  import { WithTestID } from "../../utils/types";
29
- import { ButtonLink, IconButton } from "../buttons";
33
+ import { IconButton } from "../buttons";
30
34
  import {
31
- IOPictogramSizeScale,
32
35
  IOPictogramsBleed,
36
+ IOPictogramSizeScale,
33
37
  PictogramBleed
34
38
  } from "../pictograms";
35
39
  import { VSpacer } from "../spacer";
36
- import { H6, BodySmall } from "../typography";
40
+ import { buttonTextFontSize, H6, IOText, BodySmall } from "../typography";
37
41
 
38
42
  /* Styles */
39
- const colorTitle: IOColors = "blueIO-850";
40
- const colorContent: IOColors = "grey-700";
41
- const colorCloseButton: IconButton["color"] = "neutral";
42
43
  const sizePictogramBig: IOPictogramSizeScale = 80;
43
44
  const sizePictogramSmall: IOPictogramSizeScale = 64;
44
- const closeButtonDistanceFromEdge: number = 4;
45
+ const closeButtonDistanceFromEdge: number = 6;
45
46
  const closeButtonOpacity = 0.6;
46
47
  const sizeBigPadding = IOBannerBigSpacing;
47
48
  const sizeSmallHPadding = IOBannerSmallHSpacing;
@@ -66,15 +67,6 @@ const styles = StyleSheet.create({
66
67
  }
67
68
  });
68
69
 
69
- const dynamicContainerStyles = (
70
- size: BaseBannerProps["size"],
71
- color: BaseBannerProps["color"]
72
- ): ViewStyle => ({
73
- backgroundColor: IOColors[mapBackgroundColor[color]],
74
- paddingVertical: size === "big" ? sizeBigPadding : sizeSmallVPadding,
75
- paddingHorizontal: size === "big" ? sizeBigPadding : sizeSmallHPadding
76
- });
77
-
78
70
  /* Component Types */
79
71
 
80
72
  type BaseBannerProps = WithTestID<{
@@ -136,7 +128,7 @@ export const bannerBackgroundColours: Array<BaseBannerProps["color"]> = [
136
128
  "turquoise"
137
129
  ];
138
130
 
139
- const mapBackgroundColor: Record<
131
+ const mapBackgroundColorLightMode: Record<
140
132
  NonNullable<BaseBannerProps["color"]>,
141
133
  IOColors
142
134
  > = {
@@ -144,6 +136,14 @@ const mapBackgroundColor: Record<
144
136
  turquoise: "turquoise-50"
145
137
  };
146
138
 
139
+ const mapBackgroundColorDarkMode: Record<
140
+ NonNullable<BaseBannerProps["color"]>,
141
+ IOColors
142
+ > = {
143
+ neutral: "grey-50",
144
+ turquoise: "turquoise-300"
145
+ };
146
+
147
147
  export const Banner = ({
148
148
  viewRef,
149
149
  size,
@@ -159,7 +159,27 @@ export const Banner = ({
159
159
  accessibilityLabel,
160
160
  testID
161
161
  }: Banner) => {
162
- const isPressed: Animated.SharedValue<number> = useSharedValue(0);
162
+ const isPressed: SharedValue<number> = useSharedValue(0);
163
+
164
+ const { isExperimental } = useIOExperimentalDesign();
165
+ const { themeType } = useIOThemeContext();
166
+ const theme = useIOTheme();
167
+
168
+ // Dynamic colors
169
+ const colorTitle: IOColors = themeType === "dark" ? "grey-50" : "blueIO-850";
170
+ const colorCloseButton: IconButton["color"] =
171
+ themeType === "dark" ? "contrast" : "neutral";
172
+ const colorMainButton =
173
+ themeType === "dark" ? "blueIO-200" : theme["interactiveElem-default"];
174
+
175
+ const dynamicContainerStyles: ViewStyle = {
176
+ backgroundColor:
177
+ themeType === "dark"
178
+ ? hexToRgba(IOColors[mapBackgroundColorDarkMode[color]], 0.1)
179
+ : IOColors[mapBackgroundColorLightMode[color]],
180
+ paddingVertical: size === "big" ? sizeBigPadding : sizeSmallVPadding,
181
+ paddingHorizontal: size === "big" ? sizeBigPadding : sizeSmallHPadding
182
+ };
163
183
 
164
184
  // Scaling transformation applied when the button is pressed
165
185
  const animationScaleValue = IOScaleValues?.magnifiedButton?.pressedState;
@@ -178,7 +198,7 @@ export const Banner = ({
178
198
  progressPressed.value,
179
199
  [0, 1],
180
200
  [1, animationScaleValue],
181
- Extrapolate.CLAMP
201
+ Extrapolation.CLAMP
182
202
  );
183
203
 
184
204
  return {
@@ -221,7 +241,7 @@ export const Banner = ({
221
241
  )}
222
242
  {content && (
223
243
  <>
224
- <BodySmall color={colorContent} weight={"Regular"}>
244
+ <BodySmall color={theme["textBody-tertiary"]} weight={"Regular"}>
225
245
  {content}
226
246
  </BodySmall>
227
247
  {action && <VSpacer size={8} />}
@@ -236,13 +256,21 @@ export const Banner = ({
236
256
  importantForAccessibility="no-hide-descendants"
237
257
  >
238
258
  <VSpacer size={4} />
239
- <ButtonLink color="primary" onPress={onPress} label={action} />
259
+ <IOText
260
+ font={isExperimental ? "Titillio" : "TitilliumSansPro"}
261
+ weight={isExperimental ? "Regular" : "Bold"}
262
+ color={colorMainButton}
263
+ size={buttonTextFontSize}
264
+ numberOfLines={1}
265
+ ellipsizeMode="tail"
266
+ >
267
+ {action}
268
+ </IOText>
240
269
  </View>
241
270
  )}
242
271
  </View>
243
272
  <View style={[styles.bleedPictogram, IOStyles.selfCenter]}>
244
273
  <PictogramBleed
245
- pictogramStyle="dark-content"
246
274
  name={pictogramName}
247
275
  size={size === "big" ? sizePictogramBig : sizePictogramSmall}
248
276
  />
@@ -272,7 +300,7 @@ export const Banner = ({
272
300
  <Animated.View
273
301
  style={[
274
302
  styles.container,
275
- dynamicContainerStyles(size, color),
303
+ dynamicContainerStyles,
276
304
  pressedAnimationStyle
277
305
  ]}
278
306
  >
@@ -285,7 +313,7 @@ export const Banner = ({
285
313
  <View
286
314
  ref={viewRef}
287
315
  testID={testID}
288
- style={[styles.container, dynamicContainerStyles(size, color)]}
316
+ style={[styles.container, dynamicContainerStyles]}
289
317
  // A11y related props
290
318
  accessible={false}
291
319
  accessibilityHint={accessibilityHint}
@@ -111,104 +111,27 @@ exports[`Test Banner Components - Experimental Enabled Banner Snapshot 1`] = `
111
111
  }
112
112
  }
113
113
  />
114
- <View
115
- accessibilityLabel="Action text"
116
- accessibilityRole="button"
117
- accessibilityState={
118
- {
119
- "busy": undefined,
120
- "checked": undefined,
121
- "disabled": false,
122
- "expanded": undefined,
123
- "selected": undefined,
124
- }
125
- }
126
- accessibilityValue={
127
- {
128
- "max": undefined,
129
- "min": undefined,
130
- "now": undefined,
131
- "text": undefined,
132
- }
133
- }
134
- accessible={true}
135
- collapsable={false}
136
- focusable={true}
137
- hitSlop={
138
- {
139
- "bottom": 14,
140
- "left": 24,
141
- "right": 24,
142
- "top": 14,
143
- }
144
- }
145
- onBlur={[Function]}
146
- onClick={[Function]}
147
- onFocus={[Function]}
148
- onResponderGrant={[Function]}
149
- onResponderMove={[Function]}
150
- onResponderRelease={[Function]}
151
- onResponderTerminate={[Function]}
152
- onResponderTerminationRequest={[Function]}
153
- onStartShouldSetResponder={[Function]}
154
- onTouchEnd={[Function]}
114
+ <Text
115
+ allowFontScaling={true}
116
+ ellipsizeMode="tail"
117
+ maxFontSizeMultiplier={1.25}
118
+ numberOfLines={1}
155
119
  style={
156
- {
157
- "alignSelf": "flex-start",
158
- }
120
+ [
121
+ {},
122
+ {
123
+ "color": "#0B3EE3",
124
+ "fontFamily": "Titillio",
125
+ "fontSize": 16,
126
+ "fontStyle": "normal",
127
+ "fontWeight": "400",
128
+ "lineHeight": undefined,
129
+ },
130
+ ]
159
131
  }
160
132
  >
161
- <View
162
- style={
163
- [
164
- {
165
- "alignItems": "center",
166
- "elevation": 0,
167
- "flexDirection": "row",
168
- "justifyContent": "center",
169
- "textAlignVertical": "center",
170
- },
171
- false,
172
- {},
173
- {
174
- "transform": [
175
- {
176
- "scale": undefined,
177
- },
178
- ],
179
- },
180
- ]
181
- }
182
- >
183
- <Text
184
- accessibilityElementsHidden={true}
185
- accessible={false}
186
- allowFontScaling={true}
187
- ellipsizeMode="tail"
188
- importantForAccessibility="no-hide-descendants"
189
- maxFontSizeMultiplier={1.25}
190
- numberOfLines={1}
191
- style={
192
- [
193
- {},
194
- {
195
- "color": "#0E0F13",
196
- "fontFamily": "Titillio",
197
- "fontSize": 16,
198
- "fontStyle": "normal",
199
- "fontWeight": "600",
200
- "lineHeight": undefined,
201
- },
202
- {
203
- "color": undefined,
204
- },
205
- ]
206
- }
207
- >
208
- Action text
209
- </Text>
210
- </View>
211
- </View>
133
+ Action text
134
+ </Text>
212
135
  </View>
213
136
  </View>
214
137
  <View
@@ -461,104 +384,27 @@ exports[`Test Banner Components Banner Snapshot 1`] = `
461
384
  }
462
385
  }
463
386
  />
464
- <View
465
- accessibilityLabel="Action text"
466
- accessibilityRole="button"
467
- accessibilityState={
468
- {
469
- "busy": undefined,
470
- "checked": undefined,
471
- "disabled": false,
472
- "expanded": undefined,
473
- "selected": undefined,
474
- }
475
- }
476
- accessibilityValue={
477
- {
478
- "max": undefined,
479
- "min": undefined,
480
- "now": undefined,
481
- "text": undefined,
482
- }
483
- }
484
- accessible={true}
485
- collapsable={false}
486
- focusable={true}
487
- hitSlop={
488
- {
489
- "bottom": 14,
490
- "left": 24,
491
- "right": 24,
492
- "top": 14,
493
- }
494
- }
495
- onBlur={[Function]}
496
- onClick={[Function]}
497
- onFocus={[Function]}
498
- onResponderGrant={[Function]}
499
- onResponderMove={[Function]}
500
- onResponderRelease={[Function]}
501
- onResponderTerminate={[Function]}
502
- onResponderTerminationRequest={[Function]}
503
- onStartShouldSetResponder={[Function]}
504
- onTouchEnd={[Function]}
387
+ <Text
388
+ allowFontScaling={false}
389
+ ellipsizeMode="tail"
390
+ maxFontSizeMultiplier={1.25}
391
+ numberOfLines={1}
505
392
  style={
506
- {
507
- "alignSelf": "flex-start",
508
- }
393
+ [
394
+ {},
395
+ {
396
+ "color": "#0B3EE3",
397
+ "fontFamily": "Titillium Sans Pro",
398
+ "fontSize": 16,
399
+ "fontStyle": "normal",
400
+ "fontWeight": "700",
401
+ "lineHeight": undefined,
402
+ },
403
+ ]
509
404
  }
510
405
  >
511
- <View
512
- style={
513
- [
514
- {
515
- "alignItems": "center",
516
- "elevation": 0,
517
- "flexDirection": "row",
518
- "justifyContent": "center",
519
- "textAlignVertical": "center",
520
- },
521
- false,
522
- {},
523
- {
524
- "transform": [
525
- {
526
- "scale": undefined,
527
- },
528
- ],
529
- },
530
- ]
531
- }
532
- >
533
- <Text
534
- accessibilityElementsHidden={true}
535
- accessible={false}
536
- allowFontScaling={false}
537
- ellipsizeMode="tail"
538
- importantForAccessibility="no-hide-descendants"
539
- maxFontSizeMultiplier={1.25}
540
- numberOfLines={1}
541
- style={
542
- [
543
- {},
544
- {
545
- "color": "#0E0F13",
546
- "fontFamily": "Titillium Sans Pro",
547
- "fontSize": 16,
548
- "fontStyle": "normal",
549
- "fontWeight": "600",
550
- "lineHeight": undefined,
551
- },
552
- {
553
- "color": undefined,
554
- },
555
- ]
556
- }
557
- >
558
- Action text
559
- </Text>
560
- </View>
561
- </View>
406
+ Action text
407
+ </Text>
562
408
  </View>
563
409
  </View>
564
410
  <View
@@ -9,9 +9,9 @@ import {
9
9
  IOPictograms,
10
10
  Icon,
11
11
  Pictogram,
12
- VSpacer
12
+ VStack
13
13
  } from "../../components";
14
- import { IOStyles } from "../../core";
14
+ import { IOStyles, useIOTheme } from "../../core";
15
15
 
16
16
  type PartialFeatureInfo = {
17
17
  // Necessary to render main body with different formatting
@@ -42,11 +42,7 @@ const DEFAULT_PICTOGRAM_SIZE: IOPictogramSizeScale = 48;
42
42
 
43
43
  const renderNode = (body: FeatureInfoProps["body"]) => {
44
44
  if (typeof body === "string") {
45
- return (
46
- <BodySmall color="grey-700" testID="infoScreenBody">
47
- {body}
48
- </BodySmall>
49
- );
45
+ return <BodySmall testID="infoScreenBody">{body}</BodySmall>;
50
46
  }
51
47
 
52
48
  return body;
@@ -57,23 +53,25 @@ export const FeatureInfo = ({
57
53
  pictogramName,
58
54
  body,
59
55
  action
60
- }: FeatureInfoProps) => (
61
- <View style={[IOStyles.flex, IOStyles.row, IOStyles.alignCenter]}>
62
- {iconName && (
63
- <Icon name={iconName} size={DEFAULT_ICON_SIZE} color="grey-300" />
64
- )}
65
- {pictogramName && (
66
- <Pictogram name={pictogramName} size={DEFAULT_PICTOGRAM_SIZE} />
67
- )}
68
- <HSpacer size={24} />
69
- <View style={{ flexShrink: 1 }}>
70
- {renderNode(body)}
71
- {action && (
72
- <>
73
- {/* Add "marginTop" equivalent if body text is present.
74
- This verbose code could be deleted once we got "gap"
75
- property support */}
76
- {body && <VSpacer size={4} />}
56
+ }: FeatureInfoProps) => {
57
+ const theme = useIOTheme();
58
+
59
+ return (
60
+ <View style={[IOStyles.flex, IOStyles.row, IOStyles.alignCenter]}>
61
+ {iconName && (
62
+ <Icon
63
+ name={iconName}
64
+ size={DEFAULT_ICON_SIZE}
65
+ color={theme["icon-decorative"]}
66
+ />
67
+ )}
68
+ {pictogramName && (
69
+ <Pictogram name={pictogramName} size={DEFAULT_PICTOGRAM_SIZE} />
70
+ )}
71
+ <HSpacer size={24} />
72
+ <VStack space={4} style={{ flexShrink: 1 }}>
73
+ {renderNode(body)}
74
+ {action && (
77
75
  <BodySmall
78
76
  weight="Semibold"
79
77
  asLink
@@ -84,8 +82,8 @@ export const FeatureInfo = ({
84
82
  >
85
83
  {action.label}
86
84
  </BodySmall>
87
- </>
88
- )}
85
+ )}
86
+ </VStack>
89
87
  </View>
90
- </View>
91
- );
88
+ );
89
+ };
@@ -2,10 +2,8 @@ import React from "react";
2
2
  import { View } from "react-native";
3
3
  import { hexToRgba, IOColors, IOSpacer } from "../../core";
4
4
 
5
- export type SpacerOrientation = "vertical" | "horizontal";
6
-
7
5
  type BaseSpacerProps = {
8
- orientation: SpacerOrientation;
6
+ orientation: "vertical" | "horizontal";
9
7
  size: IOSpacer;
10
8
  };
11
9
 
@@ -21,7 +19,7 @@ const debugBg = hexToRgba(IOColors.red, 0.2);
21
19
 
22
20
  /**
23
21
  Native `Spacer` component
24
- @param {SpacerOrientation} orientation
22
+ @param {string} orientation
25
23
  @param {IOSpacer} size
26
24
  */
27
25
  const Spacer = ({ orientation, size }: BaseSpacerProps) => {