Skip to content

Commit d77c202

Browse files
authored
New Dialog using the new Pan and Transition Views (#1576)
* Rename Direction to TransitionViewDirection * New Dialog using the new Pan and Tranistion Views * Remove gestureHandler style * Remove extra view * Add TODO * Add union type + each component has its own statics and types * Fix import in tests * PR fixes * Move types to PanView
1 parent b7089dd commit d77c202

File tree

21 files changed

+505
-128
lines changed

21 files changed

+505
-128
lines changed

demo/src/screens/MenuStructure.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ export const navigationData = {
154154
title: 'Incubator (Experimental)',
155155
screens: [
156156
{title: 'Native TouchableOpacity', tags: 'touchable native', screen: 'unicorn.incubator.TouchableOpacityScreen'},
157+
{title: '(New) Dialog', tags: 'dialog modal popup alert', screen: 'unicorn.incubator.IncubatorDialogScreen'},
157158
{title: '(New) TextField', tags: 'text field input', screen: 'unicorn.components.IncubatorTextFieldScreen'},
158159
{title: 'ExpandableOverlay', tags: 'text field expandable input picker', screen: 'unicorn.components.IncubatorExpandableOverlayScreen'},
159160
{title: 'WheelPicker (Incubator)', tags: 'wheel picker spinner experimental', screen: 'unicorn.incubator.WheelPickerScreen'},
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, {Component} from 'react';
2+
import {StyleSheet} from 'react-native';
3+
import {FlatList} from 'react-native-gesture-handler';
4+
import {View, Text, Card, Button, Incubator, Colors, BorderRadiuses} from 'react-native-ui-lib'; //eslint-disable-line
5+
6+
interface Item {
7+
value: string;
8+
label: string;
9+
}
10+
11+
const colors: Item[] = [
12+
{value: Colors.red10, label: 'Red10'},
13+
{value: Colors.red30, label: 'Red30'},
14+
{value: Colors.red50, label: 'Red50'},
15+
{value: Colors.red70, label: 'Red70'},
16+
{value: Colors.blue10, label: 'Blue10'},
17+
{value: Colors.blue30, label: 'Blue30'},
18+
{value: Colors.blue50, label: 'Blue50'},
19+
{value: Colors.blue70, label: 'Blue70'},
20+
{value: Colors.purple10, label: 'Purple10'},
21+
{value: Colors.purple30, label: 'Purple30'},
22+
{value: Colors.purple50, label: 'Purple50'},
23+
{value: Colors.purple70, label: 'Purple70'},
24+
{value: Colors.green10, label: 'Green10'},
25+
{value: Colors.green30, label: 'Green30'},
26+
{value: Colors.green50, label: 'Green50'},
27+
{value: Colors.green70, label: 'Green70'},
28+
{value: Colors.yellow10, label: 'Yellow10'},
29+
{value: Colors.yellow30, label: 'Yellow30'},
30+
{value: Colors.yellow50, label: 'Yellow50'},
31+
{value: Colors.yellow70, label: 'Yellow70'}
32+
];
33+
34+
export default class IncubatorDialogScreen extends Component {
35+
state = {visible: false};
36+
37+
renderVerticalItem = ({item}: {item: Item}) => {
38+
return (
39+
<Text text50 margin-20 color={item.value}>
40+
{item.label}
41+
</Text>
42+
);
43+
};
44+
45+
keyExtractor = (item: Item) => {
46+
return item.value;
47+
};
48+
49+
openDialog = () => {
50+
this.setState({visible: true});
51+
};
52+
53+
closeDialog = () => {
54+
this.setState({visible: false});
55+
};
56+
57+
render() {
58+
const {visible} = this.state;
59+
60+
return (
61+
<View bg-dark80 flex padding-20>
62+
<Card height={100} center padding-20>
63+
<Text text50>IncubatorDialogScreen</Text>
64+
</Card>
65+
<View flex center>
66+
<Button marginV-20 label="Open Dialog" onPress={this.openDialog}/>
67+
</View>
68+
<Incubator.Dialog visible={visible} onDismiss={this.closeDialog} bottom containerStyle={styles.dialogContainer}>
69+
<View style={styles.dialog}>
70+
<Text text60 margin-s2>
71+
Title (swipe here)
72+
</Text>
73+
<View height={1} bg-grey40/>
74+
<FlatList
75+
showsVerticalScrollIndicator={false}
76+
style={styles.verticalScroll}
77+
data={colors}
78+
renderItem={this.renderVerticalItem}
79+
keyExtractor={this.keyExtractor}
80+
/>
81+
</View>
82+
</Incubator.Dialog>
83+
</View>
84+
);
85+
}
86+
}
87+
88+
const styles = StyleSheet.create({
89+
dialogContainer: {
90+
bottom: 20,
91+
alignSelf: 'center'
92+
},
93+
dialog: {
94+
backgroundColor: Colors.white,
95+
width: 200,
96+
height: 300,
97+
borderRadius: BorderRadiuses.br20
98+
},
99+
verticalScroll: {
100+
marginTop: 20
101+
}
102+
});

demo/src/screens/incubatorScreens/TransitionViewScreen.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ const {TransitionView} = Incubator;
55
import {renderRadioGroup} from '../ExampleScreenPresenter';
66

77
interface State {
8-
enterDirection: Incubator.Direction;
9-
exitDirection: Incubator.Direction;
8+
enterDirection: Incubator.TransitionViewDirection;
9+
exitDirection: Incubator.TransitionViewDirection;
1010
key: number;
1111
}
1212

1313
export default class TransitionViewScreen extends Component<{}, State> {
1414
private ref = React.createRef<typeof TransitionView>();
1515
state = {
16-
enterDirection: 'left' as Incubator.Direction,
17-
exitDirection: 'bottom' as Incubator.Direction,
16+
enterDirection: Incubator.TransitionViewDirectionEnum.LEFT,
17+
exitDirection: Incubator.TransitionViewDirectionEnum.DOWN,
1818
key: 1
1919
};
2020

@@ -30,21 +30,16 @@ export default class TransitionViewScreen extends Component<{}, State> {
3030
const {key, enterDirection, exitDirection} = this.state;
3131
return (
3232
<View padding-20 bg-grey80 flex>
33-
{renderRadioGroup.call(this,
34-
'Enter direction',
35-
'enterDirection',
36-
{top: 'top', bottom: 'bottom', left: 'left', right: 'right'},
37-
{isRow: true})}
38-
{renderRadioGroup.call(this,
39-
'Exit direction',
40-
'exitDirection',
41-
{top: 'top', bottom: 'bottom', left: 'left', right: 'right'},
42-
{isRow: true})}
33+
{renderRadioGroup.call(this, 'Enter direction', 'enterDirection', Incubator.TransitionViewDirectionEnum, {
34+
isRow: true
35+
})}
36+
{renderRadioGroup.call(this, 'Exit direction', 'exitDirection', Incubator.TransitionViewDirectionEnum, {
37+
isRow: true
38+
})}
4339
<Button label="Refresh" onPress={() => this.setState({key: key + 1})}/>
4440
<View flex center>
4541
<TransitionView
4642
key={`${key}`}
47-
// @ts-expect-error
4843
ref={this.ref}
4944
enterFrom={enterDirection}
5045
exitTo={exitDirection}

demo/src/screens/incubatorScreens/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {gestureHandlerRootHOC} from 'react-native-gesture-handler';
33
export function registerScreens(registrar) {
44
registrar('unicorn.incubator.TouchableOpacityScreen', () =>
55
gestureHandlerRootHOC(require('./TouchableOpacityScreen').default));
6+
registrar('unicorn.incubator.IncubatorDialogScreen', () => require('./IncubatorDialogScreen').default);
67
registrar('unicorn.components.IncubatorExpandableOverlayScreen', () => require('./IncubatorExpandableOverlayScreen').default);
78
registrar('unicorn.components.IncubatorTextFieldScreen', () => require('./IncubatorTextFieldScreen').default);
89
registrar('unicorn.incubator.PanViewScreen', () => require('./PanViewScreen').default);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { 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;
8+
export { DialogDirections, DialogDirectionsEnum };
9+
interface _DialogProps extends AlignmentModifiers {
10+
/**
11+
* Control visibility of the dialog.
12+
*/
13+
visible?: boolean;
14+
/**
15+
* Callback that is called after the dialog's dismiss (after the animation has ended).
16+
*/
17+
onDismiss?: (props?: DialogProps) => 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 DialogProps = PropsWithChildren<_DialogProps>;
45+
declare const Dialog: {
46+
(props: DialogProps): JSX.Element;
47+
displayName: string;
48+
directions: typeof PanningDirectionsEnum;
49+
};
50+
export default Dialog;
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import React, { PropsWithChildren } from 'react';
1+
import React from 'react';
22
import { ViewProps } from '../../components/view';
3-
import { ForwardRefInjectedProps } from '../../commons/new';
4-
import { Direction } from '../hooks/useHiddenLocation';
53
import { TransitionViewAnimationType } from './useAnimationEndNotifier';
4+
import { TransitionViewDirection, TransitionViewDirectionEnum } from './useAnimatedTranslator';
65
import { AnimatedTransitionProps } from './useAnimatedTransition';
7-
export { Direction, TransitionViewAnimationType };
8-
export declare type TransitionViewProps = AnimatedTransitionProps & ViewProps;
9-
declare type Props = PropsWithChildren<TransitionViewProps> & ForwardRefInjectedProps;
6+
export { TransitionViewDirection, TransitionViewDirectionEnum, TransitionViewAnimationType };
7+
export interface TransitionViewProps extends AnimatedTransitionProps, ViewProps {
8+
ref?: any;
9+
}
1010
interface Statics {
1111
animateOut: () => void;
12+
directions: typeof TransitionViewDirectionEnum;
1213
}
13-
declare const _default: React.ComponentType<Props> & Statics;
14+
declare const _default: React.ComponentType<TransitionViewProps> & Statics;
1415
export default _default;

generatedTypes/src/incubator/TransitionView/useAnimatedTransition.d.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
import { Direction, HiddenLocation } from '../hooks/useHiddenLocation';
2-
import { AnimationNotifierEndProps } from './useAnimationEndNotifier';
1+
import { HiddenLocation } from '../hooks/useHiddenLocation';
2+
import { TransitionViewDirection } from './useAnimatedTranslator';
3+
import { AnimationNotifierEndProps, TransitionViewAnimationType } from './useAnimationEndNotifier';
34
export interface AnimatedTransitionProps extends AnimationNotifierEndProps {
5+
/**
6+
* Callback to the animation start.
7+
*/
8+
onAnimationStart?: (animationType: TransitionViewAnimationType) => void;
49
/**
510
* If this is given there will be an enter animation from this direction.
611
*/
7-
enterFrom?: Direction;
12+
enterFrom?: TransitionViewDirection;
813
/**
914
* If this is given there will be an exit animation to this direction.
1015
*/
11-
exitTo?: Direction;
16+
exitTo?: TransitionViewDirection;
1217
}
1318
declare type Props = AnimatedTransitionProps & {
1419
hiddenLocation: HiddenLocation;

generatedTypes/src/incubator/TransitionView/useAnimatedTranslator.d.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
import { Direction } from '../hooks/useHiddenLocation';
1+
import { PanningDirections, PanningDirectionsEnum } from '../panView';
2+
export declare const TransitionViewDirectionEnum: typeof PanningDirectionsEnum;
3+
export declare type TransitionViewDirection = PanningDirections;
24
export interface TranslatorProps {
35
initialVisibility: boolean;
46
}
57
export default function useAnimatedTranslator(props: TranslatorProps): {
68
init: (to: {
79
x: number;
810
y: number;
9-
}, animationDirection: Direction, callback: (isFinished: boolean) => void) => void;
11+
}, animationDirection: TransitionViewDirection, callback: (isFinished: boolean) => void) => void;
1012
animate: (to: {
1113
x: number;
1214
y: number;
13-
}, animationDirection: Direction, callback: (isFinished: boolean) => void) => void;
15+
}, animationDirection: TransitionViewDirection, callback: (isFinished: boolean) => void) => void;
1416
animatedStyle: {
1517
transform: ({
1618
translateX: number;
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import { RefObject } from 'react';
22
import { View, LayoutChangeEvent } from 'react-native';
3-
export declare type Direction = 'top' | 'bottom' | 'left' | 'right';
4-
export interface HiddenLocation {
3+
import { PanningDirectionsEnum } from '../panView';
4+
declare type HiddenLocationRecord = Record<PanningDirectionsEnum, number>;
5+
export interface HiddenLocation extends HiddenLocationRecord {
56
isDefault: boolean;
6-
top: number;
7-
bottom: number;
8-
left: number;
9-
right: number;
107
}
118
export interface HiddenLocationProps<T extends View> {
129
containerRef: RefObject<T>;
@@ -15,3 +12,4 @@ export default function useHiddenLocation<T extends View>(props: HiddenLocationP
1512
onLayout: (event: LayoutChangeEvent) => void;
1613
hiddenLocation: HiddenLocation;
1714
};
15+
export {};

generatedTypes/src/incubator/index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export { default as TextField, TextFieldProps, FieldContextType } from './TextFi
33
export { default as TouchableOpacity, TouchableOpacityProps } from './TouchableOpacity';
44
export { default as WheelPicker, WheelPickerProps } from './WheelPicker';
55
export { default as PanView, PanViewProps, PanViewDirections, PanViewDismissThreshold } from './panView';
6-
export { default as TransitionView, TransitionViewProps, Direction, TransitionViewAnimationType } from './TransitionView';
6+
export { default as TransitionView, TransitionViewProps, TransitionViewDirection, TransitionViewDirectionEnum, TransitionViewAnimationType } from './TransitionView';
7+
export { default as Dialog, DialogProps } from './Dialog';

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import React from 'react';
22
import { StyleProp, ViewStyle } from 'react-native';
33
import { ViewProps } from '../../components/view';
4-
import { PanViewDirections, PanViewDismissThreshold } from './panningUtil';
5-
export { PanViewDirections, PanViewDismissThreshold };
4+
import { PanningDirections, PanningDirectionsEnum, PanningDismissThreshold } from './panningUtil';
5+
declare type PanViewDirections = PanningDirections;
6+
declare const PanViewDirectionsEnum: typeof PanningDirectionsEnum;
7+
declare type PanViewDismissThreshold = PanningDismissThreshold;
8+
export { PanningDirections, PanningDirectionsEnum, PanViewDirections, PanViewDirectionsEnum, PanViewDismissThreshold };
69
export interface PanViewProps extends ViewProps {
710
/**
811
* The directions of the allowed pan (default is all)
@@ -42,9 +45,9 @@ declare const _default: React.ComponentClass<PanViewProps & {
4245
}, any> & {
4346
(props: Props): JSX.Element;
4447
displayName: string;
45-
directions: typeof PanViewDirections;
48+
directions: typeof PanningDirectionsEnum;
4649
defaultProps: {
47-
threshold: Required<PanViewDismissThreshold>;
50+
threshold: Required<PanningDismissThreshold>;
4851
};
4952
};
5053
export default _default;
Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import { PanGestureHandlerEventPayload } from 'react-native-gesture-handler';
2-
export declare enum PanViewDirections {
2+
export declare enum PanningDirectionsEnum {
33
UP = "up",
44
DOWN = "down",
55
LEFT = "left",
66
RIGHT = "right"
77
}
8-
export interface Frame {
9-
x: number;
10-
y: number;
11-
}
12-
export interface TranslationOptions {
13-
directionLock?: boolean;
14-
currentTranslation: Frame;
15-
}
16-
export interface PanViewDismissThreshold {
8+
export declare type PanningDirectionsUnion = 'up' | 'down' | 'left' | 'right';
9+
export declare type PanningDirections = PanningDirectionsEnum | PanningDirectionsUnion;
10+
export interface PanningDismissThreshold {
1711
/**
1812
* The (positive) velocity of a drag\swipe past it the view will be dismissed.
1913
*/
@@ -27,10 +21,18 @@ export interface PanViewDismissThreshold {
2721
*/
2822
y?: number;
2923
}
24+
export interface Frame {
25+
x: number;
26+
y: number;
27+
}
28+
export interface TranslationOptions {
29+
directionLock?: boolean;
30+
currentTranslation: Frame;
31+
}
3032
export declare function getTranslationDirectionClamp(translation: Frame, options: TranslationOptions): Frame;
31-
export declare function getTranslation(event: PanGestureHandlerEventPayload, initialTranslation: Frame, directions: PanViewDirections[], options: TranslationOptions): Frame;
32-
export declare const DEFAULT_THRESHOLD: Required<PanViewDismissThreshold>;
33+
export declare function getTranslation(event: PanGestureHandlerEventPayload, initialTranslation: Frame, directions: PanningDirections[], options: TranslationOptions): Frame;
34+
export declare const DEFAULT_THRESHOLD: Required<PanningDismissThreshold>;
3335
/**
3436
* Will return undefined if should not dismiss
3537
*/
36-
export declare function getDismissVelocity(event: PanGestureHandlerEventPayload, directions: PanViewDirections[], options: TranslationOptions, threshold?: PanViewDismissThreshold): Partial<Frame> | undefined;
38+
export declare function getDismissVelocity(event: PanGestureHandlerEventPayload, directions: PanningDirections[], options: TranslationOptions, threshold?: PanningDismissThreshold): Partial<Frame> | undefined;

0 commit comments

Comments
 (0)