Skip to content

Commit b4aa69a

Browse files
authored
Dialog - add showClose (#3192)
* Dialog - add showClose * Review fixes 1 * Review fixes 2 * Rename to useDialogContent
1 parent 1b9fbdf commit b4aa69a

File tree

10 files changed

+130
-11
lines changed

10 files changed

+130
-11
lines changed

src/assets/icons/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ export const icons = {
1717
get x() {
1818
return require('./x.png');
1919
},
20+
get xMedium() {
21+
return require('./xMedium.png');
22+
},
2023
get xFlat() {
2124
return require('./xFlat.png');
2225
}

src/assets/icons/xMedium.png

218 Bytes
Loading
256 Bytes
Loading
290 Bytes
Loading
390 Bytes
Loading
483 Bytes
Loading

src/incubator/Dialog/dialog.api.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
"description": "The direction from which and to which the dialog is animating \\ panning (default down).",
3030
"default": "down"
3131
},
32+
{
33+
"name": "showClose",
34+
"type": "boolean",
35+
"description": "Show the close button"
36+
},
3237
{"name": "ignoreBackgroundPress", "type": "boolean", "description": "Whether or not to ignore background press."},
3338
{"name": "modalProps", "type": "ModalProps", "description": "Pass props to the dialog modal"},
3439
{

src/incubator/Dialog/index.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import Modal from '../../components/modal';
2424
import {extractAlignmentsValues} from '../../commons/modifiers';
2525
import useHiddenLocation from '../hooks/useHiddenLocation';
2626
import DialogHeader from './DialogHeader';
27+
import useDialogContent from './useDialogContent';
2728
import {DialogProps, DialogDirections, DialogDirectionsEnum, DialogHeaderProps, DialogMigrationProps} from './types';
2829
export {DialogProps, DialogDirections, DialogDirectionsEnum, DialogHeaderProps, DialogMigrationProps};
2930

@@ -42,8 +43,10 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)
4243
const {
4344
visible = false,
4445
headerProps,
45-
containerStyle,
46-
containerProps,
46+
showCloseButton,
47+
closeButtonProps,
48+
containerStyle: propsContainerStyle,
49+
containerProps: propsContainerProps,
4750
width,
4851
height,
4952
onDismiss,
@@ -124,6 +127,16 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)
124127
// eslint-disable-next-line react-hooks/exhaustive-deps
125128
}, []);
126129

130+
const {DialogContent, containerProps, containerStyle} = useDialogContent({
131+
showCloseButton,
132+
close,
133+
closeButtonProps,
134+
containerStyle: propsContainerStyle,
135+
containerProps: propsContainerProps,
136+
headerProps,
137+
children
138+
});
139+
127140
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
128141
const animatedStyle = useAnimatedStyle(() => {
129142
if (isVertical) {
@@ -202,8 +215,7 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)
202215
<GestureDetector gesture={panGesture}>
203216
{/* @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881) */}
204217
<View {...containerProps} reanimated style={style} onLayout={onLayout} ref={setRef} testID={testID}>
205-
{headerProps && <DialogHeader {...headerProps}/>}
206-
{children}
218+
<DialogContent/>
207219
</View>
208220
</GestureDetector>
209221
);

src/incubator/Dialog/types.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import {PropsWithChildren, ReactElement} from 'react';
22
import {StyleProp, TextStyle, ViewStyle} from 'react-native';
33
import {AlignmentModifiers} from '../../commons/modifiers';
44
import {DialogProps as DialogPropsOld} from '../../components/dialog';
5+
import {ButtonProps} from '../../components/button';
56
import {ModalProps} from '../../components/modal';
6-
import {ViewProps} from '../../components/view';
7-
import {TextProps} from '../../components/text';
87
import {PanningDirections, PanningDirectionsEnum} from '../panView';
8+
import {TextProps} from '../../components/text';
9+
import {ViewProps} from '../../components/view';
910
type DialogDirections = PanningDirections;
1011
const DialogDirectionsEnum = PanningDirectionsEnum;
1112
export {DialogDirections, DialogDirectionsEnum};
@@ -69,11 +70,7 @@ export interface DialogHeaderProps extends ViewProps {
6970
onPress?: () => void;
7071
}
7172

72-
export interface _DialogProps extends AlignmentModifiers, Pick<ViewProps, 'useSafeArea'> {
73-
/**
74-
* The visibility of the dialog.
75-
*/
76-
visible?: boolean;
73+
export interface DialogCloseButtonProps {
7774
/**
7875
* The Dialog's header (title, subtitle etc)
7976
*/
@@ -86,6 +83,21 @@ export interface _DialogProps extends AlignmentModifiers, Pick<ViewProps, 'useSa
8683
* Extra props for the container
8784
*/
8885
containerProps?: Omit<ViewProps, 'reanimated' | 'animated' | 'style' | 'onLayout' | 'ref' | 'testID'>;
86+
/**
87+
* Whether to show the close button or not
88+
*/
89+
showCloseButton?: boolean;
90+
/**
91+
* The close button props
92+
*/
93+
closeButtonProps?: Pick<ButtonProps, 'label' | 'labelProps' | 'iconProps'>;
94+
}
95+
96+
export interface _DialogProps extends AlignmentModifiers, Pick<ViewProps, 'useSafeArea'>, DialogCloseButtonProps {
97+
/**
98+
* The visibility of the dialog.
99+
*/
100+
visible?: boolean;
89101
/**
90102
* The dialog width.
91103
*/
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import React, {PropsWithChildren, useMemo} from 'react';
2+
import {BorderRadiuses, Colors} from '../../style';
3+
import {DialogCloseButtonProps} from './types';
4+
import {StyleSheet} from 'react-native';
5+
import Assets from '../../assets';
6+
import DialogHeader from './DialogHeader';
7+
import Icon from '../../components/icon';
8+
import Text from '../../components/text';
9+
import TouchableOpacity from '../../components/touchableOpacity';
10+
import View from '../../components/view';
11+
12+
interface InternalDialogCloseButtonProps extends PropsWithChildren<DialogCloseButtonProps> {
13+
close: () => void;
14+
}
15+
16+
const useDialogContent = (props: InternalDialogCloseButtonProps) => {
17+
const {
18+
showCloseButton,
19+
close,
20+
closeButtonProps,
21+
containerStyle: propsContainerStyle,
22+
containerProps: propsContainerProps,
23+
headerProps,
24+
children
25+
} = props;
26+
27+
const DialogCloseButton = useMemo(() => {
28+
if (!showCloseButton) {
29+
return null;
30+
}
31+
32+
return (
33+
<View left centerV pointerEvents={'box-none'}>
34+
<TouchableOpacity paddingB-s2 row onPress={close}>
35+
<Icon source={Assets.icons.xMedium} tintColor={Colors.white} {...closeButtonProps?.iconProps}/>
36+
<Text recorderTag={'unmask'} text70BO white {...closeButtonProps?.labelProps}>
37+
{closeButtonProps?.label || 'Close'}
38+
</Text>
39+
</TouchableOpacity>
40+
</View>
41+
);
42+
}, [showCloseButton, close, closeButtonProps]);
43+
44+
const containerProps = useMemo((): DialogCloseButtonProps['containerProps'] => {
45+
return showCloseButton ? {...propsContainerProps, pointerEvents: 'box-none'} : propsContainerProps;
46+
}, [showCloseButton, propsContainerProps]);
47+
48+
const containerStyle = useMemo(() => {
49+
return showCloseButton ? [propsContainerStyle, styles.transparent] : propsContainerStyle;
50+
}, [showCloseButton, propsContainerStyle]);
51+
52+
const DialogContent = () => {
53+
const DialogContent = (
54+
<>
55+
{headerProps && <DialogHeader {...headerProps}/>}
56+
{children}
57+
</>
58+
);
59+
60+
if (DialogCloseButton) {
61+
return (
62+
<>
63+
{DialogCloseButton}
64+
<View style={styles.dialogContentContainer}>{DialogContent}</View>
65+
</>
66+
);
67+
} else {
68+
return DialogContent;
69+
}
70+
};
71+
72+
return {DialogContent, containerStyle, containerProps};
73+
};
74+
75+
export default useDialogContent;
76+
77+
const styles = StyleSheet.create({
78+
transparent: {
79+
backgroundColor: Colors.transparent
80+
},
81+
dialogContentContainer: {
82+
flexShrink: 1,
83+
backgroundColor: Colors.$backgroundDefault,
84+
overflow: 'hidden',
85+
borderRadius: BorderRadiuses.br60
86+
}
87+
});

0 commit comments

Comments
 (0)