@pagopa/io-app-design-system 5.0.7 → 5.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 (54) hide show
  1. package/lib/commonjs/components/codeInput/CodeInput.js +8 -5
  2. package/lib/commonjs/components/codeInput/CodeInput.js.map +1 -1
  3. package/lib/commonjs/components/common/ScaleInOutAnimation.js +7 -5
  4. package/lib/commonjs/components/common/ScaleInOutAnimation.js.map +1 -1
  5. package/lib/commonjs/components/layout/ForceScrollDownView.js +27 -23
  6. package/lib/commonjs/components/layout/ForceScrollDownView.js.map +1 -1
  7. package/lib/commonjs/components/layout/__test__/ForceScrollDownView.test.js +12 -4
  8. package/lib/commonjs/components/layout/__test__/ForceScrollDownView.test.js.map +1 -1
  9. package/lib/commonjs/components/layout/__test__/__snapshots__/ForceScrollDownView.test.tsx.snap +1 -6
  10. package/lib/commonjs/components/layout/hooks/useFooterActionsInlineMeasurements.js +2 -2
  11. package/lib/commonjs/components/layout/hooks/useFooterActionsInlineMeasurements.js.map +1 -1
  12. package/lib/commonjs/components/layout/hooks/useFooterActionsMeasurements.js +2 -2
  13. package/lib/commonjs/components/layout/hooks/useFooterActionsMeasurements.js.map +1 -1
  14. package/lib/commonjs/components/numberpad/NumberButton.js +17 -14
  15. package/lib/commonjs/components/numberpad/NumberButton.js.map +1 -1
  16. package/lib/commonjs/components/numberpad/NumberPad.js +3 -3
  17. package/lib/commonjs/components/numberpad/NumberPad.js.map +1 -1
  18. package/lib/module/components/codeInput/CodeInput.js +8 -5
  19. package/lib/module/components/codeInput/CodeInput.js.map +1 -1
  20. package/lib/module/components/common/ScaleInOutAnimation.js +8 -6
  21. package/lib/module/components/common/ScaleInOutAnimation.js.map +1 -1
  22. package/lib/module/components/layout/ForceScrollDownView.js +27 -23
  23. package/lib/module/components/layout/ForceScrollDownView.js.map +1 -1
  24. package/lib/module/components/layout/__test__/ForceScrollDownView.test.js +12 -4
  25. package/lib/module/components/layout/__test__/ForceScrollDownView.test.js.map +1 -1
  26. package/lib/module/components/layout/__test__/__snapshots__/ForceScrollDownView.test.tsx.snap +1 -6
  27. package/lib/module/components/layout/hooks/useFooterActionsInlineMeasurements.js +3 -3
  28. package/lib/module/components/layout/hooks/useFooterActionsInlineMeasurements.js.map +1 -1
  29. package/lib/module/components/layout/hooks/useFooterActionsMeasurements.js +3 -3
  30. package/lib/module/components/layout/hooks/useFooterActionsMeasurements.js.map +1 -1
  31. package/lib/module/components/numberpad/NumberButton.js +18 -16
  32. package/lib/module/components/numberpad/NumberButton.js.map +1 -1
  33. package/lib/module/components/numberpad/NumberPad.js +3 -3
  34. package/lib/module/components/numberpad/NumberPad.js.map +1 -1
  35. package/lib/typescript/components/codeInput/CodeInput.d.ts +1 -1
  36. package/lib/typescript/components/codeInput/CodeInput.d.ts.map +1 -1
  37. package/lib/typescript/components/common/ScaleInOutAnimation.d.ts +1 -3
  38. package/lib/typescript/components/common/ScaleInOutAnimation.d.ts.map +1 -1
  39. package/lib/typescript/components/layout/ForceScrollDownView.d.ts +20 -8
  40. package/lib/typescript/components/layout/ForceScrollDownView.d.ts.map +1 -1
  41. package/lib/typescript/components/layout/hooks/useFooterActionsInlineMeasurements.d.ts.map +1 -1
  42. package/lib/typescript/components/layout/hooks/useFooterActionsMeasurements.d.ts.map +1 -1
  43. package/lib/typescript/components/numberpad/NumberButton.d.ts +2 -2
  44. package/lib/typescript/components/numberpad/NumberButton.d.ts.map +1 -1
  45. package/package.json +1 -1
  46. package/src/components/codeInput/CodeInput.tsx +11 -7
  47. package/src/components/common/ScaleInOutAnimation.tsx +8 -10
  48. package/src/components/layout/ForceScrollDownView.tsx +67 -32
  49. package/src/components/layout/__test__/ForceScrollDownView.test.tsx +4 -4
  50. package/src/components/layout/__test__/__snapshots__/ForceScrollDownView.test.tsx.snap +1 -6
  51. package/src/components/layout/hooks/useFooterActionsInlineMeasurements.ts +7 -6
  52. package/src/components/layout/hooks/useFooterActionsMeasurements.ts +7 -6
  53. package/src/components/numberpad/NumberButton.tsx +30 -18
  54. package/src/components/numberpad/NumberPad.tsx +3 -3
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
- type NumberButtonVariantType = "light" | "dark";
2
+ type NumberButtonVariantType = "neutral" | "primary";
3
3
  type NumberButtonProps = {
4
4
  /**
5
- * Used to choose the component color variant between `dark` and `light`.
5
+ * Used to choose the component color variant between `neutral` and `primary`.
6
6
  */
7
7
  variant: NumberButtonVariantType;
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"NumberButton.d.ts","sourceRoot":"","sources":["../../../../src/components/numberpad/NumberButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAejD,KAAK,uBAAuB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhD,KAAK,iBAAiB,GAAG;IACvB;;OAEG;IACH,OAAO,EAAE,uBAAuB,CAAC;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAqBF;;;;GAIG;AACH,eAAO,MAAM,YAAY,2DACQ,iBAAiB,uBAoDjD,CAAC"}
1
+ {"version":3,"file":"NumberButton.d.ts","sourceRoot":"","sources":["../../../../src/components/numberpad/NumberButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAkB1D,KAAK,uBAAuB,GAAG,SAAS,GAAG,SAAS,CAAC;AAErD,KAAK,iBAAiB,GAAG;IACvB;;OAEG;IACH,OAAO,EAAE,uBAAuB,CAAC;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAQF;;;;GAIG;AACH,eAAO,MAAM,YAAY,2DACQ,iBAAiB,uBA0EjD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/io-app-design-system",
3
- "version": "5.0.7",
3
+ "version": "5.1.0",
4
4
  "description": "The library defining the core components of the design system of @pagopa/io-app",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -11,7 +11,7 @@ type CodeInputProps = {
11
11
  onValueChange: (value: string) => void;
12
12
  length: number;
13
13
  onValidate: (value: string) => boolean;
14
- variant?: "light" | "dark";
14
+ variant?: "primary" | "neutral";
15
15
  };
16
16
 
17
17
  const DOT_SIZE = 16;
@@ -47,35 +47,39 @@ export const CodeInput = ({
47
47
  length,
48
48
  value,
49
49
  onValueChange,
50
- variant = "light",
50
+ variant = "primary",
51
51
  onValidate
52
52
  }: CodeInputProps) => {
53
53
  const [status, setStatus] = useState<"default" | "error">("default");
54
- const { themeType } = useIOThemeContext();
54
+ const { themeType, theme } = useIOThemeContext();
55
55
 
56
56
  const { translate, animatedStyle, shakeAnimation } = useErrorShakeAnimation();
57
57
 
58
58
  /* Empty Dot
59
59
  - Right color depending on both theme and variant */
60
60
  const emptyDotColorLightBg = IOColors["grey-650"];
61
- const emptyDotColorDarkBg = hexToRgba(IOColors.white, 0.75);
61
+ const emptyDotColorDarkBg = IOColors["grey-300"];
62
+ const emptyDotColorAccentBg = hexToRgba(IOColors.white, 0.75);
63
+
62
64
  const emptyDotColorThemeBased =
63
65
  themeType === "light" ? emptyDotColorLightBg : emptyDotColorDarkBg;
64
66
 
65
67
  const emptyDotColor =
66
- variant === "light" ? emptyDotColorDarkBg : emptyDotColorThemeBased;
68
+ variant === "primary" ? emptyDotColorAccentBg : emptyDotColorThemeBased;
67
69
 
68
70
  /* Filled Dot
69
71
  - Right color depending on theme, variant and status */
70
72
  const filledDotColorLightBg = IOColors.black;
71
73
  const filledDotColorDarkBg = IOColors.white;
74
+ const filledDotColorError =
75
+ variant === "primary" ? IOColors["error-400"] : IOColors[theme.errorText];
72
76
  const filledDotColorThemeBased =
73
77
  themeType === "light" ? filledDotColorLightBg : filledDotColorDarkBg;
74
78
 
75
79
  const filledDotColor =
76
80
  status === "error"
77
- ? IOColors["error-600"]
78
- : variant === "light"
81
+ ? filledDotColorError
82
+ : variant === "primary"
79
83
  ? filledDotColorDarkBg
80
84
  : filledDotColorThemeBased;
81
85
 
@@ -4,16 +4,12 @@ import { ViewStyle } from "react-native";
4
4
  import Animated, {
5
5
  LayoutAnimation,
6
6
  WithSpringConfig,
7
- withDelay,
8
- withSpring,
9
- withTiming
7
+ withSpring
10
8
  } from "react-native-reanimated";
11
9
 
12
10
  type Props = {
13
11
  visible?: boolean;
14
12
  springConfig?: WithSpringConfig;
15
- delayOut?: number;
16
- delayIn?: number;
17
13
  children: React.ReactNode;
18
14
  style?: ViewStyle;
19
15
  };
@@ -21,8 +17,6 @@ type Props = {
21
17
  const ScaleInOutAnimation = ({
22
18
  visible = true,
23
19
  springConfig = { damping: 500, mass: 3, stiffness: 1000 },
24
- delayOut = 0,
25
- delayIn = 0,
26
20
  children,
27
21
  style
28
22
  }: Props) => {
@@ -30,10 +24,12 @@ const ScaleInOutAnimation = ({
30
24
  "worklet";
31
25
  return {
32
26
  initialValues: {
33
- transform: [{ scale: 0 }]
27
+ opacity: 0,
28
+ transform: [{ scale: 0.5 }]
34
29
  },
35
30
  animations: {
36
- transform: [{ scale: withDelay(delayIn, withSpring(1, springConfig)) }]
31
+ opacity: withSpring(1, springConfig),
32
+ transform: [{ scale: withSpring(1, springConfig) }]
37
33
  }
38
34
  };
39
35
  };
@@ -42,10 +38,12 @@ const ScaleInOutAnimation = ({
42
38
  "worklet";
43
39
  return {
44
40
  initialValues: {
41
+ opacity: 1,
45
42
  transform: [{ scale: 1 }]
46
43
  },
47
44
  animations: {
48
- transform: [{ scale: withDelay(delayOut, withTiming(0)) }]
45
+ opacity: withSpring(0, springConfig),
46
+ transform: [{ scale: withSpring(0.5, springConfig) }]
49
47
  }
50
48
  };
51
49
  };
@@ -1,4 +1,6 @@
1
1
  import React, {
2
+ ComponentProps,
3
+ ReactNode,
2
4
  useCallback,
3
5
  useEffect,
4
6
  useMemo,
@@ -13,29 +15,51 @@ import {
13
15
  ScrollViewProps,
14
16
  StyleSheet
15
17
  } from "react-native";
16
- import { ScaleInOutAnimation } from "../common/ScaleInOutAnimation";
17
18
  import { IOSpringValues, IOVisualCostants } from "../../core";
18
19
  import { IconButtonSolid } from "../buttons";
20
+ import { ScaleInOutAnimation } from "../common/ScaleInOutAnimation";
21
+ import { FooterActions } from "./FooterActions";
22
+ import { useFooterActionsInlineMeasurements } from "./hooks";
19
23
 
20
- type ForceScrollDownViewProps = {
24
+ type ForceScrollDownViewActions = {
21
25
  /**
22
- * The content to display inside the scroll view.
26
+ * The distance from the bottom is computed automatically based on the actions.
23
27
  */
24
- children: React.ReactNode;
28
+ threshold?: never;
29
+ footerActions: Omit<
30
+ ComponentProps<typeof FooterActions>,
31
+ "fixed" | "onMeasure"
32
+ >;
33
+ };
34
+
35
+ type ForceScrollDownViewCustomSlot = {
25
36
  /**
26
37
  * The distance from the bottom of the scrollable content at which the "scroll to bottom" button
27
- * should become hidden. Defaults to 100.
38
+ * should become hidden.
28
39
  */
29
- threshold?: number;
40
+ threshold: number;
41
+ footerActions?: never;
42
+ };
43
+
44
+ type ForceScrollDownViewSlot =
45
+ | ForceScrollDownViewActions
46
+ | ForceScrollDownViewCustomSlot;
47
+
48
+ export type ForceScrollDownView = {
49
+ /**
50
+ * The content to display inside the scroll view.
51
+ */
52
+ children: ReactNode;
30
53
  /**
31
54
  * A callback that will be called whenever the scroll view crosses the threshold. The callback
32
55
  * is passed a boolean indicating whether the threshold has been crossed (`true`) or not (`false`).
33
56
  */
34
57
  onThresholdCrossed?: (crossed: boolean) => void;
35
- } & Pick<
36
- ScrollViewProps,
37
- "style" | "contentContainerStyle" | "scrollEnabled" | "testID"
38
- >;
58
+ } & ForceScrollDownViewSlot &
59
+ Pick<
60
+ ScrollViewProps,
61
+ "style" | "contentContainerStyle" | "scrollEnabled" | "testID"
62
+ >;
39
63
 
40
64
  /**
41
65
  * A React Native component that displays a scroll view with a button that scrolls to the bottom of the content
@@ -44,26 +68,36 @@ type ForceScrollDownViewProps = {
44
68
  * `scrollEnabled` prop to `false`.
45
69
  */
46
70
  const ForceScrollDownView = ({
71
+ footerActions,
47
72
  children,
48
- threshold = 100,
73
+ threshold: customThreshold,
49
74
  style,
50
75
  contentContainerStyle,
51
76
  scrollEnabled = true,
52
77
  onThresholdCrossed
53
- }: ForceScrollDownViewProps) => {
78
+ }: ForceScrollDownView) => {
54
79
  const scrollViewRef = useRef<ScrollView>(null);
55
80
 
81
+ const {
82
+ footerActionsInlineMeasurements,
83
+ handleFooterActionsInlineMeasurements
84
+ } = useFooterActionsInlineMeasurements();
85
+
86
+ const threshold = footerActions
87
+ ? footerActionsInlineMeasurements.safeBottomAreaHeight
88
+ : customThreshold;
89
+
56
90
  /**
57
91
  * The height of the scroll view, used to determine whether or not the scrollable content fits inside
58
92
  * the scroll view and whether the "scroll to bottom" button should be displayed.
59
93
  */
60
- const [scrollViewHeight, setScrollViewHeight] = useState<number>();
94
+ const [scrollViewHeight, setScrollViewHeight] = useState<number>(0);
61
95
 
62
96
  /**
63
97
  * The height of the scrollable content, used to determine whether or not the "scroll to bottom" button
64
98
  * should be displayed.
65
99
  */
66
- const [contentHeight, setContentHeight] = useState<number>();
100
+ const [contentHeight, setContentHeight] = useState<number>(0);
67
101
 
68
102
  /**
69
103
  * Whether or not the scroll view has crossed the threshold from the bottom.
@@ -79,7 +113,7 @@ const ForceScrollDownView = ({
79
113
  /**
80
114
  * A callback that is called whenever the scroll view is scrolled. It checks whether or not the
81
115
  * scroll view has crossed the threshold from the bottom and updates the state accordingly.
82
- * The callback is designed to updatr button visibility only when crossing the threshold.
116
+ * The callback is designed to update button visibility only when crossing the threshold.
83
117
  */
84
118
  const handleScroll = useCallback(
85
119
  (event: NativeSyntheticEvent<NativeScrollEvent>) => {
@@ -88,19 +122,14 @@ const ForceScrollDownView = ({
88
122
 
89
123
  const thresholdCrossed =
90
124
  layoutMeasurement.height + contentOffset.y >=
91
- contentSize.height - threshold;
92
-
93
- setThresholdCrossed(previousState => {
94
- if (!previousState && thresholdCrossed) {
95
- setButtonVisible(false);
96
- }
97
- if (previousState && !thresholdCrossed) {
98
- setButtonVisible(true);
99
- }
100
- return thresholdCrossed;
101
- });
125
+ contentSize.height - (threshold ?? 0);
126
+
127
+ if (isThresholdCrossed !== thresholdCrossed) {
128
+ setThresholdCrossed(thresholdCrossed);
129
+ setButtonVisible(!thresholdCrossed);
130
+ }
102
131
  },
103
- [threshold]
132
+ [threshold, isThresholdCrossed]
104
133
  );
105
134
 
106
135
  /**
@@ -145,8 +174,8 @@ const ForceScrollDownView = ({
145
174
  */
146
175
  const needsScroll = useMemo(
147
176
  () =>
148
- scrollViewHeight != null &&
149
- contentHeight != null &&
177
+ scrollViewHeight > 0 &&
178
+ contentHeight > 0 &&
150
179
  scrollViewHeight < contentHeight,
151
180
  [scrollViewHeight, contentHeight]
152
181
  );
@@ -182,16 +211,22 @@ const ForceScrollDownView = ({
182
211
  <ScrollView
183
212
  testID={"ScrollView"}
184
213
  ref={scrollViewRef}
185
- scrollIndicatorInsets={{ right: 1 }}
186
214
  scrollEnabled={scrollEnabled}
187
- onScroll={handleScroll}
188
- scrollEventThrottle={400}
189
215
  style={style}
216
+ onScroll={handleScroll}
217
+ scrollEventThrottle={8}
190
218
  onLayout={handleLayout}
191
219
  onContentSizeChange={handleContentSizeChange}
192
220
  contentContainerStyle={contentContainerStyle}
193
221
  >
194
222
  {children}
223
+ {footerActions && (
224
+ <FooterActions
225
+ {...footerActions}
226
+ onMeasure={handleFooterActionsInlineMeasurements}
227
+ fixed={false}
228
+ />
229
+ )}
195
230
  </ScrollView>
196
231
  {scrollDownButton}
197
232
  </>
@@ -13,7 +13,7 @@ describe("ForceScrollDownView", () => {
13
13
  const tChildren = <Text>{tContent}</Text>;
14
14
 
15
15
  const component = render(
16
- <ForceScrollDownView>{tChildren}</ForceScrollDownView>
16
+ <ForceScrollDownView threshold={100}>{tChildren}</ForceScrollDownView>
17
17
  );
18
18
 
19
19
  expect(component).toMatchSnapshot();
@@ -23,7 +23,7 @@ describe("ForceScrollDownView", () => {
23
23
  const tChildren = <Text>{tContent}</Text>;
24
24
 
25
25
  const { getByText } = render(
26
- <ForceScrollDownView>{tChildren}</ForceScrollDownView>
26
+ <ForceScrollDownView threshold={100}>{tChildren}</ForceScrollDownView>
27
27
  );
28
28
 
29
29
  expect(getByText(tContent)).toBeDefined();
@@ -35,7 +35,7 @@ describe("ForceScrollDownView", () => {
35
35
  const tScreenHeight = 1000;
36
36
 
37
37
  const { getByTestId, queryByTestId } = render(
38
- <ForceScrollDownView>{tChildren}</ForceScrollDownView>
38
+ <ForceScrollDownView threshold={100}>{tChildren}</ForceScrollDownView>
39
39
  );
40
40
 
41
41
  const scrollView = getByTestId("ScrollView");
@@ -72,7 +72,7 @@ describe("ForceScrollDownView", () => {
72
72
  const tScreenHeight = 1000;
73
73
 
74
74
  const { getByTestId, queryByTestId } = render(
75
- <ForceScrollDownView>{tChildren}</ForceScrollDownView>
75
+ <ForceScrollDownView threshold={100}>{tChildren}</ForceScrollDownView>
76
76
  );
77
77
 
78
78
  const scrollView = getByTestId("ScrollView");
@@ -6,12 +6,7 @@ exports[`ForceScrollDownView should match snapshot 1`] = `
6
6
  onLayout={[Function]}
7
7
  onScroll={[Function]}
8
8
  scrollEnabled={true}
9
- scrollEventThrottle={400}
10
- scrollIndicatorInsets={
11
- {
12
- "right": 1,
13
- }
14
- }
9
+ scrollEventThrottle={8}
15
10
  testID="ScrollView"
16
11
  >
17
12
  <View>
@@ -1,4 +1,4 @@
1
- import { useState } from "react";
1
+ import { useCallback, useState } from "react";
2
2
  import { FooterActionsInlineMeasurements } from "../FooterActionsInline";
3
3
 
4
4
  type UseFooterActionsInlineMeasurementsProps = {
@@ -25,11 +25,12 @@ export const useFooterActionsInlineMeasurements =
25
25
  safeBottomAreaHeight: 0
26
26
  });
27
27
 
28
- const handleFooterActionsInlineMeasurements = (
29
- values: FooterActionsInlineMeasurements
30
- ) => {
31
- setFooterActionsInlineMeasurements(values);
32
- };
28
+ const handleFooterActionsInlineMeasurements = useCallback(
29
+ (values: FooterActionsInlineMeasurements) => {
30
+ setFooterActionsInlineMeasurements(values);
31
+ },
32
+ []
33
+ );
33
34
 
34
35
  return {
35
36
  footerActionsInlineMeasurements,
@@ -1,4 +1,4 @@
1
- import { useState } from "react";
1
+ import { useCallback, useState } from "react";
2
2
  import { FooterActionsMeasurements } from "../FooterActions";
3
3
 
4
4
  type UseFooterActionsMeasurementsProps = {
@@ -22,11 +22,12 @@ export const useFooterActionsMeasurements =
22
22
  safeBottomAreaHeight: 0
23
23
  });
24
24
 
25
- const handleFooterActionsMeasurements = (
26
- values: FooterActionsMeasurements
27
- ) => {
28
- setFooterActionsMeasurements(values);
29
- };
25
+ const handleFooterActionsMeasurements = useCallback(
26
+ (values: FooterActionsMeasurements) => {
27
+ setFooterActionsMeasurements(values);
28
+ },
29
+ []
30
+ );
30
31
 
31
32
  return {
32
33
  footerActionsMeasurements,
@@ -1,23 +1,26 @@
1
- import React, { memo, useCallback } from "react";
1
+ import React, { memo, useCallback, useMemo } from "react";
2
2
  import { Pressable } from "react-native";
3
+ import ReactNativeHapticFeedback from "react-native-haptic-feedback";
3
4
  import Animated, {
4
5
  interpolateColor,
5
6
  useAnimatedStyle,
6
7
  useReducedMotion
7
8
  } from "react-native-reanimated";
8
9
  import {
10
+ hexToRgba,
9
11
  IOColors,
10
12
  IONumberPadButtonStyles,
11
- useIONewTypeface
13
+ useIONewTypeface,
14
+ useIOTheme
12
15
  } from "../../core";
13
16
  import { useScaleAnimation } from "../../hooks";
14
17
  import { IOText } from "../typography";
15
18
 
16
- type NumberButtonVariantType = "light" | "dark";
19
+ type NumberButtonVariantType = "neutral" | "primary";
17
20
 
18
21
  type NumberButtonProps = {
19
22
  /**
20
- * Used to choose the component color variant between `dark` and `light`.
23
+ * Used to choose the component color variant between `neutral` and `primary`.
21
24
  */
22
25
  variant: NumberButtonVariantType;
23
26
  /**
@@ -38,19 +41,6 @@ type ColorMapVariant = {
38
41
  foreground: IOColors;
39
42
  };
40
43
 
41
- const colorMap: Record<NumberButtonVariantType, ColorMapVariant> = {
42
- light: {
43
- background: IOColors["grey-50"],
44
- pressed: IOColors["grey-200"],
45
- foreground: "blueIO-500"
46
- },
47
- dark: {
48
- background: IOColors["blueIO-400"],
49
- pressed: IOColors["blueIO-200"],
50
- foreground: "white"
51
- }
52
- };
53
-
54
44
  /**
55
45
  * Based on a `Pressable` element, it displays a number button with animations on press In and Out.
56
46
  *
@@ -58,11 +48,32 @@ const colorMap: Record<NumberButtonVariantType, ColorMapVariant> = {
58
48
  */
59
49
  export const NumberButton = memo(
60
50
  ({ number, variant, onPress }: NumberButtonProps) => {
51
+ const theme = useIOTheme();
52
+
61
53
  const { progress, onPressIn, onPressOut, scaleAnimatedStyle } =
62
- useScaleAnimation("slight");
54
+ useScaleAnimation("medium");
63
55
  const reducedMotion = useReducedMotion();
64
56
  const { newTypefaceEnabled } = useIONewTypeface();
65
57
 
58
+ const colorMap: Record<NumberButtonVariantType, ColorMapVariant> = useMemo(
59
+ () => ({
60
+ neutral: {
61
+ background: hexToRgba(
62
+ IOColors[theme["interactiveElem-default"]],
63
+ 0.1
64
+ ),
65
+ pressed: hexToRgba(IOColors[theme["interactiveElem-default"]], 0.35),
66
+ foreground: theme["interactiveElem-default"]
67
+ },
68
+ primary: {
69
+ background: hexToRgba(IOColors.white, 0.15),
70
+ pressed: hexToRgba(IOColors.white, 0.5),
71
+ foreground: "white"
72
+ }
73
+ }),
74
+ [theme]
75
+ );
76
+
66
77
  // Interpolate animation values from `isPressed` values
67
78
  const pressedAnimationStyle = useAnimatedStyle(() => ({
68
79
  backgroundColor: interpolateColor(
@@ -73,6 +84,7 @@ export const NumberButton = memo(
73
84
  }));
74
85
 
75
86
  const handleOnPress = useCallback(() => {
87
+ ReactNativeHapticFeedback.trigger("impactLight");
76
88
  onPress(number);
77
89
  }, [number, onPress]);
78
90
 
@@ -70,7 +70,7 @@ const mapIconSpecByBiometric: Record<
70
70
  * @returns {JSX.Element} The rendered numeric keyboard component.
71
71
  */
72
72
  export const NumberPad = ({
73
- variant = "dark",
73
+ variant = "primary",
74
74
  biometricType,
75
75
  biometricAccessibilityLabel,
76
76
  deleteAccessibilityLabel,
@@ -101,7 +101,7 @@ export const NumberPad = ({
101
101
  <ButtonWrapper key={item}>
102
102
  <IconButton
103
103
  icon="cancel"
104
- color={variant === "dark" ? "contrast" : "primary"}
104
+ color={variant === "primary" ? "contrast" : "primary"}
105
105
  onPress={onDeletePress}
106
106
  accessibilityLabel={deleteAccessibilityLabel}
107
107
  />
@@ -114,7 +114,7 @@ export const NumberPad = ({
114
114
  <IconButton
115
115
  icon={mapIconSpecByBiometric[biometricType].icon}
116
116
  iconSize={mapIconSpecByBiometric[biometricType].size}
117
- color={variant === "dark" ? "contrast" : "primary"}
117
+ color={variant === "primary" ? "contrast" : "primary"}
118
118
  onPress={onBiometricPress}
119
119
  accessibilityLabel={biometricAccessibilityLabel}
120
120
  />