@proximus/lavender-cards-native 0.0.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BackgroundImageLinearGradientContainer.d.ts +13 -0
- package/dist/BackgroundImageLinearGradientContainer.d.ts.map +1 -0
- package/dist/Content.d.ts +7 -0
- package/dist/Content.d.ts.map +1 -0
- package/dist/PxCard.d.ts +20 -0
- package/dist/PxCard.d.ts.map +1 -0
- package/dist/PxMessageCard.d.ts +18 -0
- package/dist/PxMessageCard.d.ts.map +1 -0
- package/dist/Title.d.ts +8 -0
- package/dist/Title.d.ts.map +1 -0
- package/dist/__tests__/PxCard.spec.d.ts +2 -0
- package/dist/__tests__/PxCard.spec.d.ts.map +1 -0
- package/dist/__tests__/PxMessageCard.spec.d.ts +2 -0
- package/dist/__tests__/PxMessageCard.spec.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/package.json +43 -0
- package/src/BackgroundImageLinearGradientContainer.tsx +80 -0
- package/src/Content.tsx +30 -0
- package/src/PxCard.tsx +157 -0
- package/src/PxMessageCard.tsx +174 -0
- package/src/Title.tsx +32 -0
- package/src/__tests__/PxCard.spec.tsx +143 -0
- package/src/__tests__/PxMessageCard.spec.tsx +80 -0
- package/src/index.ts +2 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ImageSourcePropType } from 'react-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface BackgroundImageLinearGradientContainerProps {
|
|
4
|
+
src?: ImageSourcePropType;
|
|
5
|
+
alternativeText?: string;
|
|
6
|
+
contrastHelper?: 'overlay' | 'gradient';
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
backgroundColor?: 'Default' | 'Light';
|
|
9
|
+
inverted?: boolean;
|
|
10
|
+
gradientDirection?: 'horizontal' | 'vertical';
|
|
11
|
+
}
|
|
12
|
+
export declare function BackgroundImageLinearGradientContainer(props: BackgroundImageLinearGradientContainerProps): React.JSX.Element;
|
|
13
|
+
//# sourceMappingURL=BackgroundImageLinearGradientContainer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BackgroundImageLinearGradientContainer.d.ts","sourceRoot":"","sources":["../src/BackgroundImageLinearGradientContainer.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,2CAA2C;IAC1D,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACxC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CAC/C;AAkBD,wBAAgB,sCAAsC,CACpD,KAAK,EAAE,2CAA2C,qBA+CnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Content.d.ts","sourceRoot":"","sources":["../src/Content.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,IAAU,EACV,QAAgB,GACjB,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,qBAiBA"}
|
package/dist/PxCard.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AccessibilityProps, ImageResizeMode, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { BackgroundImageLinearGradientContainerProps } from './BackgroundImageLinearGradientContainer';
|
|
4
|
+
export interface PxCardMediaProps {
|
|
5
|
+
mediaPosition?: 'top' | 'left' | 'background';
|
|
6
|
+
}
|
|
7
|
+
export interface ICardProps extends Pick<AccessibilityProps, 'accessibilityLabel' | 'accessibilityHint'>, BackgroundImageLinearGradientContainerProps {
|
|
8
|
+
title: string;
|
|
9
|
+
content?: string;
|
|
10
|
+
backgroundColor?: 'Default' | 'Light';
|
|
11
|
+
backgroundSize?: ImageResizeMode;
|
|
12
|
+
testID?: string;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
onPress?: () => void;
|
|
15
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
16
|
+
inverted?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function MediaPart(props: ICardProps & PxCardMediaProps): React.JSX.Element;
|
|
19
|
+
export declare function PxCard(props: ICardProps & PxCardMediaProps): React.JSX.Element;
|
|
20
|
+
//# sourceMappingURL=PxCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PxCard.d.ts","sourceRoot":"","sources":["../src/PxCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,kBAAkB,EAElB,eAAe,EACf,SAAS,EAGT,SAAS,EACV,MAAM,cAAc,CAAC;AAOtB,OAAO,EAEL,2CAA2C,EAC5C,MAAM,0CAA0C,CAAC;AAIlD,MAAM,WAAW,gBAAgB;IAC/B,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,YAAY,CAAC;CAC/C;AAED,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,kBAAkB,EAAE,oBAAoB,GAAG,mBAAmB,CAAC,EAC1E,2CAA2C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IACtC,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,qBAwD7D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,qBAyD1D"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ICardProps } from './PxCard';
|
|
3
|
+
import { ImageURISource } from 'react-native';
|
|
4
|
+
export interface PxMessageCardProps extends ICardProps {
|
|
5
|
+
ctaLabel: string;
|
|
6
|
+
ctaAccessibilityLabel?: string;
|
|
7
|
+
ctaAccessibilityHint?: string;
|
|
8
|
+
imageLayout?: 'leading' | 'background';
|
|
9
|
+
src?: ImageURISource;
|
|
10
|
+
closeButtonSize?: 'small' | 'default';
|
|
11
|
+
closeButtonAccessibilityLabel?: string;
|
|
12
|
+
closeButtonAccessibilityHint?: string;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
tag?: string;
|
|
15
|
+
height?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function PxMessageCard(props: PxMessageCardProps): React.JSX.Element;
|
|
18
|
+
//# sourceMappingURL=PxMessageCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PxMessageCard.d.ts","sourceRoot":"","sources":["../src/PxMessageCard.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAS,cAAc,EAAQ,MAAM,cAAc,CAAC;AAM3D,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IAEvC,GAAG,CAAC,EAAE,cAAc,CAAC;IAErB,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,qBA4FtD"}
|
package/dist/Title.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Title.d.ts","sourceRoot":"","sources":["../src/Title.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,IAAY,EACZ,KAAe,EACf,QAAgB,GACjB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,qBAiBA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PxCard.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/PxCard.spec.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PxMessageCard.spec.d.ts","sourceRoot":"","sources":["../../src/__tests__/PxMessageCard.spec.tsx"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@proximus/lavender-cards-native",
|
|
3
|
+
"version": "0.0.1-alpha.0",
|
|
4
|
+
"description": "Card component",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"clean": "rm -rf dist",
|
|
9
|
+
"prepublish": "yarn clean && yarn build",
|
|
10
|
+
"build": "npx tsc -p tsconfig.json"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@proximus/lavender-button-native": "workspace:*",
|
|
14
|
+
"@proximus/lavender-buttonicon-native": "workspace:*",
|
|
15
|
+
"@proximus/lavender-common-native": "workspace:*",
|
|
16
|
+
"@proximus/lavender-styling-native": "workspace:*",
|
|
17
|
+
"@proximus/lavender-tag-native": "workspace:*",
|
|
18
|
+
"@proximus/lavender-texts-native": "workspace:*"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@proximus/lavender-button-native": "0.1.0-alpha.5",
|
|
22
|
+
"@proximus/lavender-buttonicon-native": "0.1.0-alpha.4",
|
|
23
|
+
"@proximus/lavender-common-native": "0.1.0-alpha.4",
|
|
24
|
+
"@proximus/lavender-styling-native": "0.1.0-alpha.3",
|
|
25
|
+
"@proximus/lavender-tag-native": "0.1.0-alpha.1",
|
|
26
|
+
"@proximus/lavender-texts-native": "0.1.0-alpha.4"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"lerna": {
|
|
32
|
+
"command": {
|
|
33
|
+
"publish": {
|
|
34
|
+
"assets": [
|
|
35
|
+
"dist",
|
|
36
|
+
"src",
|
|
37
|
+
"package.json"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"gitHead": "8794f25d197ead361646d6e655ce64ba1c7f60c0"
|
|
43
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
2
|
+
import { ImageBackground, ImageSourcePropType } from 'react-native';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { useTheme } from '@proximus/lavender-styling-native';
|
|
5
|
+
|
|
6
|
+
export interface BackgroundImageLinearGradientContainerProps {
|
|
7
|
+
src?: ImageSourcePropType;
|
|
8
|
+
alternativeText?: string;
|
|
9
|
+
contrastHelper?: 'overlay' | 'gradient';
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
backgroundColor?: 'Default' | 'Light';
|
|
12
|
+
inverted?: boolean;
|
|
13
|
+
gradientDirection?: 'horizontal' | 'vertical';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function useStyles(props: BackgroundImageLinearGradientContainerProps) {
|
|
17
|
+
const { theme } = useTheme();
|
|
18
|
+
const { inverted = false, backgroundColor = 'Default' } = props;
|
|
19
|
+
return {
|
|
20
|
+
gradientColors: inverted
|
|
21
|
+
? ['#252525FF', '#252525DD', '#25252500']
|
|
22
|
+
: ['#FFFFFF', '#FFFFFFDD', '#FFFFFF00'],
|
|
23
|
+
backgroundColor: inverted
|
|
24
|
+
? theme.t(`ColorBackgroundContainer${backgroundColor}Inverted`)
|
|
25
|
+
: theme.t(`ColorBackgroundContainer${backgroundColor}Default`),
|
|
26
|
+
contrastColors: inverted
|
|
27
|
+
? ['rgba(0,0,0,0.6)', 'rgba(0,0,0,0.6)']
|
|
28
|
+
: ['rgba(255,255,255,0.7)', 'rgba(255,255,255,0.7)'],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function BackgroundImageLinearGradientContainer(
|
|
33
|
+
props: BackgroundImageLinearGradientContainerProps
|
|
34
|
+
) {
|
|
35
|
+
const { theme } = useTheme();
|
|
36
|
+
const styles = useStyles(props);
|
|
37
|
+
|
|
38
|
+
const {
|
|
39
|
+
src,
|
|
40
|
+
alternativeText = 'Image',
|
|
41
|
+
contrastHelper = 'none',
|
|
42
|
+
children,
|
|
43
|
+
gradientDirection = 'diagonal',
|
|
44
|
+
} = props;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<ImageBackground
|
|
48
|
+
alt={alternativeText}
|
|
49
|
+
imageStyle={{
|
|
50
|
+
borderRadius: theme.t('RadiusMain').number,
|
|
51
|
+
}}
|
|
52
|
+
style={{
|
|
53
|
+
flex: 1,
|
|
54
|
+
}}
|
|
55
|
+
resizeMode={'cover'}
|
|
56
|
+
source={src}
|
|
57
|
+
>
|
|
58
|
+
<LinearGradient
|
|
59
|
+
colors={[styles.backgroundColor, styles.backgroundColor]}
|
|
60
|
+
{...(contrastHelper === 'gradient' && {
|
|
61
|
+
colors: styles.gradientColors,
|
|
62
|
+
...(gradientDirection === 'horizontal'
|
|
63
|
+
? {
|
|
64
|
+
start: { x: 0, y: 1.0 },
|
|
65
|
+
end: { x: 1.0, y: 1.0 },
|
|
66
|
+
}
|
|
67
|
+
: {
|
|
68
|
+
start: { x: 0.0, y: 1.0 },
|
|
69
|
+
end: { x: 0.0, y: 0.0 },
|
|
70
|
+
}),
|
|
71
|
+
})}
|
|
72
|
+
{...(contrastHelper === 'overlay' && {
|
|
73
|
+
colors: styles.contrastColors,
|
|
74
|
+
})}
|
|
75
|
+
>
|
|
76
|
+
{children}
|
|
77
|
+
</LinearGradient>
|
|
78
|
+
</ImageBackground>
|
|
79
|
+
);
|
|
80
|
+
}
|
package/src/Content.tsx
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Body } from '@proximus/lavender-texts-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useTheme } from '@proximus/lavender-styling-native';
|
|
4
|
+
|
|
5
|
+
export function Content({
|
|
6
|
+
content,
|
|
7
|
+
size = 'M',
|
|
8
|
+
inverted = false,
|
|
9
|
+
}: {
|
|
10
|
+
content: string;
|
|
11
|
+
size?: 'M' | 'L';
|
|
12
|
+
inverted?: boolean;
|
|
13
|
+
}) {
|
|
14
|
+
const { theme } = useTheme();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Body
|
|
18
|
+
style={{
|
|
19
|
+
color: inverted
|
|
20
|
+
? theme.t(`ColorTextDimmedInverted`)
|
|
21
|
+
: theme.t(`ColorTextNeutralDefault`),
|
|
22
|
+
fontSize: theme.t(`TextSizeBody${size}Mobile`).number,
|
|
23
|
+
}}
|
|
24
|
+
ellipsizeMode={'tail'}
|
|
25
|
+
numberOfLines={3}
|
|
26
|
+
>
|
|
27
|
+
{content}
|
|
28
|
+
</Body>
|
|
29
|
+
);
|
|
30
|
+
}
|
package/src/PxCard.tsx
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
AccessibilityProps,
|
|
4
|
+
Image,
|
|
5
|
+
ImageResizeMode,
|
|
6
|
+
StyleProp,
|
|
7
|
+
TouchableOpacity,
|
|
8
|
+
View,
|
|
9
|
+
ViewStyle,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
import { useTheme } from '@proximus/lavender-styling-native';
|
|
12
|
+
import {
|
|
13
|
+
a11y,
|
|
14
|
+
e2eID,
|
|
15
|
+
useImageAspectRatio,
|
|
16
|
+
} from '@proximus/lavender-common-native';
|
|
17
|
+
import {
|
|
18
|
+
BackgroundImageLinearGradientContainer,
|
|
19
|
+
BackgroundImageLinearGradientContainerProps,
|
|
20
|
+
} from './BackgroundImageLinearGradientContainer';
|
|
21
|
+
import { Title } from './Title';
|
|
22
|
+
import { Content } from './Content';
|
|
23
|
+
|
|
24
|
+
export interface PxCardMediaProps {
|
|
25
|
+
mediaPosition?: 'top' | 'left' | 'background';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ICardProps
|
|
29
|
+
extends Pick<AccessibilityProps, 'accessibilityLabel' | 'accessibilityHint'>,
|
|
30
|
+
BackgroundImageLinearGradientContainerProps {
|
|
31
|
+
title: string;
|
|
32
|
+
content?: string;
|
|
33
|
+
backgroundColor?: 'Default' | 'Light';
|
|
34
|
+
backgroundSize?: ImageResizeMode;
|
|
35
|
+
testID?: string;
|
|
36
|
+
children?: React.ReactNode;
|
|
37
|
+
onPress?: () => void;
|
|
38
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
39
|
+
inverted?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function MediaPart(props: ICardProps & PxCardMediaProps) {
|
|
43
|
+
const { theme } = useTheme();
|
|
44
|
+
|
|
45
|
+
const {
|
|
46
|
+
src,
|
|
47
|
+
backgroundSize = 'cover',
|
|
48
|
+
mediaPosition = 'top',
|
|
49
|
+
alternativeText,
|
|
50
|
+
} = props;
|
|
51
|
+
|
|
52
|
+
const aspectRatio = useImageAspectRatio(src);
|
|
53
|
+
const [wrapperHeight, setWrapperHeight] = React.useState<number | undefined>(
|
|
54
|
+
undefined
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
If we don’t set width (or height), RN needs one concrete dimension for image. Local assets
|
|
59
|
+
have an intrinsic size, so they render at that size (can be wider than the parent).
|
|
60
|
+
Remote images often don’t have an intrinsic size at first and end up constrained by
|
|
61
|
+
the parent, so they look correct.
|
|
62
|
+
|
|
63
|
+
We then wrap the image in a View to be able to set the aspect ratio and
|
|
64
|
+
make sure Image takes the full width of the card when mediaPosition is 'top'.
|
|
65
|
+
*/
|
|
66
|
+
return (
|
|
67
|
+
<View
|
|
68
|
+
style={mediaPosition === 'top' && { width: '100%', aspectRatio }}
|
|
69
|
+
onLayout={(event) => {
|
|
70
|
+
// when media position is left, we need to set the height of the image to match the height of the wrapper
|
|
71
|
+
// which itself have the height of the taller's neighbor element
|
|
72
|
+
const { height } = event.nativeEvent.layout;
|
|
73
|
+
setWrapperHeight(height);
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
76
|
+
<Image
|
|
77
|
+
alt={alternativeText}
|
|
78
|
+
style={{
|
|
79
|
+
...(mediaPosition === 'top' && {
|
|
80
|
+
width: '100%',
|
|
81
|
+
height: '100%',
|
|
82
|
+
aspectRatio,
|
|
83
|
+
borderTopRightRadius: theme.t('RadiusMain').number,
|
|
84
|
+
borderTopLeftRadius: theme.t('RadiusMain').number,
|
|
85
|
+
}),
|
|
86
|
+
...(mediaPosition === 'left' && {
|
|
87
|
+
width: 120,
|
|
88
|
+
height: wrapperHeight,
|
|
89
|
+
borderBottomLeftRadius: theme.t('RadiusMain').number,
|
|
90
|
+
borderTopLeftRadius: theme.t('RadiusMain').number,
|
|
91
|
+
}),
|
|
92
|
+
}}
|
|
93
|
+
source={src}
|
|
94
|
+
resizeMode={backgroundSize}
|
|
95
|
+
/>
|
|
96
|
+
</View>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function PxCard(props: ICardProps & PxCardMediaProps) {
|
|
101
|
+
const {
|
|
102
|
+
title,
|
|
103
|
+
content,
|
|
104
|
+
children,
|
|
105
|
+
mediaPosition,
|
|
106
|
+
containerStyle,
|
|
107
|
+
accessibilityLabel,
|
|
108
|
+
accessibilityHint,
|
|
109
|
+
testID,
|
|
110
|
+
onPress,
|
|
111
|
+
src,
|
|
112
|
+
} = props;
|
|
113
|
+
|
|
114
|
+
const flexDirection = mediaPosition === 'left' ? 'row' : 'column';
|
|
115
|
+
|
|
116
|
+
const { theme } = useTheme();
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<TouchableOpacity onPress={onPress}>
|
|
120
|
+
<View
|
|
121
|
+
style={[
|
|
122
|
+
containerStyle,
|
|
123
|
+
{
|
|
124
|
+
overflow: 'hidden',
|
|
125
|
+
flexDirection,
|
|
126
|
+
borderRadius: theme.t('RadiusMain').number,
|
|
127
|
+
},
|
|
128
|
+
]}
|
|
129
|
+
{...e2eID(testID)}
|
|
130
|
+
{...a11y({
|
|
131
|
+
accessibilityLabel,
|
|
132
|
+
accessibilityHint,
|
|
133
|
+
role: 'button',
|
|
134
|
+
})}
|
|
135
|
+
>
|
|
136
|
+
{mediaPosition !== 'background' && <MediaPart {...props} />}
|
|
137
|
+
|
|
138
|
+
<BackgroundImageLinearGradientContainer
|
|
139
|
+
{...props}
|
|
140
|
+
src={mediaPosition !== 'background' ? undefined : src}
|
|
141
|
+
>
|
|
142
|
+
{/*wrapping linear gradient with content is needed as styling directly it is buggy*/}
|
|
143
|
+
<View
|
|
144
|
+
style={{
|
|
145
|
+
padding: theme.t(`PaddingMMobile`).number,
|
|
146
|
+
gap: theme.t(`PaddingSMobile`).number,
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
<Title title={title} />
|
|
150
|
+
{content && <Content content={content} />}
|
|
151
|
+
{children}
|
|
152
|
+
</View>
|
|
153
|
+
</BackgroundImageLinearGradientContainer>
|
|
154
|
+
</View>
|
|
155
|
+
</TouchableOpacity>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { a11y, e2eID, PxSpacer } from '@proximus/lavender-common-native';
|
|
2
|
+
import { Title } from './Title';
|
|
3
|
+
import { Content } from './Content';
|
|
4
|
+
import { BackgroundImageLinearGradientContainer } from './BackgroundImageLinearGradientContainer';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { ICardProps } from './PxCard';
|
|
7
|
+
import { Image, ImageURISource, View } from 'react-native';
|
|
8
|
+
import { useTheme } from '@proximus/lavender-styling-native';
|
|
9
|
+
import { PxButton } from '@proximus/lavender-button-native';
|
|
10
|
+
import { PxButtonIcon } from '@proximus/lavender-buttonicon-native';
|
|
11
|
+
import { PxTag } from '@proximus/lavender-tag-native';
|
|
12
|
+
|
|
13
|
+
export interface PxMessageCardProps extends ICardProps {
|
|
14
|
+
ctaLabel: string;
|
|
15
|
+
ctaAccessibilityLabel?: string;
|
|
16
|
+
ctaAccessibilityHint?: string;
|
|
17
|
+
|
|
18
|
+
imageLayout?: 'leading' | 'background';
|
|
19
|
+
|
|
20
|
+
src?: ImageURISource;
|
|
21
|
+
|
|
22
|
+
closeButtonSize?: 'small' | 'default';
|
|
23
|
+
closeButtonAccessibilityLabel?: string;
|
|
24
|
+
closeButtonAccessibilityHint?: string;
|
|
25
|
+
onClose: () => void;
|
|
26
|
+
|
|
27
|
+
tag?: string;
|
|
28
|
+
height?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function PxMessageCard(props: PxMessageCardProps) {
|
|
32
|
+
const {
|
|
33
|
+
children,
|
|
34
|
+
containerStyle,
|
|
35
|
+
accessibilityLabel,
|
|
36
|
+
accessibilityHint,
|
|
37
|
+
testID,
|
|
38
|
+
ctaLabel,
|
|
39
|
+
ctaAccessibilityLabel,
|
|
40
|
+
ctaAccessibilityHint,
|
|
41
|
+
onPress,
|
|
42
|
+
imageLayout = 'leading',
|
|
43
|
+
src,
|
|
44
|
+
onClose,
|
|
45
|
+
closeButtonSize = 'small',
|
|
46
|
+
closeButtonAccessibilityHint,
|
|
47
|
+
closeButtonAccessibilityLabel,
|
|
48
|
+
inverted,
|
|
49
|
+
tag,
|
|
50
|
+
backgroundColor = 'Light',
|
|
51
|
+
gradientDirection = 'vertical',
|
|
52
|
+
height,
|
|
53
|
+
} = props;
|
|
54
|
+
|
|
55
|
+
const { theme } = useTheme();
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<View
|
|
59
|
+
style={[
|
|
60
|
+
containerStyle,
|
|
61
|
+
{
|
|
62
|
+
overflow: 'hidden',
|
|
63
|
+
borderRadius: theme.t('RadiusMain').number,
|
|
64
|
+
height,
|
|
65
|
+
},
|
|
66
|
+
]}
|
|
67
|
+
{...e2eID(testID)}
|
|
68
|
+
{...a11y({
|
|
69
|
+
accessibilityLabel,
|
|
70
|
+
accessibilityHint,
|
|
71
|
+
role: 'button',
|
|
72
|
+
})}
|
|
73
|
+
>
|
|
74
|
+
<BackgroundImageLinearGradientContainer
|
|
75
|
+
{...props}
|
|
76
|
+
backgroundColor={backgroundColor}
|
|
77
|
+
src={imageLayout === 'background' ? src : undefined}
|
|
78
|
+
gradientDirection={gradientDirection}
|
|
79
|
+
>
|
|
80
|
+
<View
|
|
81
|
+
style={{
|
|
82
|
+
gap: theme.t('SpacingDefaultMobile').number,
|
|
83
|
+
padding: theme.t('PaddingSMobile').number,
|
|
84
|
+
height: '100%',
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
{tag && <TagSection {...props} />}
|
|
88
|
+
{height && <PxSpacer />}
|
|
89
|
+
<TitleSection {...props} />
|
|
90
|
+
{children}
|
|
91
|
+
<PxButton
|
|
92
|
+
title={ctaLabel}
|
|
93
|
+
onPress={onPress}
|
|
94
|
+
type="secondary"
|
|
95
|
+
accessibilityLabel={ctaAccessibilityLabel || ctaLabel}
|
|
96
|
+
accessibilityHint={ctaAccessibilityHint}
|
|
97
|
+
testID={`${testID ? testID : 'message-card'}-cta-button`}
|
|
98
|
+
inverted={inverted}
|
|
99
|
+
/>
|
|
100
|
+
<PxButtonIcon
|
|
101
|
+
size={closeButtonSize}
|
|
102
|
+
iconName={'cross'}
|
|
103
|
+
variant={'secondary'}
|
|
104
|
+
onPress={onClose}
|
|
105
|
+
wrapperStyle={{
|
|
106
|
+
position: 'absolute',
|
|
107
|
+
top: theme.t('SpacingSMobile').number,
|
|
108
|
+
right: theme.t('SpacingSMobile').number,
|
|
109
|
+
}}
|
|
110
|
+
inverted={inverted}
|
|
111
|
+
{...e2eID(
|
|
112
|
+
testID ? `${testID}-close-button` : 'message-card-close-button'
|
|
113
|
+
)}
|
|
114
|
+
{...a11y({
|
|
115
|
+
accessibilityLabel: `${closeButtonAccessibilityLabel || 'Close'}`,
|
|
116
|
+
accessibilityHint: closeButtonAccessibilityHint,
|
|
117
|
+
})}
|
|
118
|
+
/>
|
|
119
|
+
</View>
|
|
120
|
+
</BackgroundImageLinearGradientContainer>
|
|
121
|
+
</View>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function TitleSection(props: PxMessageCardProps) {
|
|
126
|
+
const { theme } = useTheme();
|
|
127
|
+
const { imageLayout, src, inverted, content, title } = props;
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<View
|
|
131
|
+
style={{
|
|
132
|
+
gap: theme.t('SpacingDefaultMobile').number,
|
|
133
|
+
flexDirection: 'row',
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
{imageLayout === 'leading' && (
|
|
137
|
+
<Image
|
|
138
|
+
source={src}
|
|
139
|
+
style={{
|
|
140
|
+
width: theme.t('SizeAssetsM').number,
|
|
141
|
+
aspectRatio: 1,
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
)}
|
|
145
|
+
<View
|
|
146
|
+
style={{
|
|
147
|
+
gap: theme.t('SpacingXsMobile').number,
|
|
148
|
+
flexDirection: 'column',
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
<Title inverted={inverted} title={title} color={'Neutral'} size={'L'} />
|
|
152
|
+
{content && (
|
|
153
|
+
<Content inverted={inverted} content={content} size={'M'} />
|
|
154
|
+
)}
|
|
155
|
+
</View>
|
|
156
|
+
</View>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function TagSection(props: PxMessageCardProps) {
|
|
161
|
+
const { theme } = useTheme();
|
|
162
|
+
const { tag, inverted } = props;
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<View
|
|
166
|
+
style={{
|
|
167
|
+
gap: theme.t('PaddingMMobile').number,
|
|
168
|
+
alignItems: 'flex-start',
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
<PxTag label={tag!} inverted={inverted} />
|
|
172
|
+
</View>
|
|
173
|
+
);
|
|
174
|
+
}
|
package/src/Title.tsx
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Header } from '@proximus/lavender-texts-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useTheme } from '@proximus/lavender-styling-native';
|
|
4
|
+
|
|
5
|
+
export function Title({
|
|
6
|
+
title,
|
|
7
|
+
size = '2xl',
|
|
8
|
+
color = 'Brand',
|
|
9
|
+
inverted = false,
|
|
10
|
+
}: {
|
|
11
|
+
title: string;
|
|
12
|
+
size?: 'L' | 'Xl' | '2xl';
|
|
13
|
+
color?: 'Brand' | 'Neutral';
|
|
14
|
+
inverted?: boolean;
|
|
15
|
+
}) {
|
|
16
|
+
const { theme } = useTheme();
|
|
17
|
+
|
|
18
|
+
const invertedSuffix = inverted ? 'Inverted' : 'Default';
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Header
|
|
22
|
+
ellipsizeMode={'tail'}
|
|
23
|
+
numberOfLines={1}
|
|
24
|
+
style={{
|
|
25
|
+
fontSize: theme.t(`TextSizeHeading${size}Mobile`).number,
|
|
26
|
+
color: theme.t(`ColorText${color}${invertedSuffix}`),
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
29
|
+
{title}
|
|
30
|
+
</Header>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Image, TouchableOpacity } from 'react-native';
|
|
3
|
+
import { fireEvent, render } from '@testing-library/react-native';
|
|
4
|
+
import { ICardProps, PxCard, PxCardMediaProps } from '..';
|
|
5
|
+
import { type RenderResult } from '@testing-library/react-native/build/render';
|
|
6
|
+
import { LaunchArguments } from 'react-native-launch-arguments';
|
|
7
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
8
|
+
|
|
9
|
+
describe('PxCard', () => {
|
|
10
|
+
let component: RenderResult;
|
|
11
|
+
const onPress = jest.fn();
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
(LaunchArguments.value as jest.Mock).mockReturnValue({ e2e: false });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
jest.resetAllMocks();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('renders title and (optional) content', () => {
|
|
22
|
+
givenComponent();
|
|
23
|
+
thenItMustDisplayTheTitleAndContent();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('fires onPress when the card is pressed', () => {
|
|
27
|
+
givenComponent();
|
|
28
|
+
whenClickingCard();
|
|
29
|
+
thenOnPressIsCalled();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('computes aspectRatio for mediaPosition="top" from Image.getSize', () => {
|
|
33
|
+
givenImageSize(1200, 600); // aspectRatio = 2
|
|
34
|
+
givenComponent();
|
|
35
|
+
thenMediaHasAspectRatio(2);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('sets width-based layout for mediaPosition="left"', () => {
|
|
39
|
+
givenImageSize(600, 1200);
|
|
40
|
+
givenComponent({
|
|
41
|
+
mediaPosition: 'left',
|
|
42
|
+
});
|
|
43
|
+
thenMediaHasWidth(120);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('shows gradient colors when contrastHelperGradient is true', () => {
|
|
47
|
+
givenComponent({
|
|
48
|
+
contrastHelper: 'gradient',
|
|
49
|
+
gradientDirection: 'horizontal',
|
|
50
|
+
});
|
|
51
|
+
thenHelperGradientIsDisplayed();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('shows overlay colors when contrastHelperOverlay is true', () => {
|
|
55
|
+
givenComponent({
|
|
56
|
+
contrastHelper: 'overlay',
|
|
57
|
+
});
|
|
58
|
+
thenHelperOverlayIsDisplayed();
|
|
59
|
+
});
|
|
60
|
+
//
|
|
61
|
+
it('does not render MediaPart when mediaPosition="background"', () => {
|
|
62
|
+
givenComponent({
|
|
63
|
+
mediaPosition: 'background',
|
|
64
|
+
});
|
|
65
|
+
thenMediaIsDisplayedBackground();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
function givenComponent(props?: Partial<ICardProps & PxCardMediaProps>) {
|
|
69
|
+
component = render(
|
|
70
|
+
<PxCard
|
|
71
|
+
{...props}
|
|
72
|
+
content={'Short description'}
|
|
73
|
+
alternativeText={'Nice Image'}
|
|
74
|
+
src={{
|
|
75
|
+
uri: 'https://example.com/img.jpg',
|
|
76
|
+
}}
|
|
77
|
+
onPress={onPress}
|
|
78
|
+
title={'Promo title'}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function givenImageSize(width: number, height: number) {
|
|
84
|
+
jest.spyOn(Image, 'getSize').mockImplementation((_, success) => {
|
|
85
|
+
success(width, height);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function thenItMustDisplayTheTitleAndContent() {
|
|
90
|
+
const { getByText } = component!;
|
|
91
|
+
const title = getByText('Promo title');
|
|
92
|
+
expect(title).toBeOnTheScreen();
|
|
93
|
+
expect(getByText('Short description')).toBeOnTheScreen();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function whenClickingCard() {
|
|
97
|
+
const { UNSAFE_getByType } = component;
|
|
98
|
+
fireEvent.press(UNSAFE_getByType(TouchableOpacity));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function thenOnPressIsCalled() {
|
|
102
|
+
expect(onPress).toHaveBeenCalled();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function thenMediaHasAspectRatio(aspectRatio: number) {
|
|
106
|
+
const { UNSAFE_queryAllByType } = component!;
|
|
107
|
+
const media = UNSAFE_queryAllByType(Image)?.[0];
|
|
108
|
+
expect(media?.props?.style.aspectRatio).toEqual(aspectRatio);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function thenMediaHasWidth(width: number) {
|
|
112
|
+
const { UNSAFE_getAllByType } = component!;
|
|
113
|
+
const media = UNSAFE_getAllByType(Image)?.[0];
|
|
114
|
+
expect(media?.props?.style.width).toEqual(width);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function thenMediaIsDisplayedBackground() {
|
|
118
|
+
const { UNSAFE_getAllByType } = component!;
|
|
119
|
+
const media = UNSAFE_getAllByType(Image);
|
|
120
|
+
expect(media.length).toEqual(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function thenHelperOverlayIsDisplayed() {
|
|
124
|
+
const { UNSAFE_getAllByType } = component!;
|
|
125
|
+
const overlay = UNSAFE_getAllByType(LinearGradient)?.[0];
|
|
126
|
+
expect(overlay?.props?.colors).toEqual([
|
|
127
|
+
'rgba(255,255,255,0.7)',
|
|
128
|
+
'rgba(255,255,255,0.7)',
|
|
129
|
+
]);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function thenHelperGradientIsDisplayed() {
|
|
133
|
+
const { UNSAFE_getAllByType } = component!;
|
|
134
|
+
const gradient = UNSAFE_getAllByType(LinearGradient)?.[0];
|
|
135
|
+
expect(gradient.props.colors).toEqual([
|
|
136
|
+
'#FFFFFF',
|
|
137
|
+
'#FFFFFFDD',
|
|
138
|
+
'#FFFFFF00',
|
|
139
|
+
]);
|
|
140
|
+
expect(gradient.props.start).toEqual({ x: 0, y: 1.0 });
|
|
141
|
+
expect(gradient.props.end).toEqual({ x: 1.0, y: 1.0 });
|
|
142
|
+
}
|
|
143
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { RenderResult } from '@testing-library/react-native/build/render';
|
|
2
|
+
import { LaunchArguments } from 'react-native-launch-arguments';
|
|
3
|
+
import { render } from '@testing-library/react-native';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { PxMessageCard, PxMessageCardProps } from '../PxMessageCard';
|
|
6
|
+
|
|
7
|
+
describe('PxCard', () => {
|
|
8
|
+
let component: RenderResult;
|
|
9
|
+
const onPress = jest.fn();
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
(LaunchArguments.value as jest.Mock).mockReturnValue({ e2e: false });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
jest.resetAllMocks();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('renders title and (optional) content', () => {
|
|
20
|
+
(LaunchArguments.value as jest.Mock).mockReturnValue({ e2e: true });
|
|
21
|
+
givenComponent();
|
|
22
|
+
thenItMustDisplayTitleContentCTACloseButton();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should be accessible', () => {
|
|
26
|
+
givenComponent({
|
|
27
|
+
accessibilityLabel: 'accessibilityLabel',
|
|
28
|
+
accessibilityHint: 'accessibilityHint',
|
|
29
|
+
closeButtonAccessibilityLabel: 'closeButtonAccessibilityLabel',
|
|
30
|
+
closeButtonAccessibilityHint: 'closeButtonAccessibilityHint',
|
|
31
|
+
});
|
|
32
|
+
thenItMustBeAccessible();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should display label properly', () => {
|
|
36
|
+
givenComponent({
|
|
37
|
+
tag: 'Tag label',
|
|
38
|
+
});
|
|
39
|
+
thenItMustDisplayTagLabel();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
function givenComponent(props?: Partial<PxMessageCardProps>) {
|
|
43
|
+
component = render(
|
|
44
|
+
<PxMessageCard
|
|
45
|
+
{...props}
|
|
46
|
+
testID={'testID'}
|
|
47
|
+
content={'Short description'}
|
|
48
|
+
alternativeText={'Nice Image'}
|
|
49
|
+
src={{
|
|
50
|
+
uri: 'https://example.com/img.jpg',
|
|
51
|
+
}}
|
|
52
|
+
onPress={onPress}
|
|
53
|
+
title={'Promo title'}
|
|
54
|
+
ctaLabel={'Call to action'}
|
|
55
|
+
onClose={() => {}}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function thenItMustDisplayTitleContentCTACloseButton() {
|
|
61
|
+
const { getByText, getByTestId } = component!;
|
|
62
|
+
expect(getByText('Promo title')).toBeOnTheScreen();
|
|
63
|
+
expect(getByText('Short description')).toBeOnTheScreen();
|
|
64
|
+
expect(getByText('Call to action')).toBeOnTheScreen();
|
|
65
|
+
expect(getByTestId('testID-close-button')).toBeOnTheScreen();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function thenItMustBeAccessible() {
|
|
69
|
+
const { getByLabelText, getByA11yHint } = component!;
|
|
70
|
+
expect(getByLabelText('accessibilityLabel')).toBeOnTheScreen();
|
|
71
|
+
expect(getByA11yHint('accessibilityHint')).toBeOnTheScreen();
|
|
72
|
+
expect(getByLabelText('closeButtonAccessibilityLabel')).toBeOnTheScreen();
|
|
73
|
+
expect(getByA11yHint('closeButtonAccessibilityHint')).toBeOnTheScreen();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function thenItMustDisplayTagLabel() {
|
|
77
|
+
const { getByText } = component!;
|
|
78
|
+
expect(getByText('Tag label')).toBeOnTheScreen();
|
|
79
|
+
}
|
|
80
|
+
});
|
package/src/index.ts
ADDED