Skip to content

New Dialog using the new Pan and Transition Views #1576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Nov 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions demo/src/screens/MenuStructure.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export const navigationData = {
title: 'Incubator (Experimental)',
screens: [
{title: 'Native TouchableOpacity', tags: 'touchable native', screen: 'unicorn.incubator.TouchableOpacityScreen'},
{title: '(New) Dialog', tags: 'dialog modal popup alert', screen: 'unicorn.incubator.IncubatorDialogScreen'},
{title: '(New) TextField', tags: 'text field input', screen: 'unicorn.components.IncubatorTextFieldScreen'},
{title: 'ExpandableOverlay', tags: 'text field expandable input picker', screen: 'unicorn.components.IncubatorExpandableOverlayScreen'},
{title: 'WheelPicker (Incubator)', tags: 'wheel picker spinner experimental', screen: 'unicorn.incubator.WheelPickerScreen'},
Expand Down
102 changes: 102 additions & 0 deletions demo/src/screens/incubatorScreens/IncubatorDialogScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React, {Component} from 'react';
import {StyleSheet} from 'react-native';
import {FlatList} from 'react-native-gesture-handler';
import {View, Text, Card, Button, Incubator, Colors, BorderRadiuses} from 'react-native-ui-lib'; //eslint-disable-line

interface Item {
value: string;
label: string;
}

const colors: Item[] = [
{value: Colors.red10, label: 'Red10'},
{value: Colors.red30, label: 'Red30'},
{value: Colors.red50, label: 'Red50'},
{value: Colors.red70, label: 'Red70'},
{value: Colors.blue10, label: 'Blue10'},
{value: Colors.blue30, label: 'Blue30'},
{value: Colors.blue50, label: 'Blue50'},
{value: Colors.blue70, label: 'Blue70'},
{value: Colors.purple10, label: 'Purple10'},
{value: Colors.purple30, label: 'Purple30'},
{value: Colors.purple50, label: 'Purple50'},
{value: Colors.purple70, label: 'Purple70'},
{value: Colors.green10, label: 'Green10'},
{value: Colors.green30, label: 'Green30'},
{value: Colors.green50, label: 'Green50'},
{value: Colors.green70, label: 'Green70'},
{value: Colors.yellow10, label: 'Yellow10'},
{value: Colors.yellow30, label: 'Yellow30'},
{value: Colors.yellow50, label: 'Yellow50'},
{value: Colors.yellow70, label: 'Yellow70'}
];

export default class IncubatorDialogScreen extends Component {
state = {visible: false};

renderVerticalItem = ({item}: {item: Item}) => {
return (
<Text text50 margin-20 color={item.value}>
{item.label}
</Text>
);
};

keyExtractor = (item: Item) => {
return item.value;
};

openDialog = () => {
this.setState({visible: true});
};

closeDialog = () => {
this.setState({visible: false});
};

render() {
const {visible} = this.state;

return (
<View bg-dark80 flex padding-20>
<Card height={100} center padding-20>
<Text text50>IncubatorDialogScreen</Text>
</Card>
<View flex center>
<Button marginV-20 label="Open Dialog" onPress={this.openDialog}/>
</View>
<Incubator.Dialog visible={visible} onDismiss={this.closeDialog} bottom containerStyle={styles.dialogContainer}>
<View style={styles.dialog}>
<Text text60 margin-s2>
Title (swipe here)
</Text>
<View height={1} bg-grey40/>
<FlatList
showsVerticalScrollIndicator={false}
style={styles.verticalScroll}
data={colors}
renderItem={this.renderVerticalItem}
keyExtractor={this.keyExtractor}
/>
</View>
</Incubator.Dialog>
</View>
);
}
}

const styles = StyleSheet.create({
dialogContainer: {
bottom: 20,
alignSelf: 'center'
},
dialog: {
backgroundColor: Colors.white,
width: 200,
height: 300,
borderRadius: BorderRadiuses.br20
},
verticalScroll: {
marginTop: 20
}
});
25 changes: 10 additions & 15 deletions demo/src/screens/incubatorScreens/TransitionViewScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ const {TransitionView} = Incubator;
import {renderRadioGroup} from '../ExampleScreenPresenter';

interface State {
enterDirection: Incubator.Direction;
exitDirection: Incubator.Direction;
enterDirection: Incubator.TransitionViewDirection;
exitDirection: Incubator.TransitionViewDirection;
key: number;
}

export default class TransitionViewScreen extends Component<{}, State> {
private ref = React.createRef<typeof TransitionView>();
state = {
enterDirection: 'left' as Incubator.Direction,
exitDirection: 'bottom' as Incubator.Direction,
enterDirection: Incubator.TransitionViewDirectionEnum.LEFT,
exitDirection: Incubator.TransitionViewDirectionEnum.DOWN,
key: 1
};

Expand All @@ -30,21 +30,16 @@ export default class TransitionViewScreen extends Component<{}, State> {
const {key, enterDirection, exitDirection} = this.state;
return (
<View padding-20 bg-grey80 flex>
{renderRadioGroup.call(this,
'Enter direction',
'enterDirection',
{top: 'top', bottom: 'bottom', left: 'left', right: 'right'},
{isRow: true})}
{renderRadioGroup.call(this,
'Exit direction',
'exitDirection',
{top: 'top', bottom: 'bottom', left: 'left', right: 'right'},
{isRow: true})}
{renderRadioGroup.call(this, 'Enter direction', 'enterDirection', Incubator.TransitionViewDirectionEnum, {
isRow: true
})}
{renderRadioGroup.call(this, 'Exit direction', 'exitDirection', Incubator.TransitionViewDirectionEnum, {
isRow: true
})}
<Button label="Refresh" onPress={() => this.setState({key: key + 1})}/>
<View flex center>
<TransitionView
key={`${key}`}
// @ts-expect-error
ref={this.ref}
enterFrom={enterDirection}
exitTo={exitDirection}
Expand Down
1 change: 1 addition & 0 deletions demo/src/screens/incubatorScreens/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {gestureHandlerRootHOC} from 'react-native-gesture-handler';
export function registerScreens(registrar) {
registrar('unicorn.incubator.TouchableOpacityScreen', () =>
gestureHandlerRootHOC(require('./TouchableOpacityScreen').default));
registrar('unicorn.incubator.IncubatorDialogScreen', () => require('./IncubatorDialogScreen').default);
registrar('unicorn.components.IncubatorExpandableOverlayScreen', () => require('./IncubatorExpandableOverlayScreen').default);
registrar('unicorn.components.IncubatorTextFieldScreen', () => require('./IncubatorTextFieldScreen').default);
registrar('unicorn.incubator.PanViewScreen', () => require('./PanViewScreen').default);
Expand Down
50 changes: 50 additions & 0 deletions generatedTypes/src/incubator/Dialog/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { PropsWithChildren } from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import { PanningDirections, PanningDirectionsEnum } from '../panView';
import { ModalProps } from '../../components/modal';
import { AlignmentModifiers } from '../../commons/modifiers';
declare type DialogDirections = PanningDirections;
declare const DialogDirectionsEnum: typeof PanningDirectionsEnum;
export { DialogDirections, DialogDirectionsEnum };
interface _DialogProps extends AlignmentModifiers {
/**
* Control visibility of the dialog.
*/
visible?: boolean;
/**
* Callback that is called after the dialog's dismiss (after the animation has ended).
*/
onDismiss?: (props?: DialogProps) => void;
/**
* The direction from which and to which the dialog is animating \ panning (default bottom).
*/
direction?: DialogDirections;
/**
* The Dialog`s container style (it is set to {position: 'absolute'})
*/
containerStyle?: StyleProp<ViewStyle>;
/**
* Whether or not to ignore background press.
*/
ignoreBackgroundPress?: boolean;
/**
* Additional props for the modal.
*/
modalProps?: ModalProps;
/**
* Used to locate this view in end-to-end tests
* The container has the unchanged id.
* Currently supported inner IDs:
* TODO: add missing <TestID>(s?)
* <TestID>.modal - the Modal's id.
* <TestID>.overlayFadingBackground - the fading background id.
*/
testID?: string;
}
export declare type DialogProps = PropsWithChildren<_DialogProps>;
declare const Dialog: {
(props: DialogProps): JSX.Element;
displayName: string;
directions: typeof PanningDirectionsEnum;
};
export default Dialog;
15 changes: 8 additions & 7 deletions generatedTypes/src/incubator/TransitionView/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React, { PropsWithChildren } from 'react';
import React from 'react';
import { ViewProps } from '../../components/view';
import { ForwardRefInjectedProps } from '../../commons/new';
import { Direction } from '../hooks/useHiddenLocation';
import { TransitionViewAnimationType } from './useAnimationEndNotifier';
import { TransitionViewDirection, TransitionViewDirectionEnum } from './useAnimatedTranslator';
import { AnimatedTransitionProps } from './useAnimatedTransition';
export { Direction, TransitionViewAnimationType };
export declare type TransitionViewProps = AnimatedTransitionProps & ViewProps;
declare type Props = PropsWithChildren<TransitionViewProps> & ForwardRefInjectedProps;
export { TransitionViewDirection, TransitionViewDirectionEnum, TransitionViewAnimationType };
export interface TransitionViewProps extends AnimatedTransitionProps, ViewProps {
ref?: any;
}
interface Statics {
animateOut: () => void;
directions: typeof TransitionViewDirectionEnum;
}
declare const _default: React.ComponentType<Props> & Statics;
declare const _default: React.ComponentType<TransitionViewProps> & Statics;
export default _default;
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Direction, HiddenLocation } from '../hooks/useHiddenLocation';
import { AnimationNotifierEndProps } from './useAnimationEndNotifier';
import { HiddenLocation } from '../hooks/useHiddenLocation';
import { TransitionViewDirection } from './useAnimatedTranslator';
import { AnimationNotifierEndProps, TransitionViewAnimationType } from './useAnimationEndNotifier';
export interface AnimatedTransitionProps extends AnimationNotifierEndProps {
/**
* Callback to the animation start.
*/
onAnimationStart?: (animationType: TransitionViewAnimationType) => void;
/**
* If this is given there will be an enter animation from this direction.
*/
enterFrom?: Direction;
enterFrom?: TransitionViewDirection;
/**
* If this is given there will be an exit animation to this direction.
*/
exitTo?: Direction;
exitTo?: TransitionViewDirection;
}
declare type Props = AnimatedTransitionProps & {
hiddenLocation: HiddenLocation;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { Direction } from '../hooks/useHiddenLocation';
import { PanningDirections, PanningDirectionsEnum } from '../panView';
export declare const TransitionViewDirectionEnum: typeof PanningDirectionsEnum;
export declare type TransitionViewDirection = PanningDirections;
export interface TranslatorProps {
initialVisibility: boolean;
}
export default function useAnimatedTranslator(props: TranslatorProps): {
init: (to: {
x: number;
y: number;
}, animationDirection: Direction, callback: (isFinished: boolean) => void) => void;
}, animationDirection: TransitionViewDirection, callback: (isFinished: boolean) => void) => void;
animate: (to: {
x: number;
y: number;
}, animationDirection: Direction, callback: (isFinished: boolean) => void) => void;
}, animationDirection: TransitionViewDirection, callback: (isFinished: boolean) => void) => void;
animatedStyle: {
transform: ({
translateX: number;
Expand Down
10 changes: 4 additions & 6 deletions generatedTypes/src/incubator/hooks/useHiddenLocation.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { RefObject } from 'react';
import { View, LayoutChangeEvent } from 'react-native';
export declare type Direction = 'top' | 'bottom' | 'left' | 'right';
export interface HiddenLocation {
import { PanningDirectionsEnum } from '../panView';
declare type HiddenLocationRecord = Record<PanningDirectionsEnum, number>;
export interface HiddenLocation extends HiddenLocationRecord {
isDefault: boolean;
top: number;
bottom: number;
left: number;
right: number;
}
export interface HiddenLocationProps<T extends View> {
containerRef: RefObject<T>;
Expand All @@ -15,3 +12,4 @@ export default function useHiddenLocation<T extends View>(props: HiddenLocationP
onLayout: (event: LayoutChangeEvent) => void;
hiddenLocation: HiddenLocation;
};
export {};
3 changes: 2 additions & 1 deletion generatedTypes/src/incubator/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export { default as TextField, TextFieldProps, FieldContextType } from './TextFi
export { default as TouchableOpacity, TouchableOpacityProps } from './TouchableOpacity';
export { default as WheelPicker, WheelPickerProps } from './WheelPicker';
export { default as PanView, PanViewProps, PanViewDirections, PanViewDismissThreshold } from './panView';
export { default as TransitionView, TransitionViewProps, Direction, TransitionViewAnimationType } from './TransitionView';
export { default as TransitionView, TransitionViewProps, TransitionViewDirection, TransitionViewDirectionEnum, TransitionViewAnimationType } from './TransitionView';
export { default as Dialog, DialogProps } from './Dialog';
11 changes: 7 additions & 4 deletions generatedTypes/src/incubator/panView/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import { ViewProps } from '../../components/view';
import { PanViewDirections, PanViewDismissThreshold } from './panningUtil';
export { PanViewDirections, PanViewDismissThreshold };
import { PanningDirections, PanningDirectionsEnum, PanningDismissThreshold } from './panningUtil';
declare type PanViewDirections = PanningDirections;
declare const PanViewDirectionsEnum: typeof PanningDirectionsEnum;
declare type PanViewDismissThreshold = PanningDismissThreshold;
export { PanningDirections, PanningDirectionsEnum, PanViewDirections, PanViewDirectionsEnum, PanViewDismissThreshold };
export interface PanViewProps extends ViewProps {
/**
* The directions of the allowed pan (default is all)
Expand Down Expand Up @@ -42,9 +45,9 @@ declare const _default: React.ComponentClass<PanViewProps & {
}, any> & {
(props: Props): JSX.Element;
displayName: string;
directions: typeof PanViewDirections;
directions: typeof PanningDirectionsEnum;
defaultProps: {
threshold: Required<PanViewDismissThreshold>;
threshold: Required<PanningDismissThreshold>;
};
};
export default _default;
28 changes: 15 additions & 13 deletions generatedTypes/src/incubator/panView/panningUtil.d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { PanGestureHandlerEventPayload } from 'react-native-gesture-handler';
export declare enum PanViewDirections {
export declare enum PanningDirectionsEnum {
UP = "up",
DOWN = "down",
LEFT = "left",
RIGHT = "right"
}
export interface Frame {
x: number;
y: number;
}
export interface TranslationOptions {
directionLock?: boolean;
currentTranslation: Frame;
}
export interface PanViewDismissThreshold {
export declare type PanningDirectionsUnion = 'up' | 'down' | 'left' | 'right';
export declare type PanningDirections = PanningDirectionsEnum | PanningDirectionsUnion;
export interface PanningDismissThreshold {
/**
* The (positive) velocity of a drag\swipe past it the view will be dismissed.
*/
Expand All @@ -27,10 +21,18 @@ export interface PanViewDismissThreshold {
*/
y?: number;
}
export interface Frame {
x: number;
y: number;
}
export interface TranslationOptions {
directionLock?: boolean;
currentTranslation: Frame;
}
export declare function getTranslationDirectionClamp(translation: Frame, options: TranslationOptions): Frame;
export declare function getTranslation(event: PanGestureHandlerEventPayload, initialTranslation: Frame, directions: PanViewDirections[], options: TranslationOptions): Frame;
export declare const DEFAULT_THRESHOLD: Required<PanViewDismissThreshold>;
export declare function getTranslation(event: PanGestureHandlerEventPayload, initialTranslation: Frame, directions: PanningDirections[], options: TranslationOptions): Frame;
export declare const DEFAULT_THRESHOLD: Required<PanningDismissThreshold>;
/**
* Will return undefined if should not dismiss
*/
export declare function getDismissVelocity(event: PanGestureHandlerEventPayload, directions: PanViewDirections[], options: TranslationOptions, threshold?: PanViewDismissThreshold): Partial<Frame> | undefined;
export declare function getDismissVelocity(event: PanGestureHandlerEventPayload, directions: PanningDirections[], options: TranslationOptions, threshold?: PanningDismissThreshold): Partial<Frame> | undefined;
Loading