Skip to content

Commit 3a51d6c

Browse files
committed
Add alignment support
1 parent f2b645a commit 3a51d6c

File tree

9 files changed

+166
-134
lines changed

9 files changed

+166
-134
lines changed

demo/src/screens/incubatorScreens/IncubatorDialogScreen.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export default class IncubatorDialogScreen extends Component {
6969
<View flex center>
7070
<Button marginV-20 label="Open Dialog" onPress={this.openDialog}/>
7171
</View>
72-
<Incubator.Dialog visible={visible} onDismiss={this.onDismiss} bottom containerStyle={styles.dialogContainer}>
72+
<Incubator.Dialog visible={visible} onDismiss={this.onDismiss} bottom centerH>
7373
<View style={styles.dialog}>
7474
<Text text60 margin-s2>
7575
Title (swipe here)
@@ -90,11 +90,8 @@ export default class IncubatorDialogScreen extends Component {
9090
}
9191

9292
const styles = StyleSheet.create({
93-
dialogContainer: {
94-
bottom: 20,
95-
alignSelf: 'center'
96-
},
9793
dialog: {
94+
margin: 20,
9895
backgroundColor: Colors.white,
9996
width: 200,
10097
height: 300,
Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,7 @@
1-
import React, { PropsWithChildren } from 'react';
2-
import { StyleProp, ViewStyle } from 'react-native';
3-
import { PanningDirections, PanningDirectionsEnum } from '../panView';
4-
import { ModalProps } from '../../components/modal';
5-
import { AlignmentModifiers } from '../../commons/modifiers';
6-
declare type DialogDirections = PanningDirections;
7-
declare const DialogDirectionsEnum: typeof PanningDirectionsEnum;
1+
import React from 'react';
2+
import { ImperativeDialogMethods, DialogDirections, DialogDirectionsEnum } from './types';
83
export { DialogDirections, DialogDirectionsEnum };
9-
interface _DialogProps extends AlignmentModifiers {
10-
/**
11-
* The initial visibility of the dialog.
12-
*/
13-
initialVisibility?: boolean;
14-
/**
15-
* Callback that is called after the dialog's dismiss (after the animation has ended).
16-
*/
17-
onDismiss?: (props?: ImperativeDialogProps) => void;
18-
/**
19-
* The direction from which and to which the dialog is animating \ panning (default bottom).
20-
*/
21-
direction?: DialogDirections;
22-
/**
23-
* The Dialog`s container style (it is set to {position: 'absolute'})
24-
*/
25-
containerStyle?: StyleProp<ViewStyle>;
26-
/**
27-
* Whether or not to ignore background press.
28-
*/
29-
ignoreBackgroundPress?: boolean;
30-
/**
31-
* Additional props for the modal.
32-
*/
33-
modalProps?: ModalProps;
34-
/**
35-
* Used to locate this view in end-to-end tests
36-
* The container has the unchanged id.
37-
* Currently supported inner IDs:
38-
* TODO: add missing <TestID>(s?)
39-
* <TestID>.modal - the Modal's id.
40-
* <TestID>.overlayFadingBackground - the fading background id.
41-
*/
42-
testID?: string;
43-
}
44-
export declare type ImperativeDialogProps = PropsWithChildren<_DialogProps>;
45-
export interface ImperativeDialogMethods {
46-
open: () => void;
47-
close: () => void;
48-
}
49-
declare const _default: React.ForwardRefExoticComponent<_DialogProps & {
4+
declare const _default: React.ForwardRefExoticComponent<import("./types")._DialogProps & {
505
children?: React.ReactNode;
516
} & React.RefAttributes<ImperativeDialogMethods>>;
527
export default _default;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { AlignmentModifiers } from '../../../commons/modifiers';
2+
declare const useAlignmentStyle: (props: AlignmentModifiers) => {
3+
alignmentStyle: any[];
4+
};
5+
export default useAlignmentStyle;

generatedTypes/src/incubator/Dialog/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/// <reference types="react" />
2-
import { ImperativeDialogProps, DialogDirections, DialogDirectionsEnum } from './ImperativeDialog';
2+
import { ImperativeDialogProps, DialogDirections, DialogDirectionsEnum } from './types';
33
export { DialogDirections, DialogDirectionsEnum };
44
export interface DialogProps extends Omit<ImperativeDialogProps, 'initialVisibility'> {
55
/**
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { PropsWithChildren } from 'react';
2+
import { AlignmentModifiers } from '../../commons/modifiers';
3+
import { ModalProps } from '../../components/modal';
4+
import { PanningDirections, PanningDirectionsEnum } from '../panView';
5+
declare type DialogDirections = PanningDirections;
6+
declare const DialogDirectionsEnum: typeof PanningDirectionsEnum;
7+
export { DialogDirections, DialogDirectionsEnum };
8+
export interface _DialogProps extends AlignmentModifiers {
9+
/**
10+
* The initial visibility of the dialog.
11+
*/
12+
initialVisibility?: boolean;
13+
/**
14+
* Callback that is called after the dialog's dismiss (after the animation has ended).
15+
*/
16+
onDismiss?: (props?: ImperativeDialogProps) => void;
17+
/**
18+
* The direction from which and to which the dialog is animating \ panning (default bottom).
19+
*/
20+
direction?: DialogDirections;
21+
/**
22+
* Whether or not to ignore background press.
23+
*/
24+
ignoreBackgroundPress?: boolean;
25+
/**
26+
* Additional props for the modal.
27+
*/
28+
modalProps?: ModalProps;
29+
/**
30+
* Used to locate this view in end-to-end tests
31+
* The container has the unchanged id.
32+
* Currently supported inner IDs:
33+
* TODO: add missing <TestID>(s?)
34+
* <TestID>.modal - the Modal's id.
35+
* <TestID>.overlayFadingBackground - the fading background id.
36+
*/
37+
testID?: string;
38+
}
39+
export declare type ImperativeDialogProps = PropsWithChildren<_DialogProps>;
40+
export interface ImperativeDialogMethods {
41+
open: () => void;
42+
close: () => void;
43+
}

src/incubator/Dialog/ImperativeDialog.tsx

Lines changed: 33 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,14 @@
1-
import React, {PropsWithChildren, useMemo, useCallback, useState, useImperativeHandle, forwardRef} from 'react';
2-
import {StyleSheet, StyleProp, ViewStyle} from 'react-native';
1+
import React, {useMemo, useCallback, useState, useImperativeHandle, forwardRef} from 'react';
2+
import {StyleSheet} from 'react-native';
33
import {useSharedValue, withTiming, useAnimatedStyle} from 'react-native-reanimated';
4-
import TransitionView, {TransitionViewAnimationType} from '../TransitionView';
5-
import PanView, {PanningDirections, PanningDirectionsEnum} from '../panView';
64
import View from '../../components/view';
7-
import Modal, {ModalProps} from '../../components/modal';
8-
import {AlignmentModifiers} from '../../commons/modifiers';
9-
type DialogDirections = PanningDirections;
10-
const DialogDirectionsEnum = PanningDirectionsEnum;
5+
import Modal from '../../components/modal';
6+
import TransitionView, {TransitionViewAnimationType} from '../TransitionView';
7+
import PanView from '../panView';
8+
import useAlignmentStyle from './helpers/useAlignmentStyle';
9+
import {ImperativeDialogProps, ImperativeDialogMethods, DialogDirections, DialogDirectionsEnum} from './types';
1110
export {DialogDirections, DialogDirectionsEnum};
1211

13-
interface _DialogProps extends AlignmentModifiers {
14-
/**
15-
* The initial visibility of the dialog.
16-
*/
17-
initialVisibility?: boolean;
18-
/**
19-
* Callback that is called after the dialog's dismiss (after the animation has ended).
20-
*/
21-
onDismiss?: (props?: ImperativeDialogProps) => void;
22-
/**
23-
* The direction from which and to which the dialog is animating \ panning (default bottom).
24-
*/
25-
direction?: DialogDirections;
26-
/**
27-
* The Dialog`s container style (it is set to {position: 'absolute'})
28-
*/
29-
containerStyle?: StyleProp<ViewStyle>;
30-
/**
31-
* Whether or not to ignore background press.
32-
*/
33-
ignoreBackgroundPress?: boolean;
34-
/**
35-
* Additional props for the modal.
36-
*/
37-
modalProps?: ModalProps;
38-
/**
39-
* Used to locate this view in end-to-end tests
40-
* The container has the unchanged id.
41-
* Currently supported inner IDs:
42-
* TODO: add missing <TestID>(s?)
43-
* <TestID>.modal - the Modal's id.
44-
* <TestID>.overlayFadingBackground - the fading background id.
45-
*/
46-
testID?: string;
47-
}
48-
49-
export type ImperativeDialogProps = PropsWithChildren<_DialogProps>;
50-
51-
export interface ImperativeDialogMethods {
52-
open: () => void;
53-
close: () => void;
54-
}
55-
5612
import {Colors} from 'style';
5713
const DEFAULT_OVERLAY_BACKGROUND_COLORS = Colors.rgba(Colors.black, 0.2);
5814

@@ -62,7 +18,6 @@ const ImperativeDialog = (props: ImperativeDialogProps, ref: any) => {
6218
onDismiss,
6319
direction = DialogDirectionsEnum.DOWN,
6420
children,
65-
containerStyle,
6621
ignoreBackgroundPress,
6722
modalProps = {},
6823
testID
@@ -71,6 +26,7 @@ const ImperativeDialog = (props: ImperativeDialogProps, ref: any) => {
7126
const {overlayBackgroundColor = DEFAULT_OVERLAY_BACKGROUND_COLORS, ...otherModalProps} = modalProps;
7227
const fadeOpacity = useSharedValue<number>(Number(initialVisibility));
7328
const [visible, setVisible] = useState(initialVisibility);
29+
const {alignmentStyle} = useAlignmentStyle(props);
7430

7531
const open = useCallback(() => {
7632
if (!visible) {
@@ -117,39 +73,25 @@ const ImperativeDialog = (props: ImperativeDialogProps, ref: any) => {
11773
},
11874
[onDismiss, setVisible]);
11975

120-
const panStyle = useMemo(() => {
121-
return [containerStyle, styles.panView];
122-
}, [containerStyle]);
123-
12476
const fadeStyle = useAnimatedStyle(() => {
12577
return {
12678
opacity: fadeOpacity.value,
12779
backgroundColor: overlayBackgroundColor
12880
};
12981
}, [overlayBackgroundColor]);
13082

131-
return (
132-
<Modal
133-
transparent
134-
animationType={'none'}
135-
{...otherModalProps}
136-
testID={`${testID}.modal`}
137-
useGestureHandlerRootView
138-
visible={visible}
139-
onBackgroundPress={ignoreBackgroundPress ? undefined : onBackgroundPress}
140-
onRequestClose={onBackgroundPress}
141-
onDismiss={undefined}
142-
>
143-
<View testID={`${testID}.overlayFadingBackground`} absF reanimated style={fadeStyle} pointerEvents="none"/>
144-
{/* TODO: remove?
145-
{this.renderDialogView()}
146-
{addBottomSafeArea && <View style={{marginTop: bottomInsets}}/>} */}
147-
83+
const renderDialog = () => {
84+
{
85+
/* TODO: remove?
86+
{this.renderDialogView()}
87+
{addBottomSafeArea && <View style={{marginTop: bottomInsets}}/>} */
88+
}
89+
return (
14890
<PanView
14991
directions={directions}
15092
dismissible
15193
animateToOrigin
152-
containerStyle={panStyle}
94+
containerStyle={styles.panView}
15395
onDismiss={onPanViewDismiss}
15496
>
15597
<TransitionView
@@ -162,6 +104,23 @@ const ImperativeDialog = (props: ImperativeDialogProps, ref: any) => {
162104
{children}
163105
</TransitionView>
164106
</PanView>
107+
);
108+
};
109+
110+
return (
111+
<Modal
112+
transparent
113+
animationType={'none'}
114+
{...otherModalProps}
115+
testID={`${testID}.modal`}
116+
useGestureHandlerRootView
117+
visible={visible}
118+
onBackgroundPress={ignoreBackgroundPress ? undefined : onBackgroundPress}
119+
onRequestClose={onBackgroundPress}
120+
onDismiss={undefined}
121+
>
122+
<View testID={`${testID}.overlayFadingBackground`} absF reanimated style={fadeStyle} pointerEvents="none"/>
123+
<View pointerEvents={'none'} style={alignmentStyle}>{renderDialog()}</View>
165124
</Modal>
166125
);
167126
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {isEmpty} from 'lodash';
2+
import {useMemo} from 'react';
3+
import {StyleSheet} from 'react-native';
4+
import {AlignmentModifiers, extractAlignmentsValues} from '../../../commons/modifiers';
5+
6+
const useAlignmentStyle = (props: AlignmentModifiers) => {
7+
const getAlignments = () => {
8+
const alignments = extractAlignmentsValues(props);
9+
return isEmpty(alignments) ? styles.defaultAlignment : alignments;
10+
};
11+
12+
const alignments = getAlignments();
13+
14+
const alignmentStyle = useMemo(() => {
15+
return [styles.container, alignments];
16+
}, [alignments]);
17+
18+
return {alignmentStyle};
19+
};
20+
21+
export default useAlignmentStyle;
22+
23+
const styles = StyleSheet.create({
24+
container: {
25+
flex: 1
26+
},
27+
defaultAlignment: {
28+
justifyContent: 'center',
29+
alignItems: 'center'
30+
}
31+
});

src/incubator/Dialog/index.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import React, {useRef} from 'react';
22
import {useDidUpdate} from 'hooks';
3-
import ImperativeDialog, {
4-
ImperativeDialogProps,
5-
DialogDirections,
6-
DialogDirectionsEnum,
7-
ImperativeDialogMethods
8-
} from './ImperativeDialog';
3+
import ImperativeDialog from './ImperativeDialog';
4+
import {ImperativeDialogProps, DialogDirections, DialogDirectionsEnum, ImperativeDialogMethods} from './types';
95
export {DialogDirections, DialogDirectionsEnum};
106

117
export interface DialogProps extends Omit<ImperativeDialogProps, 'initialVisibility'> {

src/incubator/Dialog/types.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {PropsWithChildren} from 'react';
2+
import {AlignmentModifiers} from '../../commons/modifiers';
3+
import {ModalProps} from '../../components/modal';
4+
import {PanningDirections, PanningDirectionsEnum} from '../panView';
5+
type DialogDirections = PanningDirections;
6+
const DialogDirectionsEnum = PanningDirectionsEnum;
7+
export {DialogDirections, DialogDirectionsEnum};
8+
9+
export interface _DialogProps extends AlignmentModifiers {
10+
/**
11+
* The initial visibility of the dialog.
12+
*/
13+
initialVisibility?: boolean;
14+
/**
15+
* Callback that is called after the dialog's dismiss (after the animation has ended).
16+
*/
17+
onDismiss?: (props?: ImperativeDialogProps) => void;
18+
/**
19+
* The direction from which and to which the dialog is animating \ panning (default bottom).
20+
*/
21+
direction?: DialogDirections;
22+
/**
23+
* Whether or not to ignore background press.
24+
*/
25+
ignoreBackgroundPress?: boolean;
26+
/**
27+
* Additional props for the modal.
28+
*/
29+
modalProps?: ModalProps;
30+
/**
31+
* Used to locate this view in end-to-end tests
32+
* The container has the unchanged id.
33+
* Currently supported inner IDs:
34+
* TODO: add missing <TestID>(s?)
35+
* <TestID>.modal - the Modal's id.
36+
* <TestID>.overlayFadingBackground - the fading background id.
37+
*/
38+
testID?: string;
39+
}
40+
41+
export type ImperativeDialogProps = PropsWithChildren<_DialogProps>;
42+
43+
export interface ImperativeDialogMethods {
44+
open: () => void;
45+
close: () => void;
46+
}

0 commit comments

Comments
 (0)