@pagopa/io-app-design-system 1.22.0 → 1.23.1
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/avatar/Avatar.js +21 -8
- package/lib/commonjs/components/avatar/Avatar.js.map +1 -1
- package/lib/commonjs/components/icons/Icon.js +4 -3
- package/lib/commonjs/components/icons/Icon.js.map +1 -1
- package/lib/commonjs/components/layout/HeaderSecondLevel.js +2 -0
- package/lib/commonjs/components/layout/HeaderSecondLevel.js.map +1 -1
- package/lib/commonjs/components/listitems/ListItemHeader.js +2 -1
- package/lib/commonjs/components/listitems/ListItemHeader.js.map +1 -1
- package/lib/commonjs/components/listitems/ListItemNav.js +13 -3
- package/lib/commonjs/components/listitems/ListItemNav.js.map +1 -1
- package/lib/commonjs/components/modules/ModuleAttachment.js +196 -0
- package/lib/commonjs/components/modules/ModuleAttachment.js.map +1 -0
- package/lib/commonjs/components/modules/index.js +11 -0
- package/lib/commonjs/components/modules/index.js.map +1 -1
- package/lib/module/components/avatar/Avatar.js +22 -8
- package/lib/module/components/avatar/Avatar.js.map +1 -1
- package/lib/module/components/icons/Icon.js +4 -3
- package/lib/module/components/icons/Icon.js.map +1 -1
- package/lib/module/components/layout/HeaderSecondLevel.js +2 -0
- package/lib/module/components/layout/HeaderSecondLevel.js.map +1 -1
- package/lib/module/components/listitems/ListItemHeader.js +2 -1
- package/lib/module/components/listitems/ListItemHeader.js.map +1 -1
- package/lib/module/components/listitems/ListItemNav.js +13 -3
- package/lib/module/components/listitems/ListItemNav.js.map +1 -1
- package/lib/module/components/modules/ModuleAttachment.js +186 -0
- package/lib/module/components/modules/ModuleAttachment.js.map +1 -0
- package/lib/module/components/modules/index.js +1 -0
- package/lib/module/components/modules/index.js.map +1 -1
- package/lib/typescript/components/avatar/Avatar.d.ts +9 -1
- package/lib/typescript/components/avatar/Avatar.d.ts.map +1 -1
- package/lib/typescript/components/icons/Icon.d.ts.map +1 -1
- package/lib/typescript/components/layout/HeaderSecondLevel.d.ts.map +1 -1
- package/lib/typescript/components/listitems/ListItemHeader.d.ts.map +1 -1
- package/lib/typescript/components/listitems/ListItemNav.d.ts +2 -1
- package/lib/typescript/components/listitems/ListItemNav.d.ts.map +1 -1
- package/lib/typescript/components/modules/ModuleAttachment.d.ts +32 -0
- package/lib/typescript/components/modules/ModuleAttachment.d.ts.map +1 -0
- package/lib/typescript/components/modules/index.d.ts +1 -0
- package/lib/typescript/components/modules/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/avatar/Avatar.tsx +31 -13
- package/src/components/icons/Icon.tsx +4 -3
- package/src/components/layout/HeaderSecondLevel.tsx +2 -0
- package/src/components/listitems/ListItemHeader.tsx +4 -1
- package/src/components/listitems/ListItemNav.tsx +15 -3
- package/src/components/modules/ModuleAttachment.tsx +254 -0
- package/src/components/modules/index.tsx +1 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import React, { useCallback } from "react";
|
|
2
|
+
import {
|
|
3
|
+
GestureResponderEvent,
|
|
4
|
+
Pressable,
|
|
5
|
+
PressableProps,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
View
|
|
8
|
+
} from "react-native";
|
|
9
|
+
import Animated, {
|
|
10
|
+
Extrapolate,
|
|
11
|
+
interpolate,
|
|
12
|
+
useAnimatedStyle,
|
|
13
|
+
useDerivedValue,
|
|
14
|
+
useSharedValue,
|
|
15
|
+
withSpring
|
|
16
|
+
} from "react-native-reanimated";
|
|
17
|
+
import Placeholder from "rn-placeholder";
|
|
18
|
+
import {
|
|
19
|
+
IOColors,
|
|
20
|
+
IOListItemVisualParams,
|
|
21
|
+
IOScaleValues,
|
|
22
|
+
IOSpringValues,
|
|
23
|
+
useIOTheme
|
|
24
|
+
} from "../../core";
|
|
25
|
+
import { WithTestID } from "../../utils/types";
|
|
26
|
+
import { Icon } from "../icons";
|
|
27
|
+
import { LabelSmall } from "../typography";
|
|
28
|
+
import { VSpacer } from "../spacer";
|
|
29
|
+
import { Badge } from "../badge";
|
|
30
|
+
import { LoadingSpinner } from "../loadingSpinner";
|
|
31
|
+
|
|
32
|
+
type PartialProps = WithTestID<{
|
|
33
|
+
title: string;
|
|
34
|
+
format: "doc" | "pdf";
|
|
35
|
+
isLoading?: boolean;
|
|
36
|
+
loadingAccessibilityLabel?: string;
|
|
37
|
+
isFetching?: boolean;
|
|
38
|
+
fetchingAccessibilityLabel?: string;
|
|
39
|
+
onPress: (event: GestureResponderEvent) => void;
|
|
40
|
+
}>;
|
|
41
|
+
|
|
42
|
+
export type ModuleAttachmentProps = PartialProps &
|
|
43
|
+
Pick<
|
|
44
|
+
PressableProps,
|
|
45
|
+
"onPress" | "accessibilityLabel" | "disabled" | "testID"
|
|
46
|
+
>;
|
|
47
|
+
|
|
48
|
+
type SkeletonComponentProps = {
|
|
49
|
+
loadingAccessibilityLabel?: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const styles = StyleSheet.create({
|
|
53
|
+
button: {
|
|
54
|
+
flexDirection: "row",
|
|
55
|
+
alignItems: "center",
|
|
56
|
+
paddingHorizontal: 16,
|
|
57
|
+
paddingVertical: 16,
|
|
58
|
+
borderRadius: 8,
|
|
59
|
+
borderColor: IOColors.bluegreyLight,
|
|
60
|
+
backgroundColor: IOColors.white,
|
|
61
|
+
borderStyle: "solid",
|
|
62
|
+
borderWidth: 1
|
|
63
|
+
},
|
|
64
|
+
innerContent: {
|
|
65
|
+
flex: 1,
|
|
66
|
+
flexDirection: "column"
|
|
67
|
+
},
|
|
68
|
+
rightSection: {
|
|
69
|
+
marginLeft: IOListItemVisualParams.iconMargin,
|
|
70
|
+
alignItems: "center"
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const DISABLED_OPACITY = 0.5;
|
|
75
|
+
|
|
76
|
+
const ModuleAttachmentContent = ({
|
|
77
|
+
isFetching,
|
|
78
|
+
format,
|
|
79
|
+
title,
|
|
80
|
+
testID
|
|
81
|
+
}: Pick<
|
|
82
|
+
ModuleAttachmentProps,
|
|
83
|
+
"isFetching" | "format" | "title" | "testID"
|
|
84
|
+
>) => {
|
|
85
|
+
const theme = useIOTheme();
|
|
86
|
+
const IconOrActivityIndicatorComponent = () => {
|
|
87
|
+
if (isFetching) {
|
|
88
|
+
const activityIndicatorTestId = testID
|
|
89
|
+
? `${testID}_activityIndicator`
|
|
90
|
+
: undefined;
|
|
91
|
+
return <LoadingSpinner testID={activityIndicatorTestId} />;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<Icon
|
|
96
|
+
name="chevronRightListItem"
|
|
97
|
+
color={theme["interactiveElem-default"]}
|
|
98
|
+
size={IOListItemVisualParams.chevronSize}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<>
|
|
105
|
+
<View style={styles.innerContent}>
|
|
106
|
+
<LabelSmall
|
|
107
|
+
numberOfLines={1}
|
|
108
|
+
weight="SemiBold"
|
|
109
|
+
font="ReadexPro"
|
|
110
|
+
color="blueIO-500"
|
|
111
|
+
>
|
|
112
|
+
{title}
|
|
113
|
+
</LabelSmall>
|
|
114
|
+
<VSpacer size={4} />
|
|
115
|
+
<View style={{ width: 44 }}>
|
|
116
|
+
<Badge text={format.toUpperCase()} variant="default" />
|
|
117
|
+
</View>
|
|
118
|
+
</View>
|
|
119
|
+
<View style={styles.rightSection}>
|
|
120
|
+
<IconOrActivityIndicatorComponent />
|
|
121
|
+
</View>
|
|
122
|
+
</>
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The `ModuleAttachment` component is a custom button component with an extended outline style.
|
|
128
|
+
* It provides an animated scaling effect when pressed.
|
|
129
|
+
*
|
|
130
|
+
* @param {string} accessibilityLabel - Optional accessibility label.
|
|
131
|
+
* @param {boolean} disabled - If true, the button is disabled.
|
|
132
|
+
* @param {string} fetchingAccessibilityLabel - Optional accessibility label to use during fetching.
|
|
133
|
+
* @param {string} format - Badge content. PDF or DOC.
|
|
134
|
+
* @param {boolean} isLoading - If true, displays a skeleton loading component.
|
|
135
|
+
* @param {boolean} isFetching - If true, displays an activity indicator.
|
|
136
|
+
* @param {string} loadingAccessibilityLabel - Optional accessibility label to use during loading.
|
|
137
|
+
* @param {function} onPress - The function to be executed when the item is pressed.
|
|
138
|
+
* @param {string} testID - The test ID for testing purposes.
|
|
139
|
+
* @param {string} title - The title text to display.
|
|
140
|
+
*
|
|
141
|
+
*/
|
|
142
|
+
export const ModuleAttachment = ({
|
|
143
|
+
accessibilityLabel,
|
|
144
|
+
disabled = false,
|
|
145
|
+
fetchingAccessibilityLabel,
|
|
146
|
+
format,
|
|
147
|
+
isLoading = false,
|
|
148
|
+
isFetching = false,
|
|
149
|
+
loadingAccessibilityLabel,
|
|
150
|
+
onPress,
|
|
151
|
+
testID,
|
|
152
|
+
title
|
|
153
|
+
}: ModuleAttachmentProps) => {
|
|
154
|
+
const isPressed: Animated.SharedValue<number> = useSharedValue(0);
|
|
155
|
+
|
|
156
|
+
// Scaling transformation applied when the button is pressed
|
|
157
|
+
const animationScaleValue = IOScaleValues?.magnifiedButton?.pressedState;
|
|
158
|
+
|
|
159
|
+
const scaleTraversed = useDerivedValue(() =>
|
|
160
|
+
withSpring(isPressed.value, IOSpringValues.button)
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
// Interpolate animation values from `isPressed` values
|
|
164
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
165
|
+
const scale = interpolate(
|
|
166
|
+
scaleTraversed.value,
|
|
167
|
+
[0, 1],
|
|
168
|
+
[1, animationScaleValue],
|
|
169
|
+
Extrapolate.CLAMP
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
transform: [{ scale }]
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const onPressIn = useCallback(() => {
|
|
178
|
+
// eslint-disable-next-line functional/immutable-data
|
|
179
|
+
isPressed.value = 1;
|
|
180
|
+
}, [isPressed]);
|
|
181
|
+
|
|
182
|
+
const onPressOut = useCallback(() => {
|
|
183
|
+
// eslint-disable-next-line functional/immutable-data
|
|
184
|
+
isPressed.value = 0;
|
|
185
|
+
}, [isPressed]);
|
|
186
|
+
|
|
187
|
+
const handleOnPress = useCallback(
|
|
188
|
+
(event: GestureResponderEvent) => {
|
|
189
|
+
if (isFetching) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
onPress(event);
|
|
193
|
+
},
|
|
194
|
+
[isFetching, onPress]
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
if (isLoading) {
|
|
198
|
+
return (
|
|
199
|
+
<SkeletonComponent
|
|
200
|
+
loadingAccessibilityLabel={loadingAccessibilityLabel}
|
|
201
|
+
/>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const pressableAccessibilityLabel =
|
|
206
|
+
(isFetching && !!fetchingAccessibilityLabel
|
|
207
|
+
? fetchingAccessibilityLabel
|
|
208
|
+
: accessibilityLabel) ?? title;
|
|
209
|
+
return (
|
|
210
|
+
<Pressable
|
|
211
|
+
testID={testID}
|
|
212
|
+
onPress={handleOnPress}
|
|
213
|
+
onPressIn={onPressIn}
|
|
214
|
+
onPressOut={onPressOut}
|
|
215
|
+
accessible={true}
|
|
216
|
+
accessibilityRole={"button"}
|
|
217
|
+
accessibilityHint={format}
|
|
218
|
+
accessibilityLabel={pressableAccessibilityLabel}
|
|
219
|
+
disabled={disabled || isFetching}
|
|
220
|
+
>
|
|
221
|
+
<Animated.View
|
|
222
|
+
style={[
|
|
223
|
+
styles.button,
|
|
224
|
+
animatedStyle,
|
|
225
|
+
{ opacity: disabled ? DISABLED_OPACITY : 1 }
|
|
226
|
+
]}
|
|
227
|
+
accessibilityElementsHidden={true}
|
|
228
|
+
importantForAccessibility="no-hide-descendants"
|
|
229
|
+
>
|
|
230
|
+
<ModuleAttachmentContent
|
|
231
|
+
isFetching={isFetching}
|
|
232
|
+
title={title}
|
|
233
|
+
format={format}
|
|
234
|
+
/>
|
|
235
|
+
</Animated.View>
|
|
236
|
+
</Pressable>
|
|
237
|
+
);
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const SkeletonComponent = ({
|
|
241
|
+
loadingAccessibilityLabel
|
|
242
|
+
}: SkeletonComponentProps) => (
|
|
243
|
+
<View
|
|
244
|
+
style={styles.button}
|
|
245
|
+
accessible={true}
|
|
246
|
+
accessibilityLabel={loadingAccessibilityLabel}
|
|
247
|
+
>
|
|
248
|
+
<View style={styles.innerContent}>
|
|
249
|
+
<Placeholder.Box animate="fade" radius={8} width={107} height={22} />
|
|
250
|
+
<VSpacer size={4} />
|
|
251
|
+
<Placeholder.Box animate="fade" radius={8} width={44} height={22} />
|
|
252
|
+
</View>
|
|
253
|
+
</View>
|
|
254
|
+
);
|