@proximus/lavender-toast-native 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { StyleProp, ViewStyle } from 'react-native';
3
+ export interface PxModalProps {
4
+ containerStyle?: StyleProp<ViewStyle>;
5
+ offset?: number;
6
+ expanded?: boolean;
7
+ action1Label: string;
8
+ action1OnPress: () => void;
9
+ action1AccessibilityHint?: string;
10
+ action1TestID?: string;
11
+ action2Label?: string;
12
+ action2OnPress?: () => void;
13
+ action2AccessibilityHint?: string;
14
+ action2TestID?: string;
15
+ message: string;
16
+ visible: boolean;
17
+ status?: Status;
18
+ inverted?: boolean;
19
+ }
20
+ export type Status = 'success' | 'error' | 'warning' | 'info';
21
+ export declare function PxToast({ visible, containerStyle, offset, expanded, action1Label, action1OnPress, message, action2Label, action2OnPress, action1AccessibilityHint, action2AccessibilityHint, action1TestID, action2TestID, status, inverted, }: PxModalProps): React.JSX.Element | null;
22
+ //# sourceMappingURL=PxToast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PxToast.d.ts","sourceRoot":"","sources":["../src/PxToast.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAIL,SAAS,EAIT,SAAS,EACV,MAAM,cAAc,CAAC;AAQtB,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9D,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,cAAc,EACd,MAAU,EACV,QAAgB,EAChB,YAAY,EACZ,cAAc,EACd,OAAO,EACP,YAAY,EACZ,cAAc,EACd,wBAAwB,EACxB,wBAAwB,EACxB,aAAa,EACb,aAAa,EACb,MAAe,EACf,QAAgB,GACjB,EAAE,YAAY,4BAiNd"}
@@ -0,0 +1,187 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { AccessibilityInfo, Animated, StyleSheet, TouchableOpacity, View, } from 'react-native';
3
+ import { useTheme } from '@proximus/lavender-styling-native';
4
+ import { PxIcon } from '@proximus/lavender-icon-native';
5
+ import { Body, Header } from '@proximus/lavender-texts-native';
6
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
7
+ import { a11y, e2eID } from '@proximus/lavender-common-native';
8
+ export function PxToast({ visible, containerStyle, offset = 0, expanded = false, action1Label, action1OnPress, message, action2Label, action2OnPress, action1AccessibilityHint, action2AccessibilityHint, action1TestID, action2TestID, status = 'info', inverted = false, }) {
9
+ const [bottom, setBottom] = useState();
10
+ const [canDisplay, setCanDisplay] = useState(true);
11
+ const [animatedVisible, setAnimatedVisible] = useState(false);
12
+ const { theme } = useTheme();
13
+ const insets = useSafeAreaInsets();
14
+ const translateY = useRef(new Animated.Value(10)).current;
15
+ const opacity = useRef(new Animated.Value(0)).current;
16
+ const toastRef = useRef(null);
17
+ const iconSetup = useStatusIcon(theme, status, inverted);
18
+ const onLayoutCallback = useCallback((e) => {
19
+ if (!bottom && e.nativeEvent.layout.height > 0) {
20
+ setBottom(insets.bottom + offset);
21
+ }
22
+ }, [bottom, insets, offset]);
23
+ useEffect(() => {
24
+ if (visible) {
25
+ setCanDisplay(true);
26
+ }
27
+ }, [visible]);
28
+ useEffect(() => {
29
+ if (visible && canDisplay) {
30
+ Animated.parallel([
31
+ Animated.spring(translateY, {
32
+ toValue: 0,
33
+ useNativeDriver: true,
34
+ }),
35
+ Animated.spring(opacity, {
36
+ toValue: 1,
37
+ useNativeDriver: true,
38
+ }),
39
+ ]).start(() => {
40
+ setAnimatedVisible(true);
41
+ });
42
+ }
43
+ // eslint-disable-next-line react-hooks/exhaustive-deps
44
+ }, [visible, canDisplay]);
45
+ useEffect(() => {
46
+ if (!visible && animatedVisible) {
47
+ Animated.parallel([
48
+ Animated.spring(translateY, {
49
+ toValue: 10,
50
+ useNativeDriver: true,
51
+ }),
52
+ Animated.spring(opacity, {
53
+ toValue: 0,
54
+ useNativeDriver: true,
55
+ }),
56
+ ]).start(() => {
57
+ setAnimatedVisible(false);
58
+ setCanDisplay(false);
59
+ opacity.setValue(0);
60
+ translateY.setValue(10);
61
+ });
62
+ }
63
+ // eslint-disable-next-line react-hooks/exhaustive-deps
64
+ }, [animatedVisible, visible]);
65
+ useEffect(() => {
66
+ return () => {
67
+ opacity.setValue(0);
68
+ translateY.setValue(10);
69
+ };
70
+ // eslint-disable-next-line react-hooks/exhaustive-deps
71
+ }, []);
72
+ useEffect(() => {
73
+ if (animatedVisible) {
74
+ // Announce to screen readers that a toast has appeared
75
+ AccessibilityInfo.announceForAccessibility(message);
76
+ setTimeout(() => {
77
+ AccessibilityInfo.announceForAccessibility('Alert');
78
+ }, 1000);
79
+ }
80
+ }, [animatedVisible, message]);
81
+ return canDisplay ? (React.createElement(View, { pointerEvents: 'box-none', onLayout: onLayoutCallback, style: [
82
+ containerStyle,
83
+ styles.absoluteContainer,
84
+ {
85
+ bottom,
86
+ },
87
+ ] },
88
+ React.createElement(Animated.View, { pointerEvents: 'box-none', style: [
89
+ styles.animatedView,
90
+ {
91
+ paddingBottom: offset,
92
+ opacity,
93
+ transform: [{ translateY }],
94
+ },
95
+ ] },
96
+ React.createElement(View, { style: {
97
+ flex: 1,
98
+ marginHorizontal: theme.t('SpacingDefaultMobile').number,
99
+ borderRadius: theme.t('RadiusMain').number,
100
+ padding: theme.t('PaddingSMobile').number,
101
+ backgroundColor: inverted
102
+ ? theme.t('ColorBackgroundSurfaceLight')
103
+ : theme.t('ColorBackgroundSurfaceDark'),
104
+ flexDirection: expanded ? 'column' : 'row',
105
+ }, ref: toastRef },
106
+ React.createElement(View, { style: {
107
+ ...(!expanded && { flex: 1 }),
108
+ flexDirection: 'row',
109
+ alignItems: 'center',
110
+ justifyContent: 'flex-start',
111
+ gap: theme.t('SpacingSMobile').number,
112
+ } },
113
+ React.createElement(PxIcon, { accessible: false, importantForAccessibility: 'no', size: 24, ...iconSetup }),
114
+ React.createElement(Body, { inverted: !inverted, accessible: false, importantForAccessibility: 'no', numberOfLines: 1, ellipsizeMode: 'tail' }, message)),
115
+ React.createElement(View, { style: {
116
+ ...(!expanded && { flex: 1 }),
117
+ flexDirection: 'row',
118
+ justifyContent: 'flex-end',
119
+ gap: theme.t('SpacingDefaultMobile').number,
120
+ } },
121
+ React.createElement(TouchableOpacity, { onPress: () => {
122
+ action1OnPress();
123
+ }, ...a11y({
124
+ accessible: true,
125
+ accessibilityHint: action1AccessibilityHint,
126
+ accessibilityLabel: action1Label,
127
+ importantForAccessibility: 'yes',
128
+ }), ...e2eID(action1TestID) },
129
+ React.createElement(Header, { inverted: !inverted, style: {
130
+ textTransform: 'uppercase',
131
+ textDecorationLine: 'underline',
132
+ ...(inverted && { color: theme.t('ColorTextBrandDefault') }),
133
+ } }, action1Label)),
134
+ action2Label && action2OnPress && expanded && (React.createElement(TouchableOpacity, { onPress: () => {
135
+ action2OnPress();
136
+ }, ...a11y({
137
+ accessible: true,
138
+ accessibilityHint: action2AccessibilityHint,
139
+ accessibilityLabel: action2Label,
140
+ }), ...e2eID(action2TestID) },
141
+ React.createElement(Header, { inverted: !inverted, style: {
142
+ textTransform: 'uppercase',
143
+ textDecorationLine: 'underline',
144
+ ...(inverted && {
145
+ color: theme.t('ColorTextBrandDefault'),
146
+ }),
147
+ } }, action2Label)))))))) : null;
148
+ }
149
+ function useStatusIcon(theme, status, inverted) {
150
+ const colorSuffix = inverted ? 'Default' : 'Inverted';
151
+ switch (status) {
152
+ case 'info':
153
+ return {
154
+ name: 'information_fill',
155
+ color: theme.t(`ColorIconBrand${colorSuffix}`),
156
+ };
157
+ case 'success':
158
+ return {
159
+ name: 'checkmark_fill',
160
+ color: theme.t(`ColorIconPurposeSuccess${colorSuffix}`),
161
+ };
162
+ case 'warning':
163
+ return {
164
+ name: 'exclamation_mark_fill',
165
+ color: theme.t(`ColorIconPurposeWarning${colorSuffix}`),
166
+ };
167
+ case 'error':
168
+ return {
169
+ name: 'minus_fill',
170
+ color: theme.t(`ColorIconPurposeError${colorSuffix}`),
171
+ };
172
+ }
173
+ }
174
+ const styles = StyleSheet.create({
175
+ absoluteContainer: {
176
+ position: 'absolute',
177
+ top: 0,
178
+ left: 0,
179
+ right: 0,
180
+ zIndex: 10000,
181
+ },
182
+ animatedView: {
183
+ flex: 1,
184
+ alignItems: 'flex-end',
185
+ flexDirection: 'row',
186
+ },
187
+ });
@@ -0,0 +1,2 @@
1
+ export * from './PxToast';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './PxToast';
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@proximus/lavender-toast-native",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Lavender toast native component",
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "type": "module",
11
+ "peerDependencies": {
12
+ "@proximus/lavender-common-native": "*",
13
+ "@proximus/lavender-icon-native": "*",
14
+ "@proximus/lavender-styling-native": "*",
15
+ "@proximus/lavender-texts-native": "*"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ }
20
+ }