@proximus/lavender-drawer-native 0.1.0-alpha.15

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,20 @@
1
+ import React from 'react';
2
+ import { AccessibilityProps } from 'react-native';
3
+ type DrawerSide = 'left' | 'right';
4
+ export interface DrawerProps extends AccessibilityProps {
5
+ title?: string;
6
+ description?: string;
7
+ isOpen: boolean;
8
+ toggleSheet?: () => void;
9
+ side?: DrawerSide;
10
+ testID?: string;
11
+ children?: React.ReactNode;
12
+ onClose: () => void;
13
+ accessibilityAnnouncementMessage?: string;
14
+ accessibilityCloseButtonLabel?: string;
15
+ accessibilityCloseButtonHint?: string;
16
+ }
17
+ export declare function PxDrawer({ title, description, isOpen, toggleSheet, side, testID, children, onClose, accessibilityAnnouncementMessage, ...accessibilityProps }: DrawerProps): React.JSX.Element;
18
+ export declare function TopZone(props: Partial<DrawerProps>): React.JSX.Element;
19
+ export {};
20
+ //# sourceMappingURL=PxDrawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PxDrawer.d.ts","sourceRoot":"","sources":["../src/PxDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAEL,kBAAkB,EAOnB,MAAM,cAAc,CAAC;AAOtB,KAAK,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAInC,MAAM,WAAW,WAAY,SAAQ,kBAAkB;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,MAAM,EAAE,OAAO,CAAC;IAEhB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAEzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAGlB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE3B,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACvC;AAGD,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,WAAW,EACX,MAAM,EACN,WAAW,EACX,IAAa,EACb,MAAM,EACN,QAAQ,EACR,OAAO,EACP,gCAAgC,EAChC,GAAG,kBAAkB,EACtB,EAAE,WAAW,qBAgHb;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,qBAqDlD"}
@@ -0,0 +1,109 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { AccessibilityInfo, Animated, Dimensions, Modal, StyleSheet, TouchableOpacity, View, } from 'react-native';
3
+ import { a11y, e2eID } from '@proximus/lavender-common-native';
4
+ import { useTheme } from '@proximus/lavender-styling-native';
5
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
6
+ import { Body, Header } from '@proximus/lavender-texts-native';
7
+ import { PxButtonIcon } from '@proximus/lavender-buttonicon-native';
8
+ const DURATION_DEFAULT = 300;
9
+ // A simple side drawer implemented with React Native Animated
10
+ export function PxDrawer({ title, description, isOpen, toggleSheet, side = 'left', testID, children, onClose, accessibilityAnnouncementMessage, ...accessibilityProps }) {
11
+ const baseId = testID ?? 'PxDrawer';
12
+ const screenWidth = Dimensions.get('window').width;
13
+ const drawerWidth = Math.round(screenWidth * 0.9);
14
+ const { theme } = useTheme();
15
+ const { bottom, top } = useSafeAreaInsets();
16
+ // progress: 0 (closed) -> 1 (open)
17
+ const progress = useRef(new Animated.Value(isOpen ? 1 : 0)).current;
18
+ // Control Modal visibility so the drawer truly covers the entire screen
19
+ const [visible, setVisible] = useState(isOpen);
20
+ useEffect(() => {
21
+ // Ensure the modal is visible before starting the open animation
22
+ if (isOpen && !visible) {
23
+ setVisible(true);
24
+ }
25
+ Animated.timing(progress, {
26
+ toValue: isOpen ? 1 : 0,
27
+ duration: DURATION_DEFAULT,
28
+ useNativeDriver: true,
29
+ }).start(({ finished }) => {
30
+ if (finished && !isOpen) {
31
+ // After close animation completes, hide the modal
32
+ setVisible(false);
33
+ }
34
+ });
35
+ }, [isOpen, progress, visible]);
36
+ useEffect(() => {
37
+ if (accessibilityAnnouncementMessage && visible) {
38
+ // Announce to screen readers that the drawer has appeared
39
+ AccessibilityInfo.announceForAccessibility(accessibilityAnnouncementMessage);
40
+ }
41
+ }, [accessibilityAnnouncementMessage, visible]);
42
+ // Translate from off-screen to 0 depending on side
43
+ const offscreen = side === 'left' ? -drawerWidth : drawerWidth;
44
+ const translateX = progress.interpolate({
45
+ inputRange: [0, 1],
46
+ outputRange: [offscreen, 0],
47
+ });
48
+ const backdropOpacity = progress.interpolate({
49
+ inputRange: [0, 1],
50
+ outputRange: [0, 1],
51
+ });
52
+ const pointerEvents = isOpen ? 'auto' : 'none';
53
+ return (React.createElement(Modal, { ...e2eID(`${baseId}.Modal`), ...a11y(accessibilityProps), visible: visible, transparent: true, animationType: "none", onRequestClose: toggleSheet, statusBarTranslucent: true },
54
+ React.createElement(View, { style: styles.modalRoot, pointerEvents: "box-none", ...e2eID(`${baseId}.Root`) },
55
+ React.createElement(Animated.View, { style: [styles.backdrop, { opacity: backdropOpacity }], pointerEvents: pointerEvents },
56
+ React.createElement(TouchableOpacity, { style: { flex: 1 }, onPress: toggleSheet, ...e2eID(`${baseId}.Backdrop`) })),
57
+ React.createElement(Animated.View, { style: [
58
+ styles.drawer,
59
+ {
60
+ width: drawerWidth,
61
+ left: side === 'left' ? 0 : undefined,
62
+ right: side === 'right' ? 0 : undefined,
63
+ transform: [{ translateX }],
64
+ backgroundColor: theme.t('ColorBackgroundSurfaceLight'),
65
+ paddingTop: top + theme.t('SpacingXsMobile').number,
66
+ paddingBottom: bottom,
67
+ },
68
+ ], ...e2eID(`${baseId}.Panel`) },
69
+ React.createElement(View, { style: {
70
+ flex: 1,
71
+ gap: theme.t('SpacingSMobile').number,
72
+ padding: theme.t('SpacingSMobile').number,
73
+ } },
74
+ React.createElement(TopZone, { title, description, testID, onClose }),
75
+ children)))));
76
+ }
77
+ export function TopZone(props) {
78
+ const { title, description, testID, onClose, accessibilityCloseButtonLabel, accessibilityCloseButtonHint, } = props;
79
+ const { theme } = useTheme();
80
+ return (React.createElement(View, { style: {
81
+ flexDirection: 'row',
82
+ alignItems: 'flex-start',
83
+ } },
84
+ React.createElement(View, { style: {
85
+ flex: 1,
86
+ gap: theme.t('SpacingHeadingToSubtitleMobile').number,
87
+ } },
88
+ React.createElement(Header, { style: {
89
+ color: theme.t('ColorTextBrandDefault'),
90
+ fontSize: theme.t('TextSizeHeadingXlMobile').number,
91
+ }, ...(testID && e2eID(`${testID}-drawer-title`)) }, title),
92
+ React.createElement(Body, { style: { fontSize: theme.t('TextSizeBodyLMobile').number }, ...(testID && e2eID(`${testID}-drawer-description`)) }, description)),
93
+ React.createElement(View, null,
94
+ React.createElement(PxButtonIcon, { onPress: onClose, iconName: 'cross', variant: 'secondary', size: 'small', testID: `${testID}-drawer-close-button`, accessibilityLabel: accessibilityCloseButtonLabel || 'Close drawer', accessibilityHint: accessibilityCloseButtonHint }))));
95
+ }
96
+ const styles = StyleSheet.create({
97
+ modalRoot: {
98
+ flex: 1,
99
+ },
100
+ drawer: {
101
+ position: 'absolute',
102
+ top: 0,
103
+ bottom: 0,
104
+ },
105
+ backdrop: {
106
+ ...StyleSheet.absoluteFillObject,
107
+ backgroundColor: 'rgba(0, 0, 0, 0.3)',
108
+ },
109
+ });
@@ -0,0 +1,2 @@
1
+ export * from './PxDrawer';
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,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './PxDrawer';
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@proximus/lavender-drawer-native",
3
+ "version": "0.1.0-alpha.15",
4
+ "description": "Lavender drawer component",
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "type": "module",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "peerDependencies": {
12
+ "@proximus/lavender-buttonicon-native": "*",
13
+ "@proximus/lavender-common-native": "*",
14
+ "@proximus/lavender-icon-native": "*",
15
+ "@proximus/lavender-styling-native": "*",
16
+ "@proximus/lavender-texts-native": "*"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ }
21
+ }