@ledgerhq/lumen-ui-rnative 0.0.68 → 0.0.70
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/.storybook/mocks/blur.tsx +1 -2
- package/dist/package.json +2 -2
- package/dist/src/i18n/locales/de.json +4 -0
- package/dist/src/i18n/locales/en.json +4 -0
- package/dist/src/i18n/locales/es.json +4 -0
- package/dist/src/i18n/locales/fr.json +4 -0
- package/dist/src/i18n/locales/ja.json +4 -0
- package/dist/src/i18n/locales/ko.json +4 -0
- package/dist/src/i18n/locales/pt.json +4 -0
- package/dist/src/i18n/locales/ru.json +4 -0
- package/dist/src/i18n/locales/th.json +4 -0
- package/dist/src/i18n/locales/tr.json +4 -0
- package/dist/src/i18n/locales/zh.json +4 -0
- package/dist/src/lib/Components/Avatar/Avatar.d.ts +19 -0
- package/dist/src/lib/Components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/src/lib/Components/Avatar/Avatar.js +81 -0
- package/dist/src/lib/Components/Avatar/Avatar.stories.d.ts +22 -0
- package/dist/src/lib/Components/Avatar/Avatar.stories.d.ts.map +1 -0
- package/dist/src/lib/Components/Avatar/Avatar.stories.js +72 -0
- package/dist/src/lib/Components/Avatar/index.d.ts +3 -0
- package/dist/src/lib/Components/Avatar/index.d.ts.map +1 -0
- package/dist/src/lib/Components/Avatar/index.js +2 -0
- package/dist/src/lib/Components/Avatar/types.d.ts +26 -0
- package/dist/src/lib/Components/Avatar/types.d.ts.map +1 -0
- package/dist/src/lib/Components/Avatar/types.js +1 -0
- package/dist/src/lib/Components/CardButton/CardButton.js +3 -3
- package/dist/src/lib/Components/PageIndicator/PageIndicator.d.ts.map +1 -1
- package/dist/src/lib/Components/PageIndicator/PageIndicator.js +3 -2
- package/dist/src/lib/Components/PageIndicator/PageIndicator.stories.js +4 -4
- package/dist/src/lib/Components/PageIndicator/types.d.ts +1 -1
- package/dist/src/lib/Components/index.d.ts +1 -0
- package/dist/src/lib/Components/index.d.ts.map +1 -1
- package/dist/src/lib/Components/index.js +1 -0
- package/dist/src/lib/Symbols/Icons/Chart5.d.ts +35 -0
- package/dist/src/lib/Symbols/Icons/Chart5.d.ts.map +1 -0
- package/dist/src/lib/Symbols/Icons/Chart5.js +34 -0
- package/dist/src/lib/Symbols/Icons/Chart5Fill.d.ts +35 -0
- package/dist/src/lib/Symbols/Icons/Chart5Fill.d.ts.map +1 -0
- package/dist/src/lib/Symbols/Icons/Chart5Fill.js +34 -0
- package/dist/src/lib/Symbols/Icons/CurveDown.d.ts +35 -0
- package/dist/src/lib/Symbols/Icons/CurveDown.d.ts.map +1 -0
- package/dist/src/lib/Symbols/Icons/CurveDown.js +34 -0
- package/dist/src/lib/Symbols/Icons/CurveUp.d.ts +35 -0
- package/dist/src/lib/Symbols/Icons/CurveUp.d.ts.map +1 -0
- package/dist/src/lib/Symbols/Icons/CurveUp.js +34 -0
- package/dist/src/lib/Symbols/Icons/Target.d.ts +35 -0
- package/dist/src/lib/Symbols/Icons/Target.d.ts.map +1 -0
- package/dist/src/lib/Symbols/Icons/Target.js +34 -0
- package/dist/src/lib/Symbols/index.d.ts +5 -0
- package/dist/src/lib/Symbols/index.d.ts.map +1 -1
- package/dist/src/lib/Symbols/index.js +5 -0
- package/package.json +3 -3
- package/src/i18n/locales/de.json +4 -0
- package/src/i18n/locales/en.json +4 -0
- package/src/i18n/locales/es.json +4 -0
- package/src/i18n/locales/fr.json +4 -0
- package/src/i18n/locales/ja.json +4 -0
- package/src/i18n/locales/ko.json +4 -0
- package/src/i18n/locales/pt.json +4 -0
- package/src/i18n/locales/ru.json +4 -0
- package/src/i18n/locales/th.json +4 -0
- package/src/i18n/locales/tr.json +4 -0
- package/src/i18n/locales/zh.json +4 -0
- package/src/lib/Components/Avatar/Avatar.mdx +323 -0
- package/src/lib/Components/Avatar/Avatar.stories.tsx +127 -0
- package/src/lib/Components/Avatar/Avatar.test.tsx +215 -0
- package/src/lib/Components/Avatar/Avatar.tsx +132 -0
- package/src/lib/Components/Avatar/index.ts +2 -0
- package/src/lib/Components/Avatar/types.ts +26 -0
- package/src/lib/Components/CardButton/CardButton.tsx +3 -3
- package/src/lib/Components/PageIndicator/PageIndicator.mdx +7 -4
- package/src/lib/Components/PageIndicator/PageIndicator.stories.tsx +5 -5
- package/src/lib/Components/PageIndicator/PageIndicator.test.tsx +14 -14
- package/src/lib/Components/PageIndicator/PageIndicator.tsx +6 -2
- package/src/lib/Components/PageIndicator/types.ts +1 -1
- package/src/lib/Components/index.ts +1 -0
- package/src/lib/Symbols/Icons/Chart5.tsx +53 -0
- package/src/lib/Symbols/Icons/Chart5Fill.tsx +42 -0
- package/src/lib/Symbols/Icons/CurveDown.tsx +69 -0
- package/src/lib/Symbols/Icons/CurveUp.tsx +68 -0
- package/src/lib/Symbols/Icons/Target.tsx +45 -0
- package/src/lib/Symbols/index.ts +5 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
import { StyleSheet, Image, View } from 'react-native';
|
|
3
|
+
import { useCommonTranslation } from '../../../i18n';
|
|
4
|
+
import { useStyleSheet } from '../../../styles';
|
|
5
|
+
import { User } from '../../Symbols';
|
|
6
|
+
import { Box } from '../Utility';
|
|
7
|
+
import { AvatarProps } from './types';
|
|
8
|
+
|
|
9
|
+
type Size = NonNullable<AvatarProps['size']>;
|
|
10
|
+
|
|
11
|
+
const fallbackSizes = {
|
|
12
|
+
sm: 16,
|
|
13
|
+
md: 24,
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
const useStyles = ({ size }: { size: Size }) => {
|
|
17
|
+
return useStyleSheet(
|
|
18
|
+
(t) => {
|
|
19
|
+
const sizeMap = {
|
|
20
|
+
sm: { size: t.sizes.s40, padding: t.spacings.s4 },
|
|
21
|
+
md: { size: t.sizes.s48, padding: t.spacings.s4 },
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const notificationsMap = {
|
|
25
|
+
sm: t.sizes.s10,
|
|
26
|
+
md: t.sizes.s12,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
root: {
|
|
31
|
+
position: 'relative',
|
|
32
|
+
width: sizeMap[size].size,
|
|
33
|
+
height: sizeMap[size].size,
|
|
34
|
+
borderRadius: 9999,
|
|
35
|
+
backgroundColor: t.colors.bg.muted,
|
|
36
|
+
alignItems: 'center',
|
|
37
|
+
justifyContent: 'center',
|
|
38
|
+
padding: sizeMap[size].padding,
|
|
39
|
+
},
|
|
40
|
+
notification: {
|
|
41
|
+
position: 'absolute',
|
|
42
|
+
top: 0,
|
|
43
|
+
right: 0,
|
|
44
|
+
width: notificationsMap[size],
|
|
45
|
+
height: notificationsMap[size],
|
|
46
|
+
borderRadius: 9999,
|
|
47
|
+
backgroundColor: t.colors.bg.errorStrong,
|
|
48
|
+
zIndex: 1,
|
|
49
|
+
},
|
|
50
|
+
image: {
|
|
51
|
+
width: '100%',
|
|
52
|
+
height: '100%',
|
|
53
|
+
overflow: 'hidden',
|
|
54
|
+
borderRadius: 9999,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
[size],
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A circular avatar component that displays a user image or fallback icon.
|
|
64
|
+
*
|
|
65
|
+
* When the image fails to load or no src is provided, displays a User icon fallback.
|
|
66
|
+
* Supports an optional notification indicator.
|
|
67
|
+
*
|
|
68
|
+
* @see {@link https://lumen-ldls.vercel.app/?path=/docs/react-native_communication-avatar--docs Storybook}
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* import { Avatar } from '@ledgerhq/lumen-ui-react';
|
|
72
|
+
*
|
|
73
|
+
* <Avatar src="https://example.com/photo.jpg" size="md" />
|
|
74
|
+
*
|
|
75
|
+
* // With notification indicator
|
|
76
|
+
* <Avatar src="https://example.com/photo.jpg" showNotification />
|
|
77
|
+
*/
|
|
78
|
+
export const Avatar = ({
|
|
79
|
+
lx,
|
|
80
|
+
style,
|
|
81
|
+
src,
|
|
82
|
+
alt = 'avatar',
|
|
83
|
+
size = 'md',
|
|
84
|
+
showNotification = false,
|
|
85
|
+
ref,
|
|
86
|
+
...props
|
|
87
|
+
}: AvatarProps) => {
|
|
88
|
+
const { t } = useCommonTranslation();
|
|
89
|
+
const [error, setError] = useState<boolean>(false);
|
|
90
|
+
const shouldFallback = !src || error;
|
|
91
|
+
const styles = useStyles({ size });
|
|
92
|
+
|
|
93
|
+
const resolvedAlt = alt || t('components.avatar.defaultAlt');
|
|
94
|
+
|
|
95
|
+
const accessibilityLabel = showNotification
|
|
96
|
+
? `${resolvedAlt}, ${t('components.avatar.notificationAriaLabel')}`
|
|
97
|
+
: resolvedAlt;
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
setError(false);
|
|
101
|
+
}, [src]);
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Box
|
|
105
|
+
ref={ref}
|
|
106
|
+
lx={lx}
|
|
107
|
+
style={StyleSheet.flatten([styles.root, style])}
|
|
108
|
+
accessibilityRole='image'
|
|
109
|
+
accessibilityLabel={accessibilityLabel}
|
|
110
|
+
{...props}
|
|
111
|
+
>
|
|
112
|
+
{showNotification && (
|
|
113
|
+
<View style={styles.notification} accessible={false} />
|
|
114
|
+
)}
|
|
115
|
+
{shouldFallback ? (
|
|
116
|
+
<User
|
|
117
|
+
size={fallbackSizes[size]}
|
|
118
|
+
accessible={false}
|
|
119
|
+
testID='avatar-fallback-icon'
|
|
120
|
+
/>
|
|
121
|
+
) : (
|
|
122
|
+
<Image
|
|
123
|
+
source={{ uri: src }}
|
|
124
|
+
style={styles.image}
|
|
125
|
+
accessible={false}
|
|
126
|
+
onError={() => setError(true)}
|
|
127
|
+
testID='avatar-image'
|
|
128
|
+
/>
|
|
129
|
+
)}
|
|
130
|
+
</Box>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { StyledViewProps } from '../../../styles';
|
|
2
|
+
|
|
3
|
+
export type AvatarProps = {
|
|
4
|
+
/**
|
|
5
|
+
* Image source URL. When undefined or on load error, displays a fallback icon.
|
|
6
|
+
* @optional
|
|
7
|
+
*/
|
|
8
|
+
src?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Alternative text for the image.
|
|
11
|
+
* @optional
|
|
12
|
+
*/
|
|
13
|
+
alt?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The size variant of the avatar.
|
|
16
|
+
* @optional
|
|
17
|
+
* @default md
|
|
18
|
+
*/
|
|
19
|
+
size?: 'sm' | 'md';
|
|
20
|
+
/**
|
|
21
|
+
* Whether to show the notifications indicator.
|
|
22
|
+
* @optional
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
showNotification?: boolean;
|
|
26
|
+
} & Omit<StyledViewProps, 'children'>;
|
|
@@ -67,7 +67,7 @@ const useStyles = ({
|
|
|
67
67
|
gap: t.spacings.s4,
|
|
68
68
|
},
|
|
69
69
|
title: StyleSheet.flatten([
|
|
70
|
-
t.typographies.
|
|
70
|
+
t.typographies.body2SemiBold,
|
|
71
71
|
{
|
|
72
72
|
color: disabled ? t.colors.text.disabled : t.colors.text.base,
|
|
73
73
|
minWidth: 0,
|
|
@@ -75,9 +75,9 @@ const useStyles = ({
|
|
|
75
75
|
},
|
|
76
76
|
]),
|
|
77
77
|
description: StyleSheet.flatten([
|
|
78
|
-
t.typographies.
|
|
78
|
+
t.typographies.body3,
|
|
79
79
|
{
|
|
80
|
-
color: disabled ? t.colors.text.disabled : t.colors.text.
|
|
80
|
+
color: disabled ? t.colors.text.disabled : t.colors.text.muted,
|
|
81
81
|
minWidth: 0,
|
|
82
82
|
},
|
|
83
83
|
]),
|
|
@@ -33,6 +33,9 @@ The PageIndicator consists of:
|
|
|
33
33
|
|
|
34
34
|
## Properties
|
|
35
35
|
|
|
36
|
+
- **currentPage**: 1-based page number (first page is 1, second is 2, etc.). Valid range: 1 to totalPages.
|
|
37
|
+
- **totalPages**: Total number of pages.
|
|
38
|
+
|
|
36
39
|
### Overview
|
|
37
40
|
|
|
38
41
|
<div style={{ width: '100%' }}>
|
|
@@ -75,7 +78,7 @@ import { PageIndicator } from '@ledgerhq/lumen-ui-rnative';
|
|
|
75
78
|
import { useState } from 'react';
|
|
76
79
|
|
|
77
80
|
function MyComponent() {
|
|
78
|
-
const [currentPage, setCurrentPage] = useState(
|
|
81
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
79
82
|
const totalPages = 5;
|
|
80
83
|
|
|
81
84
|
return <PageIndicator currentPage={currentPage} totalPages={totalPages} />;
|
|
@@ -90,7 +93,7 @@ import { ArrowLeft, ArrowRight } from '@ledgerhq/lumen-ui-rnative/symbols';
|
|
|
90
93
|
import { useState } from 'react';
|
|
91
94
|
|
|
92
95
|
function MyComponent() {
|
|
93
|
-
const [page, setPage] = useState(
|
|
96
|
+
const [page, setPage] = useState(1);
|
|
94
97
|
const totalPages = 9;
|
|
95
98
|
|
|
96
99
|
return (
|
|
@@ -100,14 +103,14 @@ function MyComponent() {
|
|
|
100
103
|
icon={ArrowLeft}
|
|
101
104
|
size='xs'
|
|
102
105
|
accessibilityLabel='Previous page'
|
|
103
|
-
onPress={() => setPage((v) => Math.max(
|
|
106
|
+
onPress={() => setPage((v) => Math.max(1, v - 1))}
|
|
104
107
|
/>
|
|
105
108
|
<PageIndicator currentPage={page} totalPages={totalPages} />
|
|
106
109
|
<IconButton
|
|
107
110
|
icon={ArrowRight}
|
|
108
111
|
size='xs'
|
|
109
112
|
accessibilityLabel='Next page'
|
|
110
|
-
onPress={() => setPage((v) => Math.min(totalPages
|
|
113
|
+
onPress={() => setPage((v) => Math.min(totalPages, v + 1))}
|
|
111
114
|
/>
|
|
112
115
|
</Box>
|
|
113
116
|
</Box>
|
|
@@ -24,13 +24,13 @@ type Story = StoryObj<typeof meta>;
|
|
|
24
24
|
|
|
25
25
|
export const Base: Story = {
|
|
26
26
|
args: {
|
|
27
|
-
currentPage:
|
|
27
|
+
currentPage: 1,
|
|
28
28
|
totalPages: 5,
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
const InteractiveComponent = ({ totalPages }: { totalPages: number }) => {
|
|
33
|
-
const [page, setPage] = useState(
|
|
33
|
+
const [page, setPage] = useState(1);
|
|
34
34
|
const { theme } = useTheme();
|
|
35
35
|
|
|
36
36
|
return (
|
|
@@ -48,7 +48,7 @@ const InteractiveComponent = ({ totalPages }: { totalPages: number }) => {
|
|
|
48
48
|
size='xs'
|
|
49
49
|
accessibilityLabel='Previous page'
|
|
50
50
|
appearance='transparent'
|
|
51
|
-
onPress={() => setPage((v) => Math.max(
|
|
51
|
+
onPress={() => setPage((v) => Math.max(1, v - 1))}
|
|
52
52
|
/>
|
|
53
53
|
<Text
|
|
54
54
|
lx={{ color: 'base', width: 's28', textAlign: 'center' }}
|
|
@@ -61,7 +61,7 @@ const InteractiveComponent = ({ totalPages }: { totalPages: number }) => {
|
|
|
61
61
|
size='xs'
|
|
62
62
|
accessibilityLabel='Next page'
|
|
63
63
|
appearance='transparent'
|
|
64
|
-
onPress={() => setPage((v) => Math.min(totalPages
|
|
64
|
+
onPress={() => setPage((v) => Math.min(totalPages, v + 1))}
|
|
65
65
|
/>
|
|
66
66
|
</Box>
|
|
67
67
|
<PageIndicator currentPage={page} totalPages={totalPages} />
|
|
@@ -71,7 +71,7 @@ const InteractiveComponent = ({ totalPages }: { totalPages: number }) => {
|
|
|
71
71
|
|
|
72
72
|
export const Interactive: Story = {
|
|
73
73
|
args: {
|
|
74
|
-
currentPage:
|
|
74
|
+
currentPage: 1,
|
|
75
75
|
totalPages: 9,
|
|
76
76
|
},
|
|
77
77
|
render: (args) => <InteractiveComponent totalPages={args.totalPages} />,
|
|
@@ -20,7 +20,7 @@ describe('PageIndicator Component', () => {
|
|
|
20
20
|
renderWithProvider(
|
|
21
21
|
<PageIndicator
|
|
22
22
|
testID='page-indicator'
|
|
23
|
-
currentPage={
|
|
23
|
+
currentPage={1}
|
|
24
24
|
totalPages={5}
|
|
25
25
|
/>,
|
|
26
26
|
);
|
|
@@ -31,7 +31,7 @@ describe('PageIndicator Component', () => {
|
|
|
31
31
|
renderWithProvider(
|
|
32
32
|
<PageIndicator
|
|
33
33
|
testID='page-indicator'
|
|
34
|
-
currentPage={
|
|
34
|
+
currentPage={1}
|
|
35
35
|
totalPages={5}
|
|
36
36
|
/>,
|
|
37
37
|
);
|
|
@@ -43,7 +43,7 @@ describe('PageIndicator Component', () => {
|
|
|
43
43
|
renderWithProvider(
|
|
44
44
|
<PageIndicator
|
|
45
45
|
testID='page-indicator'
|
|
46
|
-
currentPage={
|
|
46
|
+
currentPage={1}
|
|
47
47
|
totalPages={3}
|
|
48
48
|
/>,
|
|
49
49
|
);
|
|
@@ -55,7 +55,7 @@ describe('PageIndicator Component', () => {
|
|
|
55
55
|
renderWithProvider(
|
|
56
56
|
<PageIndicator
|
|
57
57
|
testID='page-indicator'
|
|
58
|
-
currentPage={
|
|
58
|
+
currentPage={1}
|
|
59
59
|
totalPages={10}
|
|
60
60
|
/>,
|
|
61
61
|
);
|
|
@@ -69,7 +69,7 @@ describe('PageIndicator Component', () => {
|
|
|
69
69
|
renderWithProvider(
|
|
70
70
|
<PageIndicator
|
|
71
71
|
testID='page-indicator'
|
|
72
|
-
currentPage={
|
|
72
|
+
currentPage={1}
|
|
73
73
|
totalPages={5}
|
|
74
74
|
/>,
|
|
75
75
|
);
|
|
@@ -80,7 +80,7 @@ describe('PageIndicator Component', () => {
|
|
|
80
80
|
renderWithProvider(
|
|
81
81
|
<PageIndicator
|
|
82
82
|
testID='page-indicator'
|
|
83
|
-
currentPage={
|
|
83
|
+
currentPage={3}
|
|
84
84
|
totalPages={5}
|
|
85
85
|
/>,
|
|
86
86
|
);
|
|
@@ -91,7 +91,7 @@ describe('PageIndicator Component', () => {
|
|
|
91
91
|
renderWithProvider(
|
|
92
92
|
<PageIndicator
|
|
93
93
|
testID='page-indicator'
|
|
94
|
-
currentPage={
|
|
94
|
+
currentPage={5}
|
|
95
95
|
totalPages={5}
|
|
96
96
|
/>,
|
|
97
97
|
);
|
|
@@ -104,7 +104,7 @@ describe('PageIndicator Component', () => {
|
|
|
104
104
|
renderWithProvider(
|
|
105
105
|
<PageIndicator
|
|
106
106
|
testID='page-indicator'
|
|
107
|
-
currentPage={
|
|
107
|
+
currentPage={1}
|
|
108
108
|
totalPages={1}
|
|
109
109
|
/>,
|
|
110
110
|
);
|
|
@@ -115,7 +115,7 @@ describe('PageIndicator Component', () => {
|
|
|
115
115
|
renderWithProvider(
|
|
116
116
|
<PageIndicator
|
|
117
117
|
testID='page-indicator'
|
|
118
|
-
currentPage={
|
|
118
|
+
currentPage={1}
|
|
119
119
|
totalPages={2}
|
|
120
120
|
/>,
|
|
121
121
|
);
|
|
@@ -126,7 +126,7 @@ describe('PageIndicator Component', () => {
|
|
|
126
126
|
renderWithProvider(
|
|
127
127
|
<PageIndicator
|
|
128
128
|
testID='page-indicator'
|
|
129
|
-
currentPage={
|
|
129
|
+
currentPage={6}
|
|
130
130
|
totalPages={20}
|
|
131
131
|
/>,
|
|
132
132
|
);
|
|
@@ -139,7 +139,7 @@ describe('PageIndicator Component', () => {
|
|
|
139
139
|
renderWithProvider(
|
|
140
140
|
<PageIndicator
|
|
141
141
|
testID='page-indicator'
|
|
142
|
-
currentPage={
|
|
142
|
+
currentPage={1}
|
|
143
143
|
totalPages={5}
|
|
144
144
|
lx={{ marginTop: 's16' }}
|
|
145
145
|
/>,
|
|
@@ -151,7 +151,7 @@ describe('PageIndicator Component', () => {
|
|
|
151
151
|
renderWithProvider(
|
|
152
152
|
<PageIndicator
|
|
153
153
|
testID='page-indicator'
|
|
154
|
-
currentPage={
|
|
154
|
+
currentPage={1}
|
|
155
155
|
totalPages={5}
|
|
156
156
|
style={{ marginTop: 16 }}
|
|
157
157
|
/>,
|
|
@@ -167,7 +167,7 @@ describe('PageIndicator Component', () => {
|
|
|
167
167
|
<PageIndicator
|
|
168
168
|
ref={ref}
|
|
169
169
|
testID='page-indicator'
|
|
170
|
-
currentPage={
|
|
170
|
+
currentPage={1}
|
|
171
171
|
totalPages={5}
|
|
172
172
|
/>,
|
|
173
173
|
);
|
|
@@ -178,7 +178,7 @@ describe('PageIndicator Component', () => {
|
|
|
178
178
|
renderWithProvider(
|
|
179
179
|
<PageIndicator
|
|
180
180
|
testID='page-indicator'
|
|
181
|
-
currentPage={
|
|
181
|
+
currentPage={1}
|
|
182
182
|
totalPages={5}
|
|
183
183
|
accessibilityLabel='Page indicator'
|
|
184
184
|
/>,
|
|
@@ -126,7 +126,7 @@ const usePageIndicator = ({
|
|
|
126
126
|
);
|
|
127
127
|
|
|
128
128
|
const firstVisibleIndex = offset;
|
|
129
|
-
const lastVisibleIndex = offset +
|
|
129
|
+
const lastVisibleIndex = offset + visibleDots - 1;
|
|
130
130
|
|
|
131
131
|
const isActive = useCallback(
|
|
132
132
|
(index: number): boolean => index === currentPage,
|
|
@@ -192,9 +192,13 @@ export const PageIndicator = ({
|
|
|
192
192
|
const styles = usePageIndicatorStyles();
|
|
193
193
|
const { theme } = useTheme();
|
|
194
194
|
|
|
195
|
+
const currentPageIndex = Math.max(
|
|
196
|
+
0,
|
|
197
|
+
Math.min(currentPage - 1, totalPages - 1),
|
|
198
|
+
);
|
|
195
199
|
const { viewportWidth, stripAnimatedStyle, isActive, isShrunk } =
|
|
196
200
|
usePageIndicator({
|
|
197
|
-
currentPage,
|
|
201
|
+
currentPage: currentPageIndex,
|
|
198
202
|
totalPages,
|
|
199
203
|
dotSize: theme.sizes.s6,
|
|
200
204
|
gap: theme.spacings.s4,
|
|
@@ -2,7 +2,7 @@ import { BoxProps } from '../Utility';
|
|
|
2
2
|
|
|
3
3
|
export type PageIndicatorProps = {
|
|
4
4
|
/**
|
|
5
|
-
* The currently active page
|
|
5
|
+
* The currently active page. 1-based (first page is 1, second is 2, etc.).
|
|
6
6
|
*/
|
|
7
7
|
currentPage: number;
|
|
8
8
|
/**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Svg, { Path, Mask } from 'react-native-svg';
|
|
2
|
+
import createIcon from '../../Components/Icon/createIcon';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Chart5 icon component for React Native.
|
|
6
|
+
*
|
|
7
|
+
* This icon component is automatically generated from SVG files and uses the createIcon utility
|
|
8
|
+
* to create a consistent icon interface. It supports all standard SVG props (from react-native-svg)
|
|
9
|
+
* and additional size variants defined in the Icon component.
|
|
10
|
+
*
|
|
11
|
+
* @component
|
|
12
|
+
* @param {16 | 20 | 24 | 40 | 48 | 56} [size=24] - The size of the icon in pixels.
|
|
13
|
+
* @param {string} [color] - The color of the icon.
|
|
14
|
+
* @param {SVGProps} [...props] - All standard SVG element props (from react-native-svg).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Basic usage with default size (24px)
|
|
18
|
+
* import { Chart5 } from '@ledgerhq/lumen-ui-rnative/symbols';
|
|
19
|
+
*
|
|
20
|
+
* <Chart5 />
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // With custom size and style
|
|
24
|
+
* <Chart5 size={40} color="warning" lx={{ marginTop: 's4' }} />
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Used within a Button component
|
|
28
|
+
* import { Button } from '@ledgerhq/lumen-ui-rnative';
|
|
29
|
+
*
|
|
30
|
+
* <Button icon={Chart5} size="md">
|
|
31
|
+
* Click me
|
|
32
|
+
* </Button>
|
|
33
|
+
*/
|
|
34
|
+
export const Chart5 = createIcon(
|
|
35
|
+
'Chart5',
|
|
36
|
+
<Svg width={24} height={24} fill='currentColor' viewBox='0 0 16 16'>
|
|
37
|
+
<Path
|
|
38
|
+
stroke='currentColor'
|
|
39
|
+
strokeLinecap='round'
|
|
40
|
+
strokeLinejoin='round'
|
|
41
|
+
strokeWidth={1.3}
|
|
42
|
+
d='m3.96 10.313 2.562-2.639a.485.485 0 0 1 .712 0l1.082 1.114a.493.493 0 0 0 .713 0l3.012-3.101m-1.345.005h1.344v1.385'
|
|
43
|
+
/>
|
|
44
|
+
<Mask id='path-2-inside-1_8174_813' fill='#fff'>
|
|
45
|
+
<Path d='M.9 3.672a2 2 0 0 1 2-2h10.2a2 2 0 0 1 2 2v8.656a2 2 0 0 1-2 2H2.9a2 2 0 0 1-2-2z' />
|
|
46
|
+
</Mask>
|
|
47
|
+
<Path
|
|
48
|
+
fill='currentColor'
|
|
49
|
+
d='M2.9 1.672v1.3h10.2v-2.6H2.9zm12.2 2h-1.3v8.656h2.6V3.672zm-2 10.656v-1.3H2.9v2.6h10.2zm-12.2-2h1.3V3.672H-.4v8.656zm2 2v-1.3a.7.7 0 0 1-.7-.7H-.4a3.3 3.3 0 0 0 3.3 3.3zm12.2-2h-1.3a.7.7 0 0 1-.7.7v2.6a3.3 3.3 0 0 0 3.3-3.3zm-2-10.656v1.3a.7.7 0 0 1 .7.7h2.6a3.3 3.3 0 0 0-3.3-3.3zm-10.2 0v-1.3a3.3 3.3 0 0 0-3.3 3.3h2.6a.7.7 0 0 1 .7-.7z'
|
|
50
|
+
mask='url(#path-2-inside-1_8174_813)'
|
|
51
|
+
/>
|
|
52
|
+
</Svg>,
|
|
53
|
+
);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Svg, { Path } from 'react-native-svg';
|
|
2
|
+
import createIcon from '../../Components/Icon/createIcon';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Chart5Fill icon component for React Native.
|
|
6
|
+
*
|
|
7
|
+
* This icon component is automatically generated from SVG files and uses the createIcon utility
|
|
8
|
+
* to create a consistent icon interface. It supports all standard SVG props (from react-native-svg)
|
|
9
|
+
* and additional size variants defined in the Icon component.
|
|
10
|
+
*
|
|
11
|
+
* @component
|
|
12
|
+
* @param {16 | 20 | 24 | 40 | 48 | 56} [size=24] - The size of the icon in pixels.
|
|
13
|
+
* @param {string} [color] - The color of the icon.
|
|
14
|
+
* @param {SVGProps} [...props] - All standard SVG element props (from react-native-svg).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Basic usage with default size (24px)
|
|
18
|
+
* import { Chart5Fill } from '@ledgerhq/lumen-ui-rnative/symbols';
|
|
19
|
+
*
|
|
20
|
+
* <Chart5Fill />
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // With custom size and style
|
|
24
|
+
* <Chart5Fill size={40} color="warning" lx={{ marginTop: 's4' }} />
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Used within a Button component
|
|
28
|
+
* import { Button } from '@ledgerhq/lumen-ui-rnative';
|
|
29
|
+
*
|
|
30
|
+
* <Button icon={Chart5Fill} size="md">
|
|
31
|
+
* Click me
|
|
32
|
+
* </Button>
|
|
33
|
+
*/
|
|
34
|
+
export const Chart5Fill = createIcon(
|
|
35
|
+
'Chart5Fill',
|
|
36
|
+
<Svg width={24} height={24} fill='currentColor' viewBox='0 0 16 16'>
|
|
37
|
+
<Path
|
|
38
|
+
fill='currentColor'
|
|
39
|
+
d='M13.1 1.662a2 2 0 0 1 2 2v8.66a2 2 0 0 1-2 2H2.9a2 2 0 0 1-2-2v-8.66a2 2 0 0 1 2-2zm-2.404 3.379a.648.648 0 0 0-.173 1.273L8.672 8.22l-.97-1a1.134 1.134 0 0 0-1.646 0L3.493 9.86a.65.65 0 0 0 .934.905l2.45-2.527.974 1.002.088.082c.456.381 1.132.355 1.556-.082l1.925-1.982a.648.648 0 0 0 1.27-.183V5.691a.647.647 0 0 0-.709-.65z'
|
|
40
|
+
/>
|
|
41
|
+
</Svg>,
|
|
42
|
+
);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Svg, { Path, Circle } from 'react-native-svg';
|
|
2
|
+
import createIcon from '../../Components/Icon/createIcon';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* CurveDown icon component for React Native.
|
|
6
|
+
*
|
|
7
|
+
* This icon component is automatically generated from SVG files and uses the createIcon utility
|
|
8
|
+
* to create a consistent icon interface. It supports all standard SVG props (from react-native-svg)
|
|
9
|
+
* and additional size variants defined in the Icon component.
|
|
10
|
+
*
|
|
11
|
+
* @component
|
|
12
|
+
* @param {16 | 20 | 24 | 40 | 48 | 56} [size=24] - The size of the icon in pixels.
|
|
13
|
+
* @param {string} [color] - The color of the icon.
|
|
14
|
+
* @param {SVGProps} [...props] - All standard SVG element props (from react-native-svg).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Basic usage with default size (24px)
|
|
18
|
+
* import { CurveDown } from '@ledgerhq/lumen-ui-rnative/symbols';
|
|
19
|
+
*
|
|
20
|
+
* <CurveDown />
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // With custom size and style
|
|
24
|
+
* <CurveDown size={40} color="warning" lx={{ marginTop: 's4' }} />
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Used within a Button component
|
|
28
|
+
* import { Button } from '@ledgerhq/lumen-ui-rnative';
|
|
29
|
+
*
|
|
30
|
+
* <Button icon={CurveDown} size="md">
|
|
31
|
+
* Click me
|
|
32
|
+
* </Button>
|
|
33
|
+
*/
|
|
34
|
+
export const CurveDown = createIcon(
|
|
35
|
+
'CurveDown',
|
|
36
|
+
<Svg width={24} height={24} fill='currentColor' viewBox='0 0 17 16'>
|
|
37
|
+
<Path
|
|
38
|
+
stroke='currentColor'
|
|
39
|
+
strokeDasharray='1 2.2'
|
|
40
|
+
strokeLinecap='round'
|
|
41
|
+
strokeLinejoin='round'
|
|
42
|
+
strokeWidth={1.3}
|
|
43
|
+
d='M1.52 11.793H10.2'
|
|
44
|
+
/>
|
|
45
|
+
<Path
|
|
46
|
+
stroke='currentColor'
|
|
47
|
+
strokeDasharray='1 2'
|
|
48
|
+
strokeLinecap='round'
|
|
49
|
+
strokeLinejoin='round'
|
|
50
|
+
strokeWidth={1.3}
|
|
51
|
+
d='M13.235 11.793h2.393'
|
|
52
|
+
/>
|
|
53
|
+
<Path
|
|
54
|
+
stroke='currentColor'
|
|
55
|
+
strokeLinecap='round'
|
|
56
|
+
strokeLinejoin='round'
|
|
57
|
+
strokeWidth={1.3}
|
|
58
|
+
d='M2.264 2.099C2.156 3.302 2.711 5.404 5.5 6.03c2.719.611 5.44 1.397 5.912 4.106'
|
|
59
|
+
/>
|
|
60
|
+
<Circle
|
|
61
|
+
cx={2.108}
|
|
62
|
+
cy={2.108}
|
|
63
|
+
r={1.458}
|
|
64
|
+
stroke='currentColor'
|
|
65
|
+
strokeWidth={1.3}
|
|
66
|
+
transform='matrix(1 0 0 -1 9.601 13.901)'
|
|
67
|
+
/>
|
|
68
|
+
</Svg>,
|
|
69
|
+
);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import Svg, { Path, Circle } from 'react-native-svg';
|
|
2
|
+
import createIcon from '../../Components/Icon/createIcon';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* CurveUp icon component for React Native.
|
|
6
|
+
*
|
|
7
|
+
* This icon component is automatically generated from SVG files and uses the createIcon utility
|
|
8
|
+
* to create a consistent icon interface. It supports all standard SVG props (from react-native-svg)
|
|
9
|
+
* and additional size variants defined in the Icon component.
|
|
10
|
+
*
|
|
11
|
+
* @component
|
|
12
|
+
* @param {16 | 20 | 24 | 40 | 48 | 56} [size=24] - The size of the icon in pixels.
|
|
13
|
+
* @param {string} [color] - The color of the icon.
|
|
14
|
+
* @param {SVGProps} [...props] - All standard SVG element props (from react-native-svg).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Basic usage with default size (24px)
|
|
18
|
+
* import { CurveUp } from '@ledgerhq/lumen-ui-rnative/symbols';
|
|
19
|
+
*
|
|
20
|
+
* <CurveUp />
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // With custom size and style
|
|
24
|
+
* <CurveUp size={40} color="warning" lx={{ marginTop: 's4' }} />
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Used within a Button component
|
|
28
|
+
* import { Button } from '@ledgerhq/lumen-ui-rnative';
|
|
29
|
+
*
|
|
30
|
+
* <Button icon={CurveUp} size="md">
|
|
31
|
+
* Click me
|
|
32
|
+
* </Button>
|
|
33
|
+
*/
|
|
34
|
+
export const CurveUp = createIcon(
|
|
35
|
+
'CurveUp',
|
|
36
|
+
<Svg width={24} height={24} fill='currentColor' viewBox='0 0 17 16'>
|
|
37
|
+
<Path
|
|
38
|
+
stroke='currentColor'
|
|
39
|
+
strokeDasharray='1 2.2'
|
|
40
|
+
strokeLinecap='round'
|
|
41
|
+
strokeLinejoin='round'
|
|
42
|
+
strokeWidth={1.3}
|
|
43
|
+
d='M1.52 4.208H10.2'
|
|
44
|
+
/>
|
|
45
|
+
<Path
|
|
46
|
+
stroke='currentColor'
|
|
47
|
+
strokeDasharray='1 2'
|
|
48
|
+
strokeLinecap='round'
|
|
49
|
+
strokeLinejoin='round'
|
|
50
|
+
strokeWidth={1.3}
|
|
51
|
+
d='M13.235 4.207h2.393'
|
|
52
|
+
/>
|
|
53
|
+
<Path
|
|
54
|
+
stroke='currentColor'
|
|
55
|
+
strokeLinecap='round'
|
|
56
|
+
strokeLinejoin='round'
|
|
57
|
+
strokeWidth={1.3}
|
|
58
|
+
d='M2.264 13.901c-.108-1.203.447-3.305 3.236-3.932 2.719-.611 5.44-1.397 5.912-4.106'
|
|
59
|
+
/>
|
|
60
|
+
<Circle
|
|
61
|
+
cx={11.71}
|
|
62
|
+
cy={4.207}
|
|
63
|
+
r={1.458}
|
|
64
|
+
stroke='currentColor'
|
|
65
|
+
strokeWidth={1.3}
|
|
66
|
+
/>
|
|
67
|
+
</Svg>,
|
|
68
|
+
);
|