@pagopa/io-app-design-system 5.0.6 → 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.
- package/lib/commonjs/components/codeInput/CodeInput.js +8 -5
- package/lib/commonjs/components/codeInput/CodeInput.js.map +1 -1
- package/lib/commonjs/components/common/ScaleInOutAnimation.js +7 -5
- package/lib/commonjs/components/common/ScaleInOutAnimation.js.map +1 -1
- package/lib/commonjs/components/layout/ForceScrollDownView.js +27 -23
- package/lib/commonjs/components/layout/ForceScrollDownView.js.map +1 -1
- package/lib/commonjs/components/layout/__test__/ForceScrollDownView.test.js +12 -4
- package/lib/commonjs/components/layout/__test__/ForceScrollDownView.test.js.map +1 -1
- package/lib/commonjs/components/layout/__test__/__snapshots__/ForceScrollDownView.test.tsx.snap +1 -6
- package/lib/commonjs/components/layout/hooks/useFooterActionsInlineMeasurements.js +2 -2
- package/lib/commonjs/components/layout/hooks/useFooterActionsInlineMeasurements.js.map +1 -1
- package/lib/commonjs/components/layout/hooks/useFooterActionsMeasurements.js +2 -2
- package/lib/commonjs/components/layout/hooks/useFooterActionsMeasurements.js.map +1 -1
- package/lib/commonjs/components/listitems/ListItemRadioWithAmount.js +2 -1
- package/lib/commonjs/components/listitems/ListItemRadioWithAmount.js.map +1 -1
- package/lib/commonjs/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +4 -0
- package/lib/commonjs/components/numberpad/NumberButton.js +17 -14
- package/lib/commonjs/components/numberpad/NumberButton.js.map +1 -1
- package/lib/commonjs/components/numberpad/NumberPad.js +3 -3
- package/lib/commonjs/components/numberpad/NumberPad.js.map +1 -1
- package/lib/commonjs/components/tabs/TabItem.js +2 -6
- package/lib/commonjs/components/tabs/TabItem.js.map +1 -1
- package/lib/commonjs/components/tabs/TabNavigation.js +3 -4
- package/lib/commonjs/components/tabs/TabNavigation.js.map +1 -1
- package/lib/module/components/codeInput/CodeInput.js +8 -5
- package/lib/module/components/codeInput/CodeInput.js.map +1 -1
- package/lib/module/components/common/ScaleInOutAnimation.js +8 -6
- package/lib/module/components/common/ScaleInOutAnimation.js.map +1 -1
- package/lib/module/components/layout/ForceScrollDownView.js +27 -23
- package/lib/module/components/layout/ForceScrollDownView.js.map +1 -1
- package/lib/module/components/layout/__test__/ForceScrollDownView.test.js +12 -4
- package/lib/module/components/layout/__test__/ForceScrollDownView.test.js.map +1 -1
- package/lib/module/components/layout/__test__/__snapshots__/ForceScrollDownView.test.tsx.snap +1 -6
- package/lib/module/components/layout/hooks/useFooterActionsInlineMeasurements.js +3 -3
- package/lib/module/components/layout/hooks/useFooterActionsInlineMeasurements.js.map +1 -1
- package/lib/module/components/layout/hooks/useFooterActionsMeasurements.js +3 -3
- package/lib/module/components/layout/hooks/useFooterActionsMeasurements.js.map +1 -1
- package/lib/module/components/listitems/ListItemRadioWithAmount.js +2 -1
- package/lib/module/components/listitems/ListItemRadioWithAmount.js.map +1 -1
- package/lib/module/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +4 -0
- package/lib/module/components/numberpad/NumberButton.js +18 -16
- package/lib/module/components/numberpad/NumberButton.js.map +1 -1
- package/lib/module/components/numberpad/NumberPad.js +3 -3
- package/lib/module/components/numberpad/NumberPad.js.map +1 -1
- package/lib/module/components/tabs/TabItem.js +2 -6
- package/lib/module/components/tabs/TabItem.js.map +1 -1
- package/lib/module/components/tabs/TabNavigation.js +3 -4
- package/lib/module/components/tabs/TabNavigation.js.map +1 -1
- package/lib/typescript/components/codeInput/CodeInput.d.ts +1 -1
- package/lib/typescript/components/codeInput/CodeInput.d.ts.map +1 -1
- package/lib/typescript/components/common/ScaleInOutAnimation.d.ts +1 -3
- package/lib/typescript/components/common/ScaleInOutAnimation.d.ts.map +1 -1
- package/lib/typescript/components/layout/ForceScrollDownView.d.ts +20 -8
- package/lib/typescript/components/layout/ForceScrollDownView.d.ts.map +1 -1
- package/lib/typescript/components/layout/hooks/useFooterActionsInlineMeasurements.d.ts.map +1 -1
- package/lib/typescript/components/layout/hooks/useFooterActionsMeasurements.d.ts.map +1 -1
- package/lib/typescript/components/listitems/ListItemRadioWithAmount.d.ts.map +1 -1
- package/lib/typescript/components/numberpad/NumberButton.d.ts +2 -2
- package/lib/typescript/components/numberpad/NumberButton.d.ts.map +1 -1
- package/lib/typescript/components/tabs/TabItem.d.ts +0 -2
- package/lib/typescript/components/tabs/TabItem.d.ts.map +1 -1
- package/lib/typescript/components/tabs/TabNavigation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/codeInput/CodeInput.tsx +11 -7
- package/src/components/common/ScaleInOutAnimation.tsx +8 -10
- package/src/components/layout/ForceScrollDownView.tsx +67 -32
- package/src/components/layout/__test__/ForceScrollDownView.test.tsx +4 -4
- package/src/components/layout/__test__/__snapshots__/ForceScrollDownView.test.tsx.snap +1 -6
- package/src/components/layout/hooks/useFooterActionsInlineMeasurements.ts +7 -6
- package/src/components/layout/hooks/useFooterActionsMeasurements.ts +7 -6
- package/src/components/listitems/ListItemRadioWithAmount.tsx +5 -1
- package/src/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +4 -0
- package/src/components/numberpad/NumberButton.tsx +30 -18
- package/src/components/numberpad/NumberPad.tsx +3 -3
- package/src/components/tabs/TabItem.tsx +18 -27
- package/src/components/tabs/TabNavigation.tsx +2 -4
|
@@ -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
|
|
24
|
+
type ForceScrollDownViewActions = {
|
|
21
25
|
/**
|
|
22
|
-
* The
|
|
26
|
+
* The distance from the bottom is computed automatically based on the actions.
|
|
23
27
|
*/
|
|
24
|
-
|
|
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.
|
|
38
|
+
* should become hidden.
|
|
28
39
|
*/
|
|
29
|
-
threshold
|
|
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
|
-
} &
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|
73
|
+
threshold: customThreshold,
|
|
49
74
|
style,
|
|
50
75
|
contentContainerStyle,
|
|
51
76
|
scrollEnabled = true,
|
|
52
77
|
onThresholdCrossed
|
|
53
|
-
}:
|
|
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
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
149
|
-
contentHeight
|
|
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={
|
|
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
|
-
|
|
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
|
-
|
|
29
|
-
|
|
25
|
+
const handleFooterActionsMeasurements = useCallback(
|
|
26
|
+
(values: FooterActionsMeasurements) => {
|
|
27
|
+
setFooterActionsMeasurements(values);
|
|
28
|
+
},
|
|
29
|
+
[]
|
|
30
|
+
);
|
|
30
31
|
|
|
31
32
|
return {
|
|
32
33
|
footerActionsMeasurements,
|
|
@@ -48,11 +48,15 @@ export const ListItemRadioWithAmount = ({
|
|
|
48
48
|
|
|
49
49
|
const suggestColor: IOColors = "hanPurple-500";
|
|
50
50
|
|
|
51
|
+
const defaultAccessibilityLabel = `${label} ${formattedAmountString} ${
|
|
52
|
+
suggestReason ?? ""
|
|
53
|
+
}`;
|
|
54
|
+
|
|
51
55
|
return (
|
|
52
56
|
<PressableListItemBase
|
|
53
57
|
onPress={pressHandler}
|
|
54
58
|
accessibilityRole="radio"
|
|
55
|
-
accessibilityLabel={accessibilityLabel}
|
|
59
|
+
accessibilityLabel={accessibilityLabel ?? defaultAccessibilityLabel}
|
|
56
60
|
accessibilityState={{
|
|
57
61
|
checked: selected ?? toggleValue
|
|
58
62
|
}}
|
|
@@ -767,6 +767,7 @@ exports[`Test List Item Components - Experimental Enabled ListItemNavAlert Snap
|
|
|
767
767
|
|
|
768
768
|
exports[`Test List Item Components - Experimental Enabled ListItemRadioWithAmount Snapshot 1`] = `
|
|
769
769
|
<View
|
|
770
|
+
accessibilityLabel="label € 1.000,00 suggestReason"
|
|
770
771
|
accessibilityRole="radio"
|
|
771
772
|
accessibilityState={
|
|
772
773
|
{
|
|
@@ -1140,6 +1141,7 @@ exports[`Test List Item Components - Experimental Enabled ListItemRadioWithAmou
|
|
|
1140
1141
|
|
|
1141
1142
|
exports[`Test List Item Components - Experimental Enabled ListItemRadioWithAmount Snapshot 2`] = `
|
|
1142
1143
|
<View
|
|
1144
|
+
accessibilityLabel="label € 1.000,00 "
|
|
1143
1145
|
accessibilityRole="radio"
|
|
1144
1146
|
accessibilityState={
|
|
1145
1147
|
{
|
|
@@ -2343,6 +2345,7 @@ exports[`Test List Item Components ListItemNavAlert Snapshot 1`] = `
|
|
|
2343
2345
|
|
|
2344
2346
|
exports[`Test List Item Components ListItemRadioWithAmount Snapshot 1`] = `
|
|
2345
2347
|
<View
|
|
2348
|
+
accessibilityLabel="label € 1.000,00 suggestReason"
|
|
2346
2349
|
accessibilityRole="radio"
|
|
2347
2350
|
accessibilityState={
|
|
2348
2351
|
{
|
|
@@ -2716,6 +2719,7 @@ exports[`Test List Item Components ListItemRadioWithAmount Snapshot 1`] = `
|
|
|
2716
2719
|
|
|
2717
2720
|
exports[`Test List Item Components ListItemRadioWithAmount Snapshot 2`] = `
|
|
2718
2721
|
<View
|
|
2722
|
+
accessibilityLabel="label € 1.000,00 "
|
|
2719
2723
|
accessibilityRole="radio"
|
|
2720
2724
|
accessibilityState={
|
|
2721
2725
|
{
|
|
@@ -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 = "
|
|
19
|
+
type NumberButtonVariantType = "neutral" | "primary";
|
|
17
20
|
|
|
18
21
|
type NumberButtonProps = {
|
|
19
22
|
/**
|
|
20
|
-
* Used to choose the component color variant between `
|
|
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("
|
|
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 = "
|
|
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 === "
|
|
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 === "
|
|
117
|
+
color={variant === "primary" ? "contrast" : "primary"}
|
|
118
118
|
onPress={onBiometricPress}
|
|
119
119
|
accessibilityLabel={biometricAccessibilityLabel}
|
|
120
120
|
/>
|
|
@@ -33,7 +33,6 @@ export type TabItem = WithTestID<{
|
|
|
33
33
|
label: string;
|
|
34
34
|
color?: ColorMode;
|
|
35
35
|
selected?: boolean;
|
|
36
|
-
fullWidth?: boolean;
|
|
37
36
|
// Icons
|
|
38
37
|
icon?: IOIcons;
|
|
39
38
|
iconSelected?: IOIcons;
|
|
@@ -69,7 +68,6 @@ const TabItem = forwardRef(
|
|
|
69
68
|
label,
|
|
70
69
|
color = "light",
|
|
71
70
|
selected = false,
|
|
72
|
-
fullWidth = false,
|
|
73
71
|
accessibilityLabel,
|
|
74
72
|
accessibilityHint,
|
|
75
73
|
testID,
|
|
@@ -149,27 +147,24 @@ const TabItem = forwardRef(
|
|
|
149
147
|
);
|
|
150
148
|
|
|
151
149
|
// Interpolate animation values from `pressed` values
|
|
152
|
-
const animatedStyle = useAnimatedStyle(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
[
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
[
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}),
|
|
171
|
-
[selectedStateTransition]
|
|
172
|
-
);
|
|
150
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
151
|
+
backgroundColor: interpolateColor(
|
|
152
|
+
selectedStateTransition.value,
|
|
153
|
+
[0, 1],
|
|
154
|
+
[
|
|
155
|
+
mapColorStates[color].background.default,
|
|
156
|
+
mapColorStates[color].background.selected
|
|
157
|
+
]
|
|
158
|
+
),
|
|
159
|
+
borderColor: interpolateColor(
|
|
160
|
+
selectedStateTransition.value,
|
|
161
|
+
[0, 1],
|
|
162
|
+
[
|
|
163
|
+
mapColorStates[color].border.default,
|
|
164
|
+
mapColorStates[color].border.selected
|
|
165
|
+
]
|
|
166
|
+
)
|
|
167
|
+
}));
|
|
173
168
|
|
|
174
169
|
const activeIcon = selected ? iconSelected ?? icon : icon;
|
|
175
170
|
|
|
@@ -203,7 +198,6 @@ const TabItem = forwardRef(
|
|
|
203
198
|
{ columnGap: 4 },
|
|
204
199
|
!disabled && !reducedMotion && scaleAnimatedStyle,
|
|
205
200
|
animatedStyle,
|
|
206
|
-
fullWidth && styles.fullWidth,
|
|
207
201
|
disabled && { opacity: DISABLED_OPACITY }
|
|
208
202
|
]}
|
|
209
203
|
>
|
|
@@ -235,9 +229,6 @@ const styles = StyleSheet.create({
|
|
|
235
229
|
borderCurve: "continuous",
|
|
236
230
|
justifyContent: "center",
|
|
237
231
|
alignSelf: "flex-start"
|
|
238
|
-
},
|
|
239
|
-
fullWidth: {
|
|
240
|
-
alignSelf: "auto"
|
|
241
232
|
}
|
|
242
233
|
});
|
|
243
234
|
|
|
@@ -56,9 +56,6 @@ const TabNavigation = ({
|
|
|
56
56
|
key={index}
|
|
57
57
|
style={[
|
|
58
58
|
styles.item,
|
|
59
|
-
{
|
|
60
|
-
marginEnd: index === React.Children.count(children) - 1 ? 0 : 8
|
|
61
|
-
},
|
|
62
59
|
stretchItems && {
|
|
63
60
|
minWidth: itemMinWidth
|
|
64
61
|
}
|
|
@@ -87,7 +84,8 @@ const TabNavigation = ({
|
|
|
87
84
|
: {},
|
|
88
85
|
{
|
|
89
86
|
flexGrow: 1,
|
|
90
|
-
justifyContent: itemsJustify[tabAlignment]
|
|
87
|
+
justifyContent: itemsJustify[tabAlignment],
|
|
88
|
+
gap: 8
|
|
91
89
|
}
|
|
92
90
|
]}
|
|
93
91
|
>
|