@procivis/one-react-native-components 0.3.53 → 0.3.62
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/credential/credential.js +6 -3
- package/lib/commonjs/components/credential/credential.js.map +1 -1
- package/lib/commonjs/components/history/history-list-item-icon.js +3 -1
- package/lib/commonjs/components/history/history-list-item-icon.js.map +1 -1
- package/lib/commonjs/components/history/history-list-screen.js +2 -2
- package/lib/commonjs/components/history/history-list-screen.js.map +1 -1
- package/lib/commonjs/components/proof-request/select-credential.js +7 -3
- package/lib/commonjs/components/proof-request/select-credential.js.map +1 -1
- package/lib/commonjs/components/proof-request/share-credential.js +6 -9
- package/lib/commonjs/components/proof-request/share-credential.js.map +1 -1
- package/lib/commonjs/ui-components/credential/card/credential-card.js +14 -29
- package/lib/commonjs/ui-components/credential/card/credential-card.js.map +1 -1
- package/lib/commonjs/ui-components/credential/card/credential-details-card.js +27 -28
- package/lib/commonjs/ui-components/credential/card/credential-details-card.js.map +1 -1
- package/lib/commonjs/ui-components/credential/card/credential-details-list-item.js +10 -6
- package/lib/commonjs/ui-components/credential/card/credential-details-list-item.js.map +1 -1
- package/lib/commonjs/ui-components/header/header.js +7 -5
- package/lib/commonjs/ui-components/header/header.js.map +1 -1
- package/lib/commonjs/ui-components/history/history-details.js +3 -1
- package/lib/commonjs/ui-components/history/history-details.js.map +1 -1
- package/lib/commonjs/ui-components/icons/icons.js +100 -1
- package/lib/commonjs/ui-components/icons/icons.js.map +1 -1
- package/lib/commonjs/ui-components/searchbar/animated-search-bar.js +10 -8
- package/lib/commonjs/ui-components/searchbar/animated-search-bar.js.map +1 -1
- package/lib/commonjs/utils/hooks/core/backup.js +4 -3
- package/lib/commonjs/utils/hooks/core/backup.js.map +1 -1
- package/lib/commonjs/utils/hooks/core/core-init.js +23 -4
- package/lib/commonjs/utils/hooks/core/core-init.js.map +1 -1
- package/lib/commonjs/utils/hooks/core/credentials.js +4 -4
- package/lib/commonjs/utils/hooks/core/credentials.js.map +1 -1
- package/lib/commonjs/utils/hooks/core/proofs.js +3 -1
- package/lib/commonjs/utils/hooks/core/proofs.js.map +1 -1
- package/lib/commonjs/utils/parsers/credential-sharing.js +18 -1
- package/lib/commonjs/utils/parsers/credential-sharing.js.map +1 -1
- package/lib/commonjs/utils/parsers/credential.js.map +1 -1
- package/lib/module/components/credential/credential.js +5 -3
- package/lib/module/components/credential/credential.js.map +1 -1
- package/lib/module/components/history/history-list-item-icon.js +3 -1
- package/lib/module/components/history/history-list-item-icon.js.map +1 -1
- package/lib/module/components/history/history-list-screen.js +2 -2
- package/lib/module/components/history/history-list-screen.js.map +1 -1
- package/lib/module/components/proof-request/select-credential.js +5 -2
- package/lib/module/components/proof-request/select-credential.js.map +1 -1
- package/lib/module/components/proof-request/share-credential.js +7 -10
- package/lib/module/components/proof-request/share-credential.js.map +1 -1
- package/lib/module/ui-components/credential/card/credential-card.js +15 -30
- package/lib/module/ui-components/credential/card/credential-card.js.map +1 -1
- package/lib/module/ui-components/credential/card/credential-details-card.js +27 -28
- package/lib/module/ui-components/credential/card/credential-details-card.js.map +1 -1
- package/lib/module/ui-components/credential/card/credential-details-list-item.js +10 -6
- package/lib/module/ui-components/credential/card/credential-details-list-item.js.map +1 -1
- package/lib/module/ui-components/header/header.js +7 -5
- package/lib/module/ui-components/header/header.js.map +1 -1
- package/lib/module/ui-components/history/history-details.js +4 -2
- package/lib/module/ui-components/history/history-details.js.map +1 -1
- package/lib/module/ui-components/icons/icons.js +95 -0
- package/lib/module/ui-components/icons/icons.js.map +1 -1
- package/lib/module/ui-components/searchbar/animated-search-bar.js +10 -8
- package/lib/module/ui-components/searchbar/animated-search-bar.js.map +1 -1
- package/lib/module/utils/hooks/core/backup.js +5 -4
- package/lib/module/utils/hooks/core/backup.js.map +1 -1
- package/lib/module/utils/hooks/core/core-init.js +21 -3
- package/lib/module/utils/hooks/core/core-init.js.map +1 -1
- package/lib/module/utils/hooks/core/credentials.js +4 -4
- package/lib/module/utils/hooks/core/credentials.js.map +1 -1
- package/lib/module/utils/hooks/core/proofs.js +3 -1
- package/lib/module/utils/hooks/core/proofs.js.map +1 -1
- package/lib/module/utils/parsers/credential-sharing.js +18 -1
- package/lib/module/utils/parsers/credential-sharing.js.map +1 -1
- package/lib/module/utils/parsers/credential.js.map +1 -1
- package/lib/typescript/components/proof-request/share-credential.d.ts +4 -5
- package/lib/typescript/ui-components/credential/card/credential-card.d.ts +1 -0
- package/lib/typescript/ui-components/header/header.d.ts +1 -1
- package/lib/typescript/ui-components/icons/icons.d.ts +4 -0
- package/lib/typescript/ui-components/searchbar/animated-search-bar.d.ts +2 -2
- package/lib/typescript/utils/hooks/core/backup.d.ts +1 -1
- package/lib/typescript/utils/hooks/core/core-init.d.ts +4 -1
- package/lib/typescript/utils/hooks/core/credentials.d.ts +2 -6
- package/lib/typescript/utils/parsers/credential-sharing.d.ts +6 -6
- package/lib/typescript/utils/parsers/credential.d.ts +6 -3
- package/package.json +3 -3
- package/src/components/credential/credential.tsx +4 -2
- package/src/components/history/history-list-item-icon.tsx +2 -0
- package/src/components/history/history-list-screen.tsx +9 -7
- package/src/components/proof-request/select-credential.tsx +4 -2
- package/src/components/proof-request/share-credential.tsx +10 -10
- package/src/ui-components/credential/card/credential-card.stories.tsx +14 -2
- package/src/ui-components/credential/card/credential-card.tsx +16 -23
- package/src/ui-components/credential/card/credential-details-card.stories.tsx +14 -4
- package/src/ui-components/credential/card/credential-details-card.tsx +32 -34
- package/src/ui-components/credential/card/credential-details-list-item.tsx +10 -6
- package/src/ui-components/detail/detail.stories.tsx +3 -3
- package/src/ui-components/header/header.stories.tsx +8 -6
- package/src/ui-components/header/header.tsx +7 -5
- package/src/ui-components/history/history-details.tsx +3 -1
- package/src/ui-components/icons/icons.tsx +85 -0
- package/src/ui-components/searchbar/animated-search-bar.tsx +11 -9
- package/src/utils/hooks/core/backup.ts +8 -2
- package/src/utils/hooks/core/core-init.ts +28 -2
- package/src/utils/hooks/core/credentials.ts +3 -3
- package/src/utils/hooks/core/proofs.ts +3 -1
- package/src/utils/parsers/credential-sharing.tsx +34 -11
- package/src/utils/parsers/credential.ts +8 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@procivis/one-react-native-components",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.62",
|
|
4
4
|
"author": "Procivis AG (https://procivis.ch)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "Common Procivis ONE UI components for react-native",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@babel/runtime": "^7.25.0",
|
|
52
52
|
"@commitlint/config-conventional": "^11.0.0",
|
|
53
53
|
"@gorhom/bottom-sheet": "^5.1.2",
|
|
54
|
-
"@procivis/react-native-one-core": "1.
|
|
54
|
+
"@procivis/react-native-one-core": "1.58284.0",
|
|
55
55
|
"@procivis/react-native-picker": "5.0.3",
|
|
56
56
|
"@react-native-async-storage/async-storage": "^1.17.3",
|
|
57
57
|
"@react-native-community/blur": "^4.4.0",
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
"vite": "^6.2.2"
|
|
139
139
|
},
|
|
140
140
|
"peerDependencies": {
|
|
141
|
-
"@procivis/react-native-one-core": "^1.
|
|
141
|
+
"@procivis/react-native-one-core": "^1.58284.0",
|
|
142
142
|
"@procivis/react-native-picker": "*",
|
|
143
143
|
"@react-native-community/blur": "*",
|
|
144
144
|
"@react-native-community/netinfo": "^11.4.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Claim } from '@procivis/react-native-one-core';
|
|
2
|
-
import React, { FC } from 'react';
|
|
3
|
-
import { ImageSourcePropType, StyleSheet } from 'react-native';
|
|
2
|
+
import React, { FC, useMemo } from 'react';
|
|
3
|
+
import { Dimensions, ImageSourcePropType, StyleSheet } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import { CredentialDetailsCardListItem, CredentialHeaderProps } from '../../ui-components/credential/card';
|
|
6
6
|
import { concatTestID } from '../../utils';
|
|
@@ -31,6 +31,7 @@ export const CredentialDetails: FC<CredentialDetailsProps> = ({
|
|
|
31
31
|
}) => {
|
|
32
32
|
const { data: credential } = useCredentialDetail(credentialId);
|
|
33
33
|
const { data: config } = useCoreConfig();
|
|
34
|
+
const cardWidth = useMemo(() => Dimensions.get('window').width - 32, []);
|
|
34
35
|
|
|
35
36
|
if (!credential || !config) {
|
|
36
37
|
return null;
|
|
@@ -55,6 +56,7 @@ export const CredentialDetails: FC<CredentialDetailsProps> = ({
|
|
|
55
56
|
...card,
|
|
56
57
|
credentialId,
|
|
57
58
|
onHeaderPress,
|
|
59
|
+
width: cardWidth,
|
|
58
60
|
}}
|
|
59
61
|
expanded={expanded}
|
|
60
62
|
lastItem={lastItem}
|
|
@@ -118,13 +118,15 @@ export const HistoryListScreen: FC<PropsWithChildren<HistoryListScreenProps>> =
|
|
|
118
118
|
!searchBarVisible
|
|
119
119
|
? undefined
|
|
120
120
|
: {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
rightButtons: onOpenFilter
|
|
122
|
+
? [
|
|
123
|
+
<FilterButton
|
|
124
|
+
active={Boolean(queryParams.credentialSchemaId)}
|
|
125
|
+
onPress={onOpenFilter}
|
|
126
|
+
testID={concatTestID(testID, 'filter')}
|
|
127
|
+
/>,
|
|
128
|
+
]
|
|
129
|
+
: undefined,
|
|
128
130
|
rightButtonAlwaysVisible: true,
|
|
129
131
|
searchBarProps: {
|
|
130
132
|
onSearchPhraseChange: setSearchPhrase,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PresentationDefinitionRequestedCredential } from '@procivis/react-native-one-core';
|
|
2
|
-
import React, { FC } from 'react';
|
|
3
|
-
import { ImageSourcePropType } from 'react-native';
|
|
2
|
+
import React, { FC, useMemo } from 'react';
|
|
3
|
+
import { Dimensions, ImageSourcePropType } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import { CredentialDetailsCardListItem } from '../../ui-components';
|
|
6
6
|
import { useCoreConfig } from '../../utils/hooks/core/core-config';
|
|
@@ -19,6 +19,7 @@ export const SelectCredential: FC<{
|
|
|
19
19
|
}> = ({ credentialId, labels, lastItem, onImagePreview, onPress, request, selected, testID }) => {
|
|
20
20
|
const { data: credential } = useCredentialDetail(credentialId);
|
|
21
21
|
const { data: config } = useCoreConfig();
|
|
22
|
+
const cardWidth = useMemo(() => Dimensions.get('window').width - 32, []);
|
|
22
23
|
|
|
23
24
|
if (!credential || !config) {
|
|
24
25
|
return null;
|
|
@@ -39,6 +40,7 @@ export const SelectCredential: FC<{
|
|
|
39
40
|
card={{
|
|
40
41
|
...card,
|
|
41
42
|
onHeaderPress: onPress,
|
|
43
|
+
width: cardWidth,
|
|
42
44
|
}}
|
|
43
45
|
expanded={selected}
|
|
44
46
|
lastItem={lastItem}
|
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CredentialDetail,
|
|
2
3
|
CredentialListItem,
|
|
3
4
|
CredentialStateEnum,
|
|
4
5
|
PresentationDefinitionField,
|
|
5
6
|
PresentationDefinitionRequestedCredential,
|
|
6
7
|
} from '@procivis/react-native-one-core';
|
|
7
8
|
import React, { FunctionComponent, useMemo } from 'react';
|
|
8
|
-
import { ImageSourcePropType, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
|
|
9
|
+
import { Dimensions, ImageSourcePropType, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
|
|
9
10
|
|
|
10
11
|
import { Button, ButtonType, CredentialDetailsCardListItem, Typography, useAppColorScheme } from '../../ui-components';
|
|
11
12
|
import { concatTestID } from '../../utils';
|
|
12
13
|
import { useCoreConfig } from '../../utils/hooks/core/core-config';
|
|
13
|
-
import { useCredentialDetail } from '../../utils/hooks/core/credentials';
|
|
14
14
|
import { getValidityState, ValidityState } from '../../utils/parsers/credential';
|
|
15
15
|
import { shareCredentialCardFromCredential, ShareCredentialCardLabels } from '../../utils/parsers/credential-sharing';
|
|
16
16
|
|
|
17
17
|
export type ShareCredentialLabels = ShareCredentialCardLabels & {
|
|
18
|
-
revokedCredentialNotice: string;
|
|
19
|
-
suspendedCredentialNotice: string;
|
|
20
18
|
invalidCredentialNotice: string;
|
|
21
19
|
multipleCredentialsNotice: string;
|
|
22
20
|
multipleCredentialsSelect: string;
|
|
21
|
+
revokedCredentialNotice: string;
|
|
22
|
+
suspendedCredentialNotice: string;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export const ShareCredential: FunctionComponent<{
|
|
26
|
-
allCredentials:
|
|
27
|
-
credentialId: string;
|
|
26
|
+
allCredentials: CredentialDetail[];
|
|
28
27
|
expanded?: boolean;
|
|
29
28
|
labels: ShareCredentialLabels;
|
|
30
29
|
lastItem?: boolean;
|
|
@@ -39,7 +38,6 @@ export const ShareCredential: FunctionComponent<{
|
|
|
39
38
|
testID: string;
|
|
40
39
|
}> = ({
|
|
41
40
|
allCredentials,
|
|
42
|
-
credentialId,
|
|
43
41
|
expanded,
|
|
44
42
|
labels,
|
|
45
43
|
lastItem,
|
|
@@ -54,8 +52,9 @@ export const ShareCredential: FunctionComponent<{
|
|
|
54
52
|
testID,
|
|
55
53
|
}) => {
|
|
56
54
|
const colorScheme = useAppColorScheme();
|
|
57
|
-
const
|
|
55
|
+
const credential = allCredentials.find((c) => c.id === selectedCredentialId);
|
|
58
56
|
const { data: config } = useCoreConfig();
|
|
57
|
+
const cardWidth = useMemo(() => Dimensions.get('window').width - 32, []);
|
|
59
58
|
|
|
60
59
|
const selectionOptions = useMemo(
|
|
61
60
|
() =>
|
|
@@ -141,7 +140,7 @@ export const ShareCredential: FunctionComponent<{
|
|
|
141
140
|
}
|
|
142
141
|
}, [colorScheme, expanded, invalid, labels, multipleCredentialsAvailable, onSelectCredential, testID, validityState]);
|
|
143
142
|
|
|
144
|
-
if (
|
|
143
|
+
if (!config) {
|
|
145
144
|
return null;
|
|
146
145
|
}
|
|
147
146
|
|
|
@@ -162,8 +161,9 @@ export const ShareCredential: FunctionComponent<{
|
|
|
162
161
|
attributes={attributes}
|
|
163
162
|
card={{
|
|
164
163
|
...card,
|
|
165
|
-
credentialId,
|
|
164
|
+
credentialId: request.id,
|
|
166
165
|
onHeaderPress,
|
|
166
|
+
width: cardWidth,
|
|
167
167
|
}}
|
|
168
168
|
expanded={expanded}
|
|
169
169
|
footer={footer}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
1
|
+
import type { Meta, StoryContext, StoryObj } from '@storybook/react';
|
|
2
|
+
import React from 'react';
|
|
2
3
|
|
|
3
4
|
import CredentialCardBackground from '../../../../storybook/assets/CredentialCardBackground.png';
|
|
4
5
|
import ColorSchemes from '../../../../storybook/colorScheme';
|
|
5
6
|
import { CredentialNoticeWarningIcon, CredentialWarningIcon, RequiredAttributeIcon } from '../../icons/credential';
|
|
6
|
-
import CredentialCard from './credential-card';
|
|
7
|
+
import CredentialCard, { CredentialCardProps } from './credential-card';
|
|
8
|
+
|
|
9
|
+
const Render = (args: CredentialCardProps, context: StoryContext<CredentialCardProps>) => {
|
|
10
|
+
const viewport = context.parameters.viewport.viewports[context.userGlobals.viewport];
|
|
11
|
+
const width = parseInt(viewport.styles.width.replace('px', ''), 10);
|
|
12
|
+
const props = {
|
|
13
|
+
...args,
|
|
14
|
+
width,
|
|
15
|
+
};
|
|
16
|
+
return <CredentialCard {...props} />;
|
|
17
|
+
};
|
|
7
18
|
|
|
8
19
|
const Basic: StoryObj<typeof CredentialCard> = {
|
|
9
20
|
args: {
|
|
@@ -26,6 +37,7 @@ const Basic: StoryObj<typeof CredentialCard> = {
|
|
|
26
37
|
noticeIcon: CredentialNoticeWarningIcon,
|
|
27
38
|
},
|
|
28
39
|
},
|
|
40
|
+
render: Render,
|
|
29
41
|
};
|
|
30
42
|
|
|
31
43
|
export { Basic as CredentialCard };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { FC, useCallback, useMemo
|
|
2
|
-
import { ColorValue, Image,
|
|
1
|
+
import React, { FC, useCallback, useMemo } from 'react';
|
|
2
|
+
import { ColorValue, Image, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import { concatTestID } from '../../../utils/testID';
|
|
5
5
|
import { TouchableOpacity } from '../../accessibility/accessibilityHistoryWrappers';
|
|
@@ -39,6 +39,7 @@ export type CredentialCardProps = {
|
|
|
39
39
|
onHeaderPress?: (credentialId?: string) => void;
|
|
40
40
|
style?: StyleProp<ViewStyle>;
|
|
41
41
|
testID?: string;
|
|
42
|
+
width: number;
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
const CredentialCard: FC<CredentialCardProps> = ({
|
|
@@ -52,19 +53,13 @@ const CredentialCard: FC<CredentialCardProps> = ({
|
|
|
52
53
|
onHeaderPress,
|
|
53
54
|
style,
|
|
54
55
|
testID,
|
|
56
|
+
width,
|
|
55
57
|
}) => {
|
|
56
58
|
const colorScheme = useAppColorScheme();
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const { width, height } = event.nativeEvent.layout;
|
|
62
|
-
setCardSize({ width, height });
|
|
63
|
-
}, []);
|
|
64
|
-
|
|
65
|
-
const onHeaderLayoutChange = useCallback((event: LayoutChangeEvent) => {
|
|
66
|
-
setTappableHeaderHeight(event.nativeEvent.layout.height);
|
|
67
|
-
}, []);
|
|
59
|
+
const cardSize = {
|
|
60
|
+
width,
|
|
61
|
+
height: Math.ceil(width / CredentialCardRatio),
|
|
62
|
+
};
|
|
68
63
|
|
|
69
64
|
const headerPressHandler = useCallback(() => {
|
|
70
65
|
onHeaderPress?.(credentialId);
|
|
@@ -88,35 +83,34 @@ const CredentialCard: FC<CredentialCardProps> = ({
|
|
|
88
83
|
|
|
89
84
|
const shouldShowCarousel = cardSize?.width && cardSize.height;
|
|
90
85
|
return (
|
|
91
|
-
<View
|
|
86
|
+
<View style={[styles.card, cardSize, style]} testID={testID}>
|
|
92
87
|
{cardImage ? (
|
|
93
88
|
'imageSource' in cardImage ? (
|
|
94
|
-
<View style={
|
|
89
|
+
<View style={cardSize}>
|
|
95
90
|
<Image testID={concatTestID(testID, 'imageSource')} source={cardImage.imageSource} style={styles.image} />
|
|
96
91
|
</View>
|
|
97
92
|
) : (
|
|
98
|
-
<ImageOrComponent testID={concatTestID(testID, 'cardImage')} source={cardImage} style={
|
|
93
|
+
<ImageOrComponent testID={concatTestID(testID, 'cardImage')} source={cardImage} style={cardSize} />
|
|
99
94
|
)
|
|
100
95
|
) : (
|
|
101
96
|
<View
|
|
102
97
|
testID={concatTestID(testID, 'cardBackgroundColor', String(color))}
|
|
103
|
-
style={[
|
|
98
|
+
style={[cardSize, { backgroundColor: color }]}
|
|
104
99
|
/>
|
|
105
100
|
)}
|
|
106
101
|
{onCardPress && <TouchableOpacity style={styles.cardButton} onPress={cardPressHandler} />}
|
|
107
102
|
{shouldShowCarousel ? (
|
|
108
103
|
<CarouselComponent
|
|
109
|
-
style={
|
|
104
|
+
style={styles.carousel}
|
|
110
105
|
imagesToRender={cardCarouselImages ?? []}
|
|
111
106
|
carouselSize={{
|
|
112
107
|
width: cardSize.width,
|
|
113
|
-
height: cardSize.height -
|
|
108
|
+
height: cardSize.height - 60,
|
|
114
109
|
}}
|
|
115
110
|
testID={concatTestID(testID, 'carousel')}
|
|
116
111
|
/>
|
|
117
112
|
) : null}
|
|
118
113
|
<TouchableOpacity
|
|
119
|
-
onLayout={onHeaderLayoutChange}
|
|
120
114
|
activeOpacity={0.9}
|
|
121
115
|
disabled={!onHeaderPress}
|
|
122
116
|
onPress={headerPressHandler}
|
|
@@ -151,9 +145,8 @@ const styles = StyleSheet.create({
|
|
|
151
145
|
position: 'absolute',
|
|
152
146
|
width: '100%',
|
|
153
147
|
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
width: '100%',
|
|
148
|
+
carousel: {
|
|
149
|
+
marginTop: 60,
|
|
157
150
|
},
|
|
158
151
|
header: {
|
|
159
152
|
position: 'absolute',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
1
|
+
import type { Meta, StoryContext, StoryObj } from '@storybook/react';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { StyleSheet, Text, View } from 'react-native';
|
|
3
|
+
import { Dimensions, StyleSheet, Text, View } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import CredentialDetailsCardBackground from '../../../../storybook/assets/CredentialCardBackground.png';
|
|
6
6
|
import { Placeholder } from '../../../../storybook/placeholder';
|
|
@@ -23,8 +23,17 @@ const style = StyleSheet.create({
|
|
|
23
23
|
},
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
const Render = (
|
|
27
|
-
|
|
26
|
+
const Render = (args: CredentialDetailsCardProps, context: StoryContext<CredentialDetailsCardProps>) => {
|
|
27
|
+
const viewport = context.parameters.viewport.viewports[context.userGlobals.viewport];
|
|
28
|
+
const width = parseInt(viewport.styles.width.replace('px', ''), 10) - 32;
|
|
29
|
+
const props = {
|
|
30
|
+
...args,
|
|
31
|
+
card: {
|
|
32
|
+
...args.card,
|
|
33
|
+
width,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
return <CredentialDetailsCard {...props} style={style.card} />;
|
|
28
37
|
};
|
|
29
38
|
|
|
30
39
|
const Basic: StoryObj<typeof CredentialDetailsCard> = {
|
|
@@ -270,6 +279,7 @@ const Basic: StoryObj<typeof CredentialDetailsCard> = {
|
|
|
270
279
|
text: 'Notice related to the credential',
|
|
271
280
|
noticeIcon: CredentialNoticeWarningIcon,
|
|
272
281
|
},
|
|
282
|
+
width: Dimensions.get('screen').width - 32,
|
|
273
283
|
},
|
|
274
284
|
showAllButtonLabel: 'See all',
|
|
275
285
|
expanded: true,
|
|
@@ -7,7 +7,7 @@ import { Button, ButtonType } from '../../buttons';
|
|
|
7
7
|
import { DownIcon, UpIcon } from '../../icons/credential';
|
|
8
8
|
import { useAppColorScheme } from '../../theme/color-scheme-context';
|
|
9
9
|
import CredentialAttributeItem, { CredentialAttribute } from '../credential-attribute-item';
|
|
10
|
-
import CredentialCard, { CredentialCardProps } from './credential-card';
|
|
10
|
+
import CredentialCard, { CredentialCardProps, CredentialCardRatio } from './credential-card';
|
|
11
11
|
|
|
12
12
|
export type CredentialDetailsCardProps = ViewProps & {
|
|
13
13
|
animate?: boolean;
|
|
@@ -21,6 +21,7 @@ export type CredentialDetailsCardProps = ViewProps & {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const PREVIEW_ATTRIBUTES_COUNT = 3;
|
|
24
|
+
const SEE_ALL_BUTTON_HEIGHT = 78;
|
|
24
25
|
|
|
25
26
|
const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
26
27
|
animate = true,
|
|
@@ -38,7 +39,6 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
38
39
|
const colorScheme = useAppColorScheme();
|
|
39
40
|
const [previewAttributesHeight, setPreviewAttributesHeight] = useState<number>();
|
|
40
41
|
const [fullAttributesHeight, setFullAttributesHeight] = useState<number>();
|
|
41
|
-
const [buttonViewHeight, setButtonViewHeight] = useState<number>();
|
|
42
42
|
|
|
43
43
|
const [allAttributesRendered, setAllAttributesRendered] = useState<boolean>(
|
|
44
44
|
(attributes && attributes.length <= PREVIEW_ATTRIBUTES_COUNT) || !showAllButtonLabel,
|
|
@@ -46,17 +46,12 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
46
46
|
|
|
47
47
|
const CaretIcon = expanded ? UpIcon : DownIcon;
|
|
48
48
|
|
|
49
|
+
const cardHeight = Math.ceil(card.width / CredentialCardRatio);
|
|
49
50
|
const currentHeight = useSharedValue<number | undefined>(undefined);
|
|
50
51
|
|
|
51
52
|
const previewAttributes = attributes ? attributes.slice(0, PREVIEW_ATTRIBUTES_COUNT) : [];
|
|
52
53
|
const extraAttributes = useMemo(() => (attributes ? attributes.slice(PREVIEW_ATTRIBUTES_COUNT) : []), [attributes]);
|
|
53
54
|
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
if (!extraAttributes || allAttributesRendered) {
|
|
56
|
-
setButtonViewHeight(0);
|
|
57
|
-
}
|
|
58
|
-
}, [extraAttributes, allAttributesRendered]);
|
|
59
|
-
|
|
60
55
|
useEffect(() => {
|
|
61
56
|
if (extraAttributes.length === 0) {
|
|
62
57
|
const viewStyle = StyleSheet.flatten([
|
|
@@ -69,53 +64,56 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
69
64
|
}, [extraAttributes, footer]);
|
|
70
65
|
|
|
71
66
|
useEffect(() => {
|
|
72
|
-
if (previewAttributesHeight === undefined
|
|
67
|
+
if (previewAttributesHeight === undefined) {
|
|
73
68
|
return;
|
|
74
69
|
}
|
|
75
70
|
if (allAttributesRendered && fullAttributesHeight === undefined) {
|
|
76
71
|
return;
|
|
77
72
|
}
|
|
78
73
|
|
|
74
|
+
const buttonViewHeight = !extraAttributes || allAttributesRendered ? 0 : SEE_ALL_BUTTON_HEIGHT;
|
|
79
75
|
const additionalAttributesHeight = fullAttributesHeight ?? 0;
|
|
80
76
|
const additionalHeight = allAttributesRendered ? additionalAttributesHeight : buttonViewHeight;
|
|
81
|
-
const
|
|
77
|
+
const fullHeight = previewAttributesHeight + additionalHeight;
|
|
78
|
+
|
|
79
|
+
if (!animate) {
|
|
80
|
+
currentHeight.value = fullHeight;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const newHeight = expanded ? fullHeight : 0;
|
|
82
85
|
|
|
83
86
|
if (currentHeight.value === undefined || !animate) {
|
|
84
87
|
currentHeight.value = newHeight;
|
|
85
88
|
return;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
const duration =
|
|
89
|
-
? 250
|
|
90
|
-
: allAttributesRendered
|
|
91
|
-
? previewAttributes.length * 50
|
|
92
|
-
: extraAttributes.length * 50;
|
|
91
|
+
const duration = fullHeight / 5;
|
|
93
92
|
currentHeight.value = withTiming(newHeight, {
|
|
94
93
|
duration,
|
|
95
94
|
});
|
|
96
95
|
}, [
|
|
97
96
|
allAttributesRendered,
|
|
98
|
-
buttonViewHeight,
|
|
99
97
|
currentHeight,
|
|
100
98
|
animate,
|
|
101
99
|
expanded,
|
|
102
|
-
extraAttributes
|
|
100
|
+
extraAttributes,
|
|
103
101
|
fullAttributesHeight,
|
|
104
102
|
previewAttributes.length,
|
|
105
103
|
previewAttributesHeight,
|
|
106
104
|
]);
|
|
107
105
|
|
|
108
|
-
const
|
|
106
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
109
107
|
if (currentHeight.value === undefined) {
|
|
110
108
|
if (expanded) {
|
|
111
109
|
return {};
|
|
112
110
|
}
|
|
113
111
|
return {
|
|
114
|
-
height:
|
|
112
|
+
height: cardHeight,
|
|
115
113
|
};
|
|
116
114
|
}
|
|
117
115
|
return {
|
|
118
|
-
height: currentHeight.value,
|
|
116
|
+
height: cardHeight + currentHeight.value,
|
|
119
117
|
};
|
|
120
118
|
}, [expanded, currentHeight]);
|
|
121
119
|
|
|
@@ -127,10 +125,6 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
127
125
|
setFullAttributesHeight(event.nativeEvent.layout.height);
|
|
128
126
|
}, []);
|
|
129
127
|
|
|
130
|
-
const onButtonViewLayout = useCallback((event: LayoutChangeEvent) => {
|
|
131
|
-
setButtonViewHeight(event.nativeEvent.layout.height);
|
|
132
|
-
}, []);
|
|
133
|
-
|
|
134
128
|
const footerView: ReactElement | undefined = useMemo(() => {
|
|
135
129
|
if (!footer) {
|
|
136
130
|
return undefined;
|
|
@@ -147,9 +141,11 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
147
141
|
|
|
148
142
|
const renderExtraAttributes =
|
|
149
143
|
allAttributesRendered || (previewAttributesHeight !== undefined && currentHeight.value !== undefined);
|
|
144
|
+
|
|
145
|
+
const ContainerComponent = animate ? Animated.View : View;
|
|
150
146
|
return (
|
|
151
|
-
<
|
|
152
|
-
style={[styles.detailsCard, { backgroundColor: colorScheme.white }, style]}
|
|
147
|
+
<ContainerComponent
|
|
148
|
+
style={[styles.detailsCard, { backgroundColor: colorScheme.white }, animate ? animatedStyle : undefined, style]}
|
|
153
149
|
{...viewProps}
|
|
154
150
|
testID={concatTestID(card.testID, expanded ? 'expanded' : 'collapsed')}>
|
|
155
151
|
<CredentialCard
|
|
@@ -158,7 +154,7 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
158
154
|
style={[styles.card, cardProps.style]}
|
|
159
155
|
/>
|
|
160
156
|
{previewAttributes.length > 0 && (
|
|
161
|
-
<
|
|
157
|
+
<View>
|
|
162
158
|
<View style={styles.attributesWrapper}>
|
|
163
159
|
<View onLayout={onPreviewAttrContentLayout} style={styles.previewAttributesWrapper}>
|
|
164
160
|
{previewAttributes.map((attribute, idx) => (
|
|
@@ -173,7 +169,7 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
173
169
|
))}
|
|
174
170
|
</View>
|
|
175
171
|
{!allAttributesRendered && extraAttributes.length > 0 && (
|
|
176
|
-
<View style={styles.
|
|
172
|
+
<View style={styles.buttonWrapper}>
|
|
177
173
|
<Button
|
|
178
174
|
onPress={() => setAllAttributesRendered(true)}
|
|
179
175
|
type={ButtonType.Secondary}
|
|
@@ -199,10 +195,10 @@ const CredentialDetailsCard: FC<CredentialDetailsCardProps> = ({
|
|
|
199
195
|
</View>
|
|
200
196
|
)}
|
|
201
197
|
</View>
|
|
202
|
-
</
|
|
198
|
+
</View>
|
|
203
199
|
)}
|
|
204
200
|
{footerView ? <View style={styles.footer}>{footerView}</View> : null}
|
|
205
|
-
</
|
|
201
|
+
</ContainerComponent>
|
|
206
202
|
);
|
|
207
203
|
};
|
|
208
204
|
|
|
@@ -215,12 +211,14 @@ const styles = StyleSheet.create({
|
|
|
215
211
|
allAttributesWrapperWithFooter: {
|
|
216
212
|
paddingBottom: 0,
|
|
217
213
|
},
|
|
218
|
-
attributesAnimatedWrapper: {
|
|
219
|
-
overflow: 'hidden',
|
|
220
|
-
},
|
|
221
214
|
attributesWrapper: {
|
|
222
215
|
paddingTop: 7,
|
|
223
|
-
|
|
216
|
+
width: '100%',
|
|
217
|
+
},
|
|
218
|
+
buttonWrapper: {
|
|
219
|
+
height: SEE_ALL_BUTTON_HEIGHT,
|
|
220
|
+
paddingBottom: 12,
|
|
221
|
+
paddingHorizontal: 4,
|
|
224
222
|
width: '100%',
|
|
225
223
|
},
|
|
226
224
|
card: {
|
|
@@ -52,20 +52,24 @@ const CredentialDetailsCardListItem: FC<CredentialDetailsCardListItemProps> = ({
|
|
|
52
52
|
}, [cardListItemHeight, lastItem, expanded]);
|
|
53
53
|
|
|
54
54
|
const cardWrapperStyle: ViewStyle = {
|
|
55
|
-
minHeight: cardWidth ? cardWidth / CredentialCardRatio : undefined,
|
|
55
|
+
minHeight: cardWidth ? Math.ceil(cardWidth / CredentialCardRatio) : undefined,
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const onContentLayout = useCallback(
|
|
59
59
|
(event: LayoutChangeEvent) => {
|
|
60
60
|
const { width, height } = event.nativeEvent.layout;
|
|
61
|
+
const borderWidth = StyleSheet.flatten(style)?.borderWidth ?? 0;
|
|
62
|
+
const cardHeight = Math.round(height) + 2 * borderWidth;
|
|
63
|
+
if (cardHeight === detailsCardHeight) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
61
66
|
setCardWidth(width);
|
|
62
67
|
if (!minHeight) {
|
|
63
|
-
setMinHeight(lastItem ? width / CredentialCardRatio : 60);
|
|
68
|
+
setMinHeight(lastItem ? Math.ceil(width / CredentialCardRatio) : 60);
|
|
64
69
|
}
|
|
65
|
-
|
|
66
|
-
setDetailsCardHeight(height + 2 * borderWidth);
|
|
70
|
+
setDetailsCardHeight(cardHeight);
|
|
67
71
|
},
|
|
68
|
-
[lastItem, minHeight, style],
|
|
72
|
+
[lastItem, minHeight, style, detailsCardHeight],
|
|
69
73
|
);
|
|
70
74
|
|
|
71
75
|
return (
|
|
@@ -73,7 +77,7 @@ const CredentialDetailsCardListItem: FC<CredentialDetailsCardListItemProps> = ({
|
|
|
73
77
|
<View style={[styles.cardWrapper, cardWrapperStyle]}>
|
|
74
78
|
<CredentialDetailsCard
|
|
75
79
|
animate={false}
|
|
76
|
-
expanded={
|
|
80
|
+
expanded={true}
|
|
77
81
|
onLayout={onContentLayout}
|
|
78
82
|
style={detailsCardStyle}
|
|
79
83
|
{...props}
|
|
@@ -18,11 +18,11 @@ const Render = ({ onRightAction, contentHeight, headerProps }: Args) => {
|
|
|
18
18
|
<DetailScreen
|
|
19
19
|
headerProps={{
|
|
20
20
|
...headerProps,
|
|
21
|
-
|
|
21
|
+
rightButtons: [
|
|
22
22
|
<TouchableOpacity onPress={onRightAction} hitSlop={hitSlop}>
|
|
23
23
|
<Placeholder id="R" style={styles.rightButton} />
|
|
24
|
-
</TouchableOpacity
|
|
25
|
-
|
|
24
|
+
</TouchableOpacity>,
|
|
25
|
+
],
|
|
26
26
|
}}>
|
|
27
27
|
<Placeholder id="Content" style={[contentHeight ? { height: contentHeight } : styles.content]} />
|
|
28
28
|
</DetailScreen>
|
|
@@ -16,12 +16,14 @@ const Render = ({ onBack, withBackButton, withRightButton, ...args }: Args) => {
|
|
|
16
16
|
<Header
|
|
17
17
|
{...args}
|
|
18
18
|
onBack={withBackButton ? onBack : undefined}
|
|
19
|
-
|
|
20
|
-
withRightButton
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
rightButtons={
|
|
20
|
+
withRightButton
|
|
21
|
+
? [
|
|
22
|
+
<TouchableOpacity>
|
|
23
|
+
<Placeholder id="R" style={styles.rightButton} />
|
|
24
|
+
</TouchableOpacity>,
|
|
25
|
+
]
|
|
26
|
+
: undefined
|
|
25
27
|
}
|
|
26
28
|
/>
|
|
27
29
|
);
|
|
@@ -8,7 +8,7 @@ import { useAppColorScheme } from '../theme';
|
|
|
8
8
|
|
|
9
9
|
export interface HeaderProps extends ViewProps {
|
|
10
10
|
onBack?: () => void;
|
|
11
|
-
|
|
11
|
+
rightButtons?: ReactNode[];
|
|
12
12
|
style?: StyleProp<ViewStyle>;
|
|
13
13
|
titleRowStyle?: StyleProp<ViewStyle>;
|
|
14
14
|
title: ReactNode;
|
|
@@ -22,7 +22,7 @@ const backButtonHitSlop: Insets = { top: 12, bottom: 12, left: 20, right: 20 };
|
|
|
22
22
|
* Following the design: https://www.figma.com/file/52qDYWUMjXAGre1dcnz5bz/Procivis-One-Wallet?node-id=425-18624
|
|
23
23
|
* states (Default + Dashboard)
|
|
24
24
|
*/
|
|
25
|
-
const Header: FC<HeaderProps> = ({ onBack,
|
|
25
|
+
const Header: FC<HeaderProps> = ({ onBack, rightButtons, style, titleRowStyle, testID, title, ...viewProps }) => {
|
|
26
26
|
const colorScheme = useAppColorScheme();
|
|
27
27
|
|
|
28
28
|
return (
|
|
@@ -31,7 +31,7 @@ const Header: FC<HeaderProps> = ({ onBack, rightButton, style, titleRowStyle, te
|
|
|
31
31
|
<View style={styles.backButtonRow}>
|
|
32
32
|
<BackButton hitSlop={backButtonHitSlop} onPress={onBack} testID={concatTestID(testID, 'back')} />
|
|
33
33
|
<View />
|
|
34
|
-
{
|
|
34
|
+
{rightButtons}
|
|
35
35
|
</View>
|
|
36
36
|
)}
|
|
37
37
|
|
|
@@ -39,7 +39,7 @@ const Header: FC<HeaderProps> = ({ onBack, rightButton, style, titleRowStyle, te
|
|
|
39
39
|
style={[
|
|
40
40
|
styles.titleRow,
|
|
41
41
|
onBack ? styles.titleRow2nd : styles.titleRowNoBackButton,
|
|
42
|
-
(onBack || !
|
|
42
|
+
(onBack || !rightButtons) && styles.titleRowNoRightButton,
|
|
43
43
|
titleRowStyle,
|
|
44
44
|
]}>
|
|
45
45
|
{typeof title === 'string' ? (
|
|
@@ -55,7 +55,7 @@ const Header: FC<HeaderProps> = ({ onBack, rightButton, style, titleRowStyle, te
|
|
|
55
55
|
<View style={styles.title}>{title}</View>
|
|
56
56
|
)}
|
|
57
57
|
|
|
58
|
-
{!onBack &&
|
|
58
|
+
{!onBack && rightButtons && <View style={styles.rightButtonWrapper}>{rightButtons}</View>}
|
|
59
59
|
</View>
|
|
60
60
|
</View>
|
|
61
61
|
);
|
|
@@ -75,6 +75,8 @@ const styles = StyleSheet.create({
|
|
|
75
75
|
},
|
|
76
76
|
rightButtonWrapper: {
|
|
77
77
|
alignItems: 'center',
|
|
78
|
+
flexDirection: 'row',
|
|
79
|
+
gap: '16',
|
|
78
80
|
height: 48,
|
|
79
81
|
justifyContent: 'center',
|
|
80
82
|
paddingHorizontal: 12,
|