@pagopa/io-app-design-system 6.0.4 → 6.0.6
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/badge/Badge.js +0 -4
- package/lib/commonjs/components/badge/Badge.js.map +1 -1
- package/lib/commonjs/components/banner/Banner.js +0 -4
- package/lib/commonjs/components/banner/Banner.js.map +1 -1
- package/lib/commonjs/components/buttons/IOButton/IOButton.js +0 -5
- package/lib/commonjs/components/buttons/IOButton/IOButton.js.map +1 -1
- package/lib/commonjs/components/claimsSelector/__test__/__snapshots__/ClaimsSelector.test.tsx.snap +7 -5
- package/lib/commonjs/components/headers/HeaderSecondLevel.js +0 -4
- package/lib/commonjs/components/headers/HeaderSecondLevel.js.map +1 -1
- package/lib/commonjs/components/listitems/ListItemInfo.js +86 -26
- package/lib/commonjs/components/listitems/ListItemInfo.js.map +1 -1
- package/lib/commonjs/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +6 -4
- package/lib/commonjs/components/loadingSpinner/LoadingSpinner.js +30 -23
- package/lib/commonjs/components/loadingSpinner/LoadingSpinner.js.map +1 -1
- package/lib/commonjs/components/modules/ModuleIDP.js +0 -4
- package/lib/commonjs/components/modules/ModuleIDP.js.map +1 -1
- package/lib/commonjs/components/numberpad/NumberButton.js +0 -4
- package/lib/commonjs/components/numberpad/NumberButton.js.map +1 -1
- package/lib/commonjs/components/searchInput/SearchInput.js +0 -1
- package/lib/commonjs/components/searchInput/SearchInput.js.map +1 -1
- package/lib/commonjs/components/tabs/TabItem.js +0 -4
- package/lib/commonjs/components/tabs/TabItem.js.map +1 -1
- package/lib/commonjs/components/tag/Tag.js +0 -4
- package/lib/commonjs/components/tag/Tag.js.map +1 -1
- package/lib/commonjs/components/typography/Body.js +1 -7
- package/lib/commonjs/components/typography/Body.js.map +1 -1
- package/lib/commonjs/components/typography/BodySmall.js +0 -7
- package/lib/commonjs/components/typography/BodySmall.js.map +1 -1
- package/lib/commonjs/components/typography/ButtonText.js +0 -7
- package/lib/commonjs/components/typography/ButtonText.js.map +1 -1
- package/lib/commonjs/components/typography/Caption.js +0 -4
- package/lib/commonjs/components/typography/Caption.js.map +1 -1
- package/lib/commonjs/components/typography/H1.js +0 -4
- package/lib/commonjs/components/typography/H1.js.map +1 -1
- package/lib/commonjs/components/typography/H2.js +0 -4
- package/lib/commonjs/components/typography/H2.js.map +1 -1
- package/lib/commonjs/components/typography/H3.js +0 -4
- package/lib/commonjs/components/typography/H3.js.map +1 -1
- package/lib/commonjs/components/typography/H4.js +0 -4
- package/lib/commonjs/components/typography/H4.js.map +1 -1
- package/lib/commonjs/components/typography/H5.js +0 -4
- package/lib/commonjs/components/typography/H5.js.map +1 -1
- package/lib/commonjs/components/typography/H6.js +0 -1
- package/lib/commonjs/components/typography/H6.js.map +1 -1
- package/lib/commonjs/components/typography/Hero.js +0 -4
- package/lib/commonjs/components/typography/Hero.js.map +1 -1
- package/lib/commonjs/components/typography/IOText.js +5 -1
- package/lib/commonjs/components/typography/IOText.js.map +1 -1
- package/lib/commonjs/components/typography/LabelMini.js +1 -8
- package/lib/commonjs/components/typography/LabelMini.js.map +1 -1
- package/lib/commonjs/components/typography/markdown/MdH1.js +0 -4
- package/lib/commonjs/components/typography/markdown/MdH1.js.map +1 -1
- package/lib/commonjs/components/typography/markdown/MdH2.js +0 -4
- package/lib/commonjs/components/typography/markdown/MdH2.js.map +1 -1
- package/lib/commonjs/components/typography/markdown/MdH3.js +0 -4
- package/lib/commonjs/components/typography/markdown/MdH3.js.map +1 -1
- package/lib/module/components/badge/Badge.js +1 -5
- package/lib/module/components/badge/Badge.js.map +1 -1
- package/lib/module/components/banner/Banner.js +1 -5
- package/lib/module/components/banner/Banner.js.map +1 -1
- package/lib/module/components/buttons/IOButton/IOButton.js +0 -5
- package/lib/module/components/buttons/IOButton/IOButton.js.map +1 -1
- package/lib/module/components/claimsSelector/__test__/__snapshots__/ClaimsSelector.test.tsx.snap +7 -5
- package/lib/module/components/headers/HeaderSecondLevel.js +1 -5
- package/lib/module/components/headers/HeaderSecondLevel.js.map +1 -1
- package/lib/module/components/listitems/ListItemInfo.js +87 -27
- package/lib/module/components/listitems/ListItemInfo.js.map +1 -1
- package/lib/module/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +6 -4
- package/lib/module/components/loadingSpinner/LoadingSpinner.js +30 -24
- package/lib/module/components/loadingSpinner/LoadingSpinner.js.map +1 -1
- package/lib/module/components/modules/ModuleIDP.js +1 -5
- package/lib/module/components/modules/ModuleIDP.js.map +1 -1
- package/lib/module/components/numberpad/NumberButton.js +1 -5
- package/lib/module/components/numberpad/NumberButton.js.map +1 -1
- package/lib/module/components/searchInput/SearchInput.js +0 -1
- package/lib/module/components/searchInput/SearchInput.js.map +1 -1
- package/lib/module/components/tabs/TabItem.js +1 -5
- package/lib/module/components/tabs/TabItem.js.map +1 -1
- package/lib/module/components/tag/Tag.js +1 -5
- package/lib/module/components/tag/Tag.js.map +1 -1
- package/lib/module/components/typography/Body.js +2 -8
- package/lib/module/components/typography/Body.js.map +1 -1
- package/lib/module/components/typography/BodySmall.js +1 -8
- package/lib/module/components/typography/BodySmall.js.map +1 -1
- package/lib/module/components/typography/ButtonText.js +0 -7
- package/lib/module/components/typography/ButtonText.js.map +1 -1
- package/lib/module/components/typography/Caption.js +1 -5
- package/lib/module/components/typography/Caption.js.map +1 -1
- package/lib/module/components/typography/H1.js +1 -5
- package/lib/module/components/typography/H1.js.map +1 -1
- package/lib/module/components/typography/H2.js +1 -5
- package/lib/module/components/typography/H2.js.map +1 -1
- package/lib/module/components/typography/H3.js +1 -5
- package/lib/module/components/typography/H3.js.map +1 -1
- package/lib/module/components/typography/H4.js +1 -5
- package/lib/module/components/typography/H4.js.map +1 -1
- package/lib/module/components/typography/H5.js +1 -5
- package/lib/module/components/typography/H5.js.map +1 -1
- package/lib/module/components/typography/H6.js +0 -1
- package/lib/module/components/typography/H6.js.map +1 -1
- package/lib/module/components/typography/Hero.js +1 -5
- package/lib/module/components/typography/Hero.js.map +1 -1
- package/lib/module/components/typography/IOText.js +6 -2
- package/lib/module/components/typography/IOText.js.map +1 -1
- package/lib/module/components/typography/LabelMini.js +2 -9
- package/lib/module/components/typography/LabelMini.js.map +1 -1
- package/lib/module/components/typography/markdown/MdH1.js +1 -5
- package/lib/module/components/typography/markdown/MdH1.js.map +1 -1
- package/lib/module/components/typography/markdown/MdH2.js +1 -5
- package/lib/module/components/typography/markdown/MdH2.js.map +1 -1
- package/lib/module/components/typography/markdown/MdH3.js +1 -5
- package/lib/module/components/typography/markdown/MdH3.js.map +1 -1
- package/lib/typescript/components/badge/Badge.d.ts.map +1 -1
- package/lib/typescript/components/banner/Banner.d.ts.map +1 -1
- package/lib/typescript/components/buttons/IOButton/IOButton.d.ts.map +1 -1
- package/lib/typescript/components/headers/HeaderSecondLevel.d.ts.map +1 -1
- package/lib/typescript/components/listitems/ListItemInfo.d.ts +29 -0
- package/lib/typescript/components/listitems/ListItemInfo.d.ts.map +1 -1
- package/lib/typescript/components/loadingSpinner/LoadingSpinner.d.ts +2 -3
- package/lib/typescript/components/loadingSpinner/LoadingSpinner.d.ts.map +1 -1
- package/lib/typescript/components/modules/ModuleIDP.d.ts.map +1 -1
- package/lib/typescript/components/numberpad/NumberButton.d.ts.map +1 -1
- package/lib/typescript/components/searchInput/SearchInput.d.ts.map +1 -1
- package/lib/typescript/components/tabs/TabItem.d.ts.map +1 -1
- package/lib/typescript/components/tag/Tag.d.ts.map +1 -1
- package/lib/typescript/components/typography/Body.d.ts.map +1 -1
- package/lib/typescript/components/typography/BodySmall.d.ts.map +1 -1
- package/lib/typescript/components/typography/ButtonText.d.ts.map +1 -1
- package/lib/typescript/components/typography/Caption.d.ts.map +1 -1
- package/lib/typescript/components/typography/H1.d.ts.map +1 -1
- package/lib/typescript/components/typography/H2.d.ts.map +1 -1
- package/lib/typescript/components/typography/H3.d.ts.map +1 -1
- package/lib/typescript/components/typography/H4.d.ts.map +1 -1
- package/lib/typescript/components/typography/H5.d.ts.map +1 -1
- package/lib/typescript/components/typography/H6.d.ts.map +1 -1
- package/lib/typescript/components/typography/Hero.d.ts.map +1 -1
- package/lib/typescript/components/typography/IOText.d.ts.map +1 -1
- package/lib/typescript/components/typography/LabelMini.d.ts.map +1 -1
- package/lib/typescript/components/typography/markdown/MdH1.d.ts.map +1 -1
- package/lib/typescript/components/typography/markdown/MdH2.d.ts.map +1 -1
- package/lib/typescript/components/typography/markdown/MdH3.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/badge/Badge.tsx +1 -3
- package/src/components/banner/Banner.tsx +1 -3
- package/src/components/buttons/IOButton/IOButton.tsx +0 -3
- package/src/components/claimsSelector/__test__/__snapshots__/ClaimsSelector.test.tsx.snap +7 -5
- package/src/components/headers/HeaderSecondLevel.tsx +1 -4
- package/src/components/listitems/ListItemInfo.tsx +124 -49
- package/src/components/listitems/__test__/__snapshots__/listitem.test.tsx.snap +6 -4
- package/src/components/loadingSpinner/LoadingSpinner.tsx +26 -33
- package/src/components/modules/ModuleIDP.tsx +1 -3
- package/src/components/numberpad/NumberButton.tsx +1 -3
- package/src/components/searchInput/SearchInput.tsx +0 -1
- package/src/components/tabs/TabItem.tsx +2 -8
- package/src/components/tag/Tag.tsx +1 -3
- package/src/components/typography/Body.tsx +3 -8
- package/src/components/typography/BodySmall.tsx +2 -7
- package/src/components/typography/ButtonText.tsx +2 -7
- package/src/components/typography/Caption.tsx +1 -3
- package/src/components/typography/H1.tsx +1 -3
- package/src/components/typography/H2.tsx +1 -3
- package/src/components/typography/H3.tsx +1 -3
- package/src/components/typography/H4.tsx +1 -3
- package/src/components/typography/H5.tsx +1 -3
- package/src/components/typography/H6.tsx +0 -1
- package/src/components/typography/Hero.tsx +1 -3
- package/src/components/typography/IOText.tsx +16 -3
- package/src/components/typography/LabelMini.tsx +3 -8
- package/src/components/typography/markdown/MdH1.tsx +1 -3
- package/src/components/typography/markdown/MdH2.tsx +1 -3
- package/src/components/typography/markdown/MdH3.tsx +1 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode } from "react";
|
|
2
|
-
import { AccessibilityRole,
|
|
2
|
+
import { AccessibilityRole, Pressable, View } from "react-native";
|
|
3
3
|
import Animated from "react-native-reanimated";
|
|
4
4
|
import { useIOTheme } from "../../context";
|
|
5
5
|
import { IOListItemStyles, IOListItemVisualParams } from "../../core";
|
|
@@ -35,14 +35,8 @@ type EndElementProps =
|
|
|
35
35
|
| BadgeProps;
|
|
36
36
|
|
|
37
37
|
type GraphicProps =
|
|
38
|
-
| {
|
|
39
|
-
|
|
40
|
-
icon?: never;
|
|
41
|
-
}
|
|
42
|
-
| {
|
|
43
|
-
paymentLogoIcon?: never;
|
|
44
|
-
icon?: IOIcons;
|
|
45
|
-
};
|
|
38
|
+
| { paymentLogoIcon?: IOLogoPaymentType; icon?: never }
|
|
39
|
+
| { paymentLogoIcon?: never; icon?: IOIcons };
|
|
46
40
|
|
|
47
41
|
type InteractiveProps = Pick<
|
|
48
42
|
ComponentProps<typeof Pressable>,
|
|
@@ -55,7 +49,6 @@ export type ListItemInfo = WithTestID<{
|
|
|
55
49
|
numberOfLines?: number;
|
|
56
50
|
endElement?: EndElementProps;
|
|
57
51
|
topElement?: BadgeProps;
|
|
58
|
-
// Accessibility
|
|
59
52
|
accessibilityLabel?: string;
|
|
60
53
|
accessibilityRole?: AccessibilityRole;
|
|
61
54
|
reversed?: boolean;
|
|
@@ -72,16 +65,16 @@ const EndElementComponent = ({ type, componentProps }: EndElementProps) => {
|
|
|
72
65
|
<IOButton
|
|
73
66
|
variant="link"
|
|
74
67
|
{...componentProps}
|
|
75
|
-
accessibilityLabel={
|
|
68
|
+
accessibilityLabel={
|
|
76
69
|
componentProps.accessibilityLabel ?? componentProps.label
|
|
77
|
-
}
|
|
70
|
+
}
|
|
78
71
|
/>
|
|
79
72
|
);
|
|
80
73
|
case "iconButton":
|
|
81
74
|
return (
|
|
82
75
|
<IconButton
|
|
83
76
|
{...componentProps}
|
|
84
|
-
accessibilityLabel={
|
|
77
|
+
accessibilityLabel={componentProps.accessibilityLabel}
|
|
85
78
|
/>
|
|
86
79
|
);
|
|
87
80
|
case "badge":
|
|
@@ -99,7 +92,9 @@ const ListItemInfoContent = ({
|
|
|
99
92
|
numberOfLines,
|
|
100
93
|
reversed,
|
|
101
94
|
topElement,
|
|
102
|
-
endElement
|
|
95
|
+
endElement,
|
|
96
|
+
hasInteractiveElements,
|
|
97
|
+
listItemAccessibilityLabel
|
|
103
98
|
}: Pick<
|
|
104
99
|
ListItemInfo,
|
|
105
100
|
| "icon"
|
|
@@ -110,7 +105,10 @@ const ListItemInfoContent = ({
|
|
|
110
105
|
| "reversed"
|
|
111
106
|
| "topElement"
|
|
112
107
|
| "endElement"
|
|
113
|
-
>
|
|
108
|
+
> & {
|
|
109
|
+
hasInteractiveElements: boolean;
|
|
110
|
+
listItemAccessibilityLabel?: string;
|
|
111
|
+
}) => {
|
|
114
112
|
const theme = useIOTheme();
|
|
115
113
|
const { hugeFontEnabled } = useIOFontDynamicScale();
|
|
116
114
|
|
|
@@ -124,15 +122,23 @@ const ListItemInfoContent = ({
|
|
|
124
122
|
size={IOListItemVisualParams.iconSize}
|
|
125
123
|
/>
|
|
126
124
|
)}
|
|
125
|
+
|
|
127
126
|
{paymentLogoIcon && (
|
|
128
127
|
<LogoPaymentWithFallback
|
|
129
128
|
brand={paymentLogoIcon}
|
|
130
129
|
size={PAYMENT_LOGO_SIZE}
|
|
131
130
|
/>
|
|
132
131
|
)}
|
|
132
|
+
|
|
133
133
|
<View style={{ flex: 1 }}>
|
|
134
134
|
<View
|
|
135
|
-
accessible={
|
|
135
|
+
accessible={hasInteractiveElements}
|
|
136
|
+
accessibilityLabel={
|
|
137
|
+
hasInteractiveElements ? listItemAccessibilityLabel : undefined
|
|
138
|
+
}
|
|
139
|
+
importantForAccessibility={
|
|
140
|
+
hasInteractiveElements ? "yes" : "no-hide-descendants"
|
|
141
|
+
}
|
|
136
142
|
style={{ flexDirection: reversed ? "column-reverse" : "column" }}
|
|
137
143
|
>
|
|
138
144
|
{topElement?.type === "badge" && (
|
|
@@ -141,11 +147,13 @@ const ListItemInfoContent = ({
|
|
|
141
147
|
<VSpacer size={4} />
|
|
142
148
|
</View>
|
|
143
149
|
)}
|
|
150
|
+
|
|
144
151
|
{label && (
|
|
145
152
|
<BodySmall weight="Regular" color={theme["textBody-tertiary"]}>
|
|
146
153
|
{label}
|
|
147
154
|
</BodySmall>
|
|
148
155
|
)}
|
|
156
|
+
|
|
149
157
|
{typeof value === "string" ? (
|
|
150
158
|
<H6 color={theme["textBody-default"]} numberOfLines={numberOfLines}>
|
|
151
159
|
{value}
|
|
@@ -155,8 +163,14 @@ const ListItemInfoContent = ({
|
|
|
155
163
|
)}
|
|
156
164
|
</View>
|
|
157
165
|
</View>
|
|
166
|
+
|
|
158
167
|
{endElement && (
|
|
159
|
-
<View
|
|
168
|
+
<View
|
|
169
|
+
accessible={false}
|
|
170
|
+
importantForAccessibility={
|
|
171
|
+
hasInteractiveElements ? "auto" : "no-hide-descendants"
|
|
172
|
+
}
|
|
173
|
+
>
|
|
160
174
|
<EndElementComponent {...endElement} />
|
|
161
175
|
</View>
|
|
162
176
|
)}
|
|
@@ -164,6 +178,35 @@ const ListItemInfoContent = ({
|
|
|
164
178
|
);
|
|
165
179
|
};
|
|
166
180
|
|
|
181
|
+
/**
|
|
182
|
+
* ListItemInfo component displays information in a list item format with optional icons,
|
|
183
|
+
* labels, values, and end elements (buttons, badges).
|
|
184
|
+
*
|
|
185
|
+
* @remarks
|
|
186
|
+
* **Accessibility for Interactive Elements:**
|
|
187
|
+
* When using interactive end elements (`buttonLink` or `iconButton`), you must provide
|
|
188
|
+
* an appropriate `accessibilityLabel` directly to the interactive component props.
|
|
189
|
+
* This ensures that screen reader users can understand the relationship between the
|
|
190
|
+
* list item content and the action that the interactive element triggers.
|
|
191
|
+
*
|
|
192
|
+
* Example:
|
|
193
|
+
* ```tsx
|
|
194
|
+
* <ListItemInfo
|
|
195
|
+
* label="Email"
|
|
196
|
+
* value="user@example.com"
|
|
197
|
+
* endElement={{
|
|
198
|
+
* type: "buttonLink",
|
|
199
|
+
* componentProps: {
|
|
200
|
+
* label: "Edit",
|
|
201
|
+
* accessibilityLabel: "Edit email address"
|
|
202
|
+
* }
|
|
203
|
+
* }}
|
|
204
|
+
* />
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* The design system cannot enforce this pattern automatically, so it's the responsibility
|
|
208
|
+
* of the implementing software engineer to ensure proper accessibility labels are set.
|
|
209
|
+
*/
|
|
167
210
|
export const ListItemInfo = ({
|
|
168
211
|
value,
|
|
169
212
|
label,
|
|
@@ -185,13 +228,41 @@ export const ListItemInfo = ({
|
|
|
185
228
|
const { onPressIn, onPressOut, scaleAnimatedStyle, backgroundAnimatedStyle } =
|
|
186
229
|
useListItemAnimation();
|
|
187
230
|
|
|
231
|
+
/**
|
|
232
|
+
* A11Y Support: Two different combinations based on interactive elements
|
|
233
|
+
*
|
|
234
|
+
* 1. NO interactive elements (or just badge):
|
|
235
|
+
* - The outer container is accessible and receives the complete accessibility label
|
|
236
|
+
* - This allows the entire list item to be treated as a single accessibility element
|
|
237
|
+
*
|
|
238
|
+
* 2. WITH interactive elements (buttonLink or iconButton):
|
|
239
|
+
* - The outer container is NOT accessible
|
|
240
|
+
* - The inner content becomes accessible with its label
|
|
241
|
+
* - The interactive element is separately accessible with its own label
|
|
242
|
+
* - This allows screen readers to navigate between the content and the action separately
|
|
243
|
+
*/
|
|
244
|
+
const hasInteractiveElements =
|
|
245
|
+
endElement?.type === "buttonLink" || endElement?.type === "iconButton";
|
|
246
|
+
|
|
188
247
|
const componentValueToAccessibility = typeof value === "string" ? value : "";
|
|
189
248
|
|
|
249
|
+
const topBadgeText =
|
|
250
|
+
topElement?.type === "badge" ? topElement.componentProps.text ?? "" : "";
|
|
251
|
+
|
|
252
|
+
const endBadgeText =
|
|
253
|
+
endElement?.type === "badge" ? endElement.componentProps.text ?? "" : "";
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Build text in VISUAL ORDER
|
|
257
|
+
*/
|
|
258
|
+
const mainTextParts = reversed
|
|
259
|
+
? [componentValueToAccessibility, label]
|
|
260
|
+
: [label, componentValueToAccessibility];
|
|
261
|
+
|
|
262
|
+
const textParts = [topBadgeText, ...mainTextParts, endBadgeText];
|
|
263
|
+
|
|
190
264
|
const listItemAccessibilityLabel =
|
|
191
|
-
accessibilityLabel ??
|
|
192
|
-
(label
|
|
193
|
-
? `${label}; ${componentValueToAccessibility}`
|
|
194
|
-
: componentValueToAccessibility);
|
|
265
|
+
accessibilityLabel ?? textParts.filter(Boolean).join("; ");
|
|
195
266
|
|
|
196
267
|
const contentProps = {
|
|
197
268
|
icon,
|
|
@@ -201,7 +272,9 @@ export const ListItemInfo = ({
|
|
|
201
272
|
numberOfLines,
|
|
202
273
|
reversed,
|
|
203
274
|
topElement,
|
|
204
|
-
endElement
|
|
275
|
+
endElement,
|
|
276
|
+
hasInteractiveElements,
|
|
277
|
+
listItemAccessibilityLabel
|
|
205
278
|
} as const;
|
|
206
279
|
|
|
207
280
|
if (onLongPress) {
|
|
@@ -209,14 +282,14 @@ export const ListItemInfo = ({
|
|
|
209
282
|
<Pressable
|
|
210
283
|
onLongPress={onLongPress}
|
|
211
284
|
testID={testID}
|
|
212
|
-
accessible
|
|
213
|
-
|
|
214
|
-
onPressOut={onPressOut}
|
|
215
|
-
onTouchEnd={onPressOut}
|
|
216
|
-
accessibilityRole={"button"}
|
|
285
|
+
accessible
|
|
286
|
+
accessibilityRole="button"
|
|
217
287
|
accessibilityLabel={listItemAccessibilityLabel}
|
|
218
288
|
accessibilityActions={accessibilityActions}
|
|
219
289
|
onAccessibilityAction={onAccessibilityAction}
|
|
290
|
+
onPressIn={onPressIn}
|
|
291
|
+
onPressOut={onPressOut}
|
|
292
|
+
onTouchEnd={onPressOut}
|
|
220
293
|
>
|
|
221
294
|
<Animated.View
|
|
222
295
|
style={[IOListItemStyles.listItem, backgroundAnimatedStyle]}
|
|
@@ -238,29 +311,31 @@ export const ListItemInfo = ({
|
|
|
238
311
|
</Animated.View>
|
|
239
312
|
</Pressable>
|
|
240
313
|
);
|
|
241
|
-
}
|
|
242
|
-
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<View
|
|
318
|
+
style={IOListItemStyles.listItem}
|
|
319
|
+
testID={testID}
|
|
320
|
+
accessible={!hasInteractiveElements}
|
|
321
|
+
accessibilityLabel={
|
|
322
|
+
hasInteractiveElements ? undefined : listItemAccessibilityLabel
|
|
323
|
+
}
|
|
324
|
+
accessibilityRole={hasInteractiveElements ? undefined : accessibilityRole}
|
|
325
|
+
>
|
|
243
326
|
<View
|
|
244
|
-
style={
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
327
|
+
style={[
|
|
328
|
+
IOListItemStyles.listItemInner,
|
|
329
|
+
{
|
|
330
|
+
columnGap:
|
|
331
|
+
IOListItemVisualParams.iconMargin *
|
|
332
|
+
dynamicFontScale *
|
|
333
|
+
spacingScaleMultiplier
|
|
334
|
+
}
|
|
335
|
+
]}
|
|
249
336
|
>
|
|
250
|
-
<
|
|
251
|
-
style={[
|
|
252
|
-
IOListItemStyles.listItemInner,
|
|
253
|
-
{
|
|
254
|
-
columnGap:
|
|
255
|
-
IOListItemVisualParams.iconMargin *
|
|
256
|
-
dynamicFontScale *
|
|
257
|
-
spacingScaleMultiplier
|
|
258
|
-
}
|
|
259
|
-
]}
|
|
260
|
-
>
|
|
261
|
-
<ListItemInfoContent {...contentProps} />
|
|
262
|
-
</View>
|
|
337
|
+
<ListItemInfoContent {...contentProps} />
|
|
263
338
|
</View>
|
|
264
|
-
|
|
265
|
-
|
|
339
|
+
</View>
|
|
340
|
+
);
|
|
266
341
|
};
|
|
@@ -190,7 +190,8 @@ exports[`Test List Item Components - Experimental Enabled ListItemInfo Snapshot
|
|
|
190
190
|
}
|
|
191
191
|
>
|
|
192
192
|
<View
|
|
193
|
-
accessible={
|
|
193
|
+
accessible={false}
|
|
194
|
+
importantForAccessibility="no-hide-descendants"
|
|
194
195
|
style={
|
|
195
196
|
{
|
|
196
197
|
"flexDirection": "column",
|
|
@@ -1379,7 +1380,7 @@ exports[`Test List Item Components - Experimental Enabled ListItemRadioWithAmou
|
|
|
1379
1380
|
<RNSVGPath
|
|
1380
1381
|
d="m7 12 4 4 7-7"
|
|
1381
1382
|
fill={null}
|
|
1382
|
-
|
|
1383
|
+
onSvgLayout={[Function]}
|
|
1383
1384
|
propList={
|
|
1384
1385
|
[
|
|
1385
1386
|
"fill",
|
|
@@ -2308,7 +2309,8 @@ exports[`Test List Item Components ListItemInfo Snapshot 1`] = `
|
|
|
2308
2309
|
}
|
|
2309
2310
|
>
|
|
2310
2311
|
<View
|
|
2311
|
-
accessible={
|
|
2312
|
+
accessible={false}
|
|
2313
|
+
importantForAccessibility="no-hide-descendants"
|
|
2312
2314
|
style={
|
|
2313
2315
|
{
|
|
2314
2316
|
"flexDirection": "column",
|
|
@@ -3497,7 +3499,7 @@ exports[`Test List Item Components ListItemRadioWithAmount Snapshot 1`] = `
|
|
|
3497
3499
|
<RNSVGPath
|
|
3498
3500
|
d="m7 12 4 4 7-7"
|
|
3499
3501
|
fill={null}
|
|
3500
|
-
|
|
3502
|
+
onSvgLayout={[Function]}
|
|
3501
3503
|
propList={
|
|
3502
3504
|
[
|
|
3503
3505
|
"fill",
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { ReactElement,
|
|
1
|
+
import { ReactElement, useId } from "react";
|
|
2
2
|
import { ColorValue, View } from "react-native";
|
|
3
|
-
import Animated
|
|
4
|
-
Easing,
|
|
5
|
-
useAnimatedStyle,
|
|
6
|
-
useSharedValue,
|
|
7
|
-
withRepeat,
|
|
8
|
-
withTiming
|
|
9
|
-
} from "react-native-reanimated";
|
|
3
|
+
import Animated from "react-native-reanimated";
|
|
10
4
|
import Svg, { Defs, G, LinearGradient, Path, Stop } from "react-native-svg";
|
|
11
5
|
import { useIOTheme } from "../../context";
|
|
12
6
|
import { IOColors } from "../../core/IOColors";
|
|
@@ -21,15 +15,18 @@ export type LoadingSpinner = WithTestID<{
|
|
|
21
15
|
}>;
|
|
22
16
|
|
|
23
17
|
/**
|
|
24
|
-
* Size scale
|
|
25
|
-
* It will be removed in the future.
|
|
18
|
+
* Size scale
|
|
26
19
|
*/
|
|
27
|
-
export type IOLoadingSpinnerSizeScale = 24 | 48
|
|
20
|
+
export type IOLoadingSpinnerSizeScale = 24 | 48;
|
|
28
21
|
|
|
29
|
-
const
|
|
22
|
+
const spinKeyframes = {
|
|
23
|
+
from: { transform: [{ rotateZ: "0deg" }] },
|
|
24
|
+
to: { transform: [{ rotateZ: "360deg" }] }
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const strokeMap: Record<IOLoadingSpinnerSizeScale, number> = {
|
|
30
28
|
24: 3,
|
|
31
|
-
48: 5
|
|
32
|
-
76: 7
|
|
29
|
+
48: 5
|
|
33
30
|
};
|
|
34
31
|
|
|
35
32
|
export const LoadingSpinner = ({
|
|
@@ -41,23 +38,13 @@ export const LoadingSpinner = ({
|
|
|
41
38
|
testID = "LoadingSpinnerTestID"
|
|
42
39
|
}: LoadingSpinner): ReactElement => {
|
|
43
40
|
const theme = useIOTheme();
|
|
44
|
-
const
|
|
45
|
-
const stroke
|
|
41
|
+
const id = useId();
|
|
42
|
+
const stroke = strokeMap[size];
|
|
46
43
|
|
|
47
44
|
const color = customColor ?? IOColors[theme["interactiveElem-default"]];
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
rotation.value = withRepeat(
|
|
52
|
-
withTiming(360, { duration: durationMs, easing: Easing.linear }),
|
|
53
|
-
-1,
|
|
54
|
-
false
|
|
55
|
-
);
|
|
56
|
-
}, [durationMs, rotation]);
|
|
57
|
-
|
|
58
|
-
const animatedStyle = useAnimatedStyle(() => ({
|
|
59
|
-
transform: [{ rotateZ: `${rotation.value}deg` }]
|
|
60
|
-
}));
|
|
46
|
+
const secondHalfId = `${id}-secondHalf`;
|
|
47
|
+
const firstHalfId = `${id}-firstHalf`;
|
|
61
48
|
|
|
62
49
|
return (
|
|
63
50
|
<View
|
|
@@ -70,7 +57,13 @@ export const LoadingSpinner = ({
|
|
|
70
57
|
>
|
|
71
58
|
<Animated.View
|
|
72
59
|
testID={"LoadingSpinnerAnimatedTestID"}
|
|
73
|
-
style={
|
|
60
|
+
style={{
|
|
61
|
+
animationName: spinKeyframes,
|
|
62
|
+
animationDuration: durationMs,
|
|
63
|
+
animationIterationCount: "infinite",
|
|
64
|
+
animationTimingFunction: "linear",
|
|
65
|
+
transformOrigin: "center"
|
|
66
|
+
}}
|
|
74
67
|
>
|
|
75
68
|
{/* Thanks to Ben Ilegbodu for the article on how to
|
|
76
69
|
create a a SVG gradient loading spinner. Below is
|
|
@@ -83,11 +76,11 @@ export const LoadingSpinner = ({
|
|
|
83
76
|
fill="none"
|
|
84
77
|
>
|
|
85
78
|
<Defs>
|
|
86
|
-
<LinearGradient id=
|
|
79
|
+
<LinearGradient id={secondHalfId}>
|
|
87
80
|
<Stop offset="0%" stopOpacity="0" stopColor={color} />
|
|
88
81
|
<Stop offset="100%" stopOpacity="1" stopColor={color} />
|
|
89
82
|
</LinearGradient>
|
|
90
|
-
<LinearGradient id=
|
|
83
|
+
<LinearGradient id={firstHalfId}>
|
|
91
84
|
<Stop offset="0%" stopOpacity="1" stopColor={color} />
|
|
92
85
|
<Stop offset="100%" stopOpacity="1" stopColor={color} />
|
|
93
86
|
</LinearGradient>
|
|
@@ -95,13 +88,13 @@ export const LoadingSpinner = ({
|
|
|
95
88
|
|
|
96
89
|
<G strokeWidth={stroke}>
|
|
97
90
|
<Path
|
|
98
|
-
stroke=
|
|
91
|
+
stroke={`url(#${secondHalfId})`}
|
|
99
92
|
d={`M ${stroke / 2} ${size / 2} A ${size / 2 - stroke / 2} ${
|
|
100
93
|
size / 2 - stroke / 2
|
|
101
94
|
} 0 0 1 ${size - stroke / 2} ${size / 2}`}
|
|
102
95
|
/>
|
|
103
96
|
<Path
|
|
104
|
-
stroke=
|
|
97
|
+
stroke={`url(#${firstHalfId})`}
|
|
105
98
|
d={`M ${size - stroke / 2} ${size / 2} A ${
|
|
106
99
|
size / 2 - stroke / 2
|
|
107
100
|
} ${size / 2 - stroke / 2} 0 0 1 ${stroke / 2} ${size / 2}`}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Image, ImageSourcePropType, StyleSheet } from "react-native";
|
|
2
|
-
import {
|
|
2
|
+
import { useIOThemeContext, useIOTheme } from "../../context";
|
|
3
3
|
import { IOListItemLogoMargin } from "../../core";
|
|
4
4
|
import { addCacheTimestampToUri } from "../../utils/image";
|
|
5
5
|
import { IOText } from "../typography";
|
|
@@ -49,7 +49,6 @@ export const ModuleIDP = ({
|
|
|
49
49
|
testID,
|
|
50
50
|
accessibilityLabel
|
|
51
51
|
}: ModuleIDP) => {
|
|
52
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
53
52
|
const theme = useIOTheme();
|
|
54
53
|
const IDPLogoSource = useIDPLogo(logo);
|
|
55
54
|
|
|
@@ -60,7 +59,6 @@ export const ModuleIDP = ({
|
|
|
60
59
|
withLooseSpacing={withLooseSpacing}
|
|
61
60
|
>
|
|
62
61
|
<IOText
|
|
63
|
-
font={newTypefaceEnabled ? "Titillio" : "TitilliumSansPro"}
|
|
64
62
|
weight={"Semibold"}
|
|
65
63
|
size={12}
|
|
66
64
|
lineHeight={16}
|
|
@@ -6,7 +6,7 @@ import Animated, {
|
|
|
6
6
|
useAnimatedStyle,
|
|
7
7
|
useReducedMotion
|
|
8
8
|
} from "react-native-reanimated";
|
|
9
|
-
import {
|
|
9
|
+
import { useIOTheme } from "../../context";
|
|
10
10
|
import { hexToRgba, IOColors } from "../../core";
|
|
11
11
|
import { useScaleAnimation } from "../../hooks";
|
|
12
12
|
import { IOText } from "../typography";
|
|
@@ -50,7 +50,6 @@ export const NumberButton = memo(
|
|
|
50
50
|
const { progress, onPressIn, onPressOut, scaleAnimatedStyle } =
|
|
51
51
|
useScaleAnimation("medium");
|
|
52
52
|
const reducedMotion = useReducedMotion();
|
|
53
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
54
53
|
|
|
55
54
|
const colorMap: Record<NumberButtonVariantType, ColorMapVariant> = useMemo(
|
|
56
55
|
() => ({
|
|
@@ -103,7 +102,6 @@ export const NumberButton = memo(
|
|
|
103
102
|
>
|
|
104
103
|
<IOText
|
|
105
104
|
size={22}
|
|
106
|
-
font={newTypefaceEnabled ? "Titillio" : "TitilliumSansPro"}
|
|
107
105
|
weight="Semibold"
|
|
108
106
|
color={colorMap[variant].foreground}
|
|
109
107
|
style={{
|
|
@@ -307,7 +307,6 @@ export const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
|
|
|
307
307
|
>
|
|
308
308
|
<IOText
|
|
309
309
|
color={theme["interactiveElem-default"]}
|
|
310
|
-
font={newTypefaceEnabled ? "Titillio" : "TitilliumSansPro"}
|
|
311
310
|
weight={"Semibold"}
|
|
312
311
|
size={buttonTextFontSize}
|
|
313
312
|
lineHeight={buttonTextLineHeight}
|
|
@@ -13,7 +13,7 @@ import Animated, {
|
|
|
13
13
|
useReducedMotion,
|
|
14
14
|
withSpring
|
|
15
15
|
} from "react-native-reanimated";
|
|
16
|
-
import {
|
|
16
|
+
import { useIOTheme } from "../../context";
|
|
17
17
|
import { IOColors, IOSpringValues, hexToRgba } from "../../core";
|
|
18
18
|
import { useScaleAnimation } from "../../hooks";
|
|
19
19
|
import { WithTestID } from "../../utils/types";
|
|
@@ -77,7 +77,6 @@ const TabItem = forwardRef(
|
|
|
77
77
|
useScaleAnimation("medium");
|
|
78
78
|
const theme = useIOTheme();
|
|
79
79
|
const reducedMotion = useReducedMotion();
|
|
80
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
81
80
|
|
|
82
81
|
const mapColorStates: Record<
|
|
83
82
|
NonNullable<TabItem["color"]>,
|
|
@@ -199,12 +198,7 @@ const TabItem = forwardRef(
|
|
|
199
198
|
{activeIcon && (
|
|
200
199
|
<Icon name={activeIcon} color={foregroundColor} size={16} />
|
|
201
200
|
)}
|
|
202
|
-
<IOText
|
|
203
|
-
size={14}
|
|
204
|
-
font={newTypefaceEnabled ? "Titillio" : "TitilliumSansPro"}
|
|
205
|
-
weight="Semibold"
|
|
206
|
-
color={foregroundColor}
|
|
207
|
-
>
|
|
201
|
+
<IOText size={14} weight="Semibold" color={foregroundColor}>
|
|
208
202
|
{label}
|
|
209
203
|
</IOText>
|
|
210
204
|
</Animated.View>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Platform, StyleSheet, View, ViewStyle } from "react-native";
|
|
2
|
-
import {
|
|
2
|
+
import { useIOTheme } from "../../context";
|
|
3
3
|
import {
|
|
4
4
|
IOColors,
|
|
5
5
|
IOSpacingScale,
|
|
@@ -155,7 +155,6 @@ export const Tag = ({
|
|
|
155
155
|
forceLightMode = false
|
|
156
156
|
}: Tag) => {
|
|
157
157
|
const theme = useIOTheme();
|
|
158
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
159
158
|
const { dynamicFontScale, spacingScaleMultiplier } = useIOFontDynamicScale();
|
|
160
159
|
|
|
161
160
|
const variantProps = getVariantProps(variant, icon);
|
|
@@ -203,7 +202,6 @@ export const Tag = ({
|
|
|
203
202
|
{text && (
|
|
204
203
|
<IOText
|
|
205
204
|
allowFontScaling={allowFontScaling}
|
|
206
|
-
font={newTypefaceEnabled ? "Titillio" : "TitilliumSansPro"}
|
|
207
205
|
weight={"Semibold"}
|
|
208
206
|
size={12}
|
|
209
207
|
lineHeight={16}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ForwardedRef, forwardRef } from "react";
|
|
2
2
|
import { Pressable, View } from "react-native";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { useIOTheme } from "../../context";
|
|
4
|
+
import { IOFontWeight } from "../../utils/fonts";
|
|
5
5
|
import {
|
|
6
6
|
IOText,
|
|
7
7
|
IOTextProps,
|
|
@@ -16,9 +16,6 @@ type BodyStyleProps = TypographicStyleProps & {
|
|
|
16
16
|
export const bodyFontSize = 16;
|
|
17
17
|
export const bodyLineHeight = 24;
|
|
18
18
|
|
|
19
|
-
const fontName: IOFontFamily = "Titillio";
|
|
20
|
-
const legacyFontName: IOFontFamily = "TitilliumSansPro";
|
|
21
|
-
|
|
22
19
|
/**
|
|
23
20
|
* `Body` typographic style
|
|
24
21
|
*/
|
|
@@ -37,7 +34,6 @@ export const Body = forwardRef<View, BodyStyleProps>(
|
|
|
37
34
|
ref?: ForwardedRef<View>
|
|
38
35
|
) => {
|
|
39
36
|
const theme = useIOTheme();
|
|
40
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
41
37
|
|
|
42
38
|
const defaultColor = asLink
|
|
43
39
|
? theme["interactiveElem-default"]
|
|
@@ -46,8 +42,7 @@ export const Body = forwardRef<View, BodyStyleProps>(
|
|
|
46
42
|
const BodyProps: IOTextProps = {
|
|
47
43
|
...props,
|
|
48
44
|
dynamicTypeRamp: "body", // iOS only
|
|
49
|
-
|
|
50
|
-
weight: customWeight ? customWeight : "Regular",
|
|
45
|
+
weight: customWeight || "Regular",
|
|
51
46
|
size: bodyFontSize,
|
|
52
47
|
lineHeight: bodyLineHeight,
|
|
53
48
|
color: customColor ?? defaultColor,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ForwardedRef, forwardRef } from "react";
|
|
2
2
|
import { Pressable, View } from "react-native";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { useIOTheme } from "../../context";
|
|
4
|
+
import { IOFontWeight } from "../../utils/fonts";
|
|
5
5
|
import {
|
|
6
6
|
IOText,
|
|
7
7
|
IOTextProps,
|
|
@@ -13,9 +13,6 @@ type BodySmallProps = TypographicStyleProps & {
|
|
|
13
13
|
weight?: Extract<IOFontWeight, "Regular" | "Semibold">;
|
|
14
14
|
} & TypographicStyleAsLinkProps;
|
|
15
15
|
|
|
16
|
-
const fontName: IOFontFamily = "Titillio";
|
|
17
|
-
const legacyFontName: IOFontFamily = "TitilliumSansPro";
|
|
18
|
-
|
|
19
16
|
/**
|
|
20
17
|
* `BodySmall` typographic style
|
|
21
18
|
*/
|
|
@@ -34,7 +31,6 @@ export const BodySmall = forwardRef<View, BodySmallProps>(
|
|
|
34
31
|
ref?: ForwardedRef<View>
|
|
35
32
|
) => {
|
|
36
33
|
const theme = useIOTheme();
|
|
37
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
38
34
|
|
|
39
35
|
const defaultColor = asLink
|
|
40
36
|
? theme["interactiveElem-default"]
|
|
@@ -43,7 +39,6 @@ export const BodySmall = forwardRef<View, BodySmallProps>(
|
|
|
43
39
|
const BodySmallProps: IOTextProps = {
|
|
44
40
|
...props,
|
|
45
41
|
dynamicTypeRamp: "footnote" /* iOS only */,
|
|
46
|
-
font: newTypefaceEnabled ? fontName : legacyFontName,
|
|
47
42
|
weight: customWeight ?? "Regular",
|
|
48
43
|
size: 14,
|
|
49
44
|
lineHeight: 21,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ForwardedRef, forwardRef } from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import { IOColors } from "../../core";
|
|
5
|
-
import {
|
|
5
|
+
import { IOFontSize } from "../../utils/fonts";
|
|
6
6
|
import { IOText, IOTextProps, TypographicStyleProps } from "./IOText";
|
|
7
7
|
|
|
8
8
|
export const buttonTextFontSize: IOFontSize = 16;
|
|
@@ -11,19 +11,14 @@ export const buttonTextLineHeight = 20;
|
|
|
11
11
|
/* Needed to render `ButtonOutline` and`ButtonLink` because they use
|
|
12
12
|
`AnimatedText` for color transition through Reanimated */
|
|
13
13
|
const defaultColor: IOColors = "white";
|
|
14
|
-
const fontName: IOFontFamily = "Titillio";
|
|
15
|
-
const legacyFontName: IOFontFamily = "TitilliumSansPro";
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* `ButtonText` typographic style
|
|
19
17
|
*/
|
|
20
18
|
export const ButtonText = forwardRef<View, TypographicStyleProps>(
|
|
21
19
|
({ color: customColor, ...props }, ref?: ForwardedRef<View>) => {
|
|
22
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
23
|
-
|
|
24
20
|
const ButtonTextProps: IOTextProps = {
|
|
25
21
|
...props,
|
|
26
|
-
font: newTypefaceEnabled ? fontName : legacyFontName,
|
|
27
22
|
weight: "Semibold",
|
|
28
23
|
size: buttonTextFontSize,
|
|
29
24
|
lineHeight: buttonTextLineHeight,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ForwardedRef, forwardRef } from "react";
|
|
2
2
|
import { View } from "react-native";
|
|
3
|
-
import {
|
|
3
|
+
import { useIOTheme } from "../../context";
|
|
4
4
|
import { IOFontSize } from "../../utils/fonts";
|
|
5
5
|
import { IOText, IOTextProps, TypographicStyleProps } from "./IOText";
|
|
6
6
|
|
|
@@ -12,12 +12,10 @@ export const captionFontSize: IOFontSize = 12;
|
|
|
12
12
|
export const Caption = forwardRef<View, TypographicStyleProps>(
|
|
13
13
|
({ color: customColor, ...props }, ref?: ForwardedRef<View>) => {
|
|
14
14
|
const theme = useIOTheme();
|
|
15
|
-
const { newTypefaceEnabled } = useIONewTypeface();
|
|
16
15
|
|
|
17
16
|
const CaptionProps: IOTextProps = {
|
|
18
17
|
...props,
|
|
19
18
|
dynamicTypeRamp: "caption1", // iOS only
|
|
20
|
-
font: newTypefaceEnabled ? "Titillio" : "TitilliumSansPro",
|
|
21
19
|
weight: "Regular",
|
|
22
20
|
size: captionFontSize,
|
|
23
21
|
color: customColor ?? theme["textBody-default"],
|