-
Notifications
You must be signed in to change notification settings - Fork 734
Feat/incubator dialog fixes and improvements #1704
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
lidord-wix
merged 16 commits into
master
from
feat/incubator-dialog-fixes-and-improvements
Dec 12, 2021
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
f2b645a
Add ImperativeDialog - fix bug while keeping simple
M-i-k-e-l 3a51d6c
Add alignment support
M-i-k-e-l ecfdeb8
Refactor (add useFadeView) and fix pointerEvents
M-i-k-e-l b7cfdff
Fix onRequestClose
M-i-k-e-l 654249b
Support useSafeArea
M-i-k-e-l 2f2b17c
Merge branch 'master' into feat/incubator-dialog-fixes-and-improvements
M-i-k-e-l 9d8b588
Add supportedOrientations and accessibilityLabel
M-i-k-e-l 018683a
Revert "Add supportedOrientations and accessibilityLabel"
M-i-k-e-l 39ad109
Add modalProps.supportedOrientations to the screen
M-i-k-e-l 9957846
Bring back containerStyle
M-i-k-e-l a5cbaab
Workaround useSafeArea performance issue
M-i-k-e-l 4bb9fb8
Fix types
M-i-k-e-l dcc9ad1
Merge branch 'master' into feat/incubator-dialog-fixes-and-improvements
M-i-k-e-l 639b0a1
Remove containerStyle again
M-i-k-e-l 11f0b9b
Merge branch 'master' into feat/incubator-dialog-fixes-and-improvements
M-i-k-e-l 04b53df
Add api
M-i-k-e-l File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
import { ImperativeDialogMethods, DialogDirections, DialogDirectionsEnum } from './types'; | ||
export { DialogDirections, DialogDirectionsEnum }; | ||
declare const _default: React.ForwardRefExoticComponent<import("./types")._DialogProps & { | ||
children?: React.ReactNode; | ||
} & React.RefAttributes<ImperativeDialogMethods>>; | ||
export default _default; |
11 changes: 11 additions & 0 deletions
11
generatedTypes/src/incubator/Dialog/helpers/useAlignmentStyle.d.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { AlignmentModifiers } from '../../../commons/modifiers'; | ||
export declare enum AlignmentType { | ||
DEFAULT = "default", | ||
BOTTOM = "bottom", | ||
TOP = "top" | ||
} | ||
declare const useAlignmentStyle: (props: AlignmentModifiers) => { | ||
alignmentType: AlignmentType; | ||
alignmentStyle: any[]; | ||
}; | ||
export default useAlignmentStyle; |
15 changes: 15 additions & 0 deletions
15
generatedTypes/src/incubator/Dialog/helpers/useFadeView.d.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/// <reference types="react" /> | ||
import { ModalProps } from '../../../components/modal'; | ||
import { TransitionViewAnimationType } from '../../TransitionView'; | ||
import { ImperativeDialogProps } from '../types'; | ||
export declare type AnimationType = TransitionViewAnimationType; | ||
export declare type FadeViewProps = Pick<ImperativeDialogProps, 'initialVisibility' | 'testID'> & Pick<ModalProps, 'overlayBackgroundColor'>; | ||
export interface FadeViewMethods { | ||
hideNow: () => void; | ||
} | ||
declare const useFadeView: (props: FadeViewProps) => { | ||
FadeView: JSX.Element; | ||
hideNow: () => void; | ||
fade: (type: AnimationType) => void; | ||
}; | ||
export default useFadeView; |
17 changes: 17 additions & 0 deletions
17
generatedTypes/src/incubator/Dialog/helpers/useSafeAreaView.d.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/// <reference types="react" /> | ||
import { ImperativeDialogProps } from '../types'; | ||
import { AlignmentType } from './useAlignmentStyle'; | ||
export interface SafeAreaProps extends Pick<ImperativeDialogProps, 'useSafeArea'> { | ||
alignmentType: AlignmentType; | ||
} | ||
/** | ||
* TODO: technically useSafeArea can be sent to either PanView or TransitionView. | ||
* however that causes some performance \ UI bugs (when there is a safe area). | ||
* TransitionView is less pronouns than PanView but still not good. | ||
* We think this is because of reanimation 2, we should re-visit this problem later. | ||
*/ | ||
declare const useSafeAreaView: (props: SafeAreaProps) => { | ||
topSafeArea: JSX.Element | undefined; | ||
bottomSafeArea: JSX.Element | undefined; | ||
}; | ||
export default useSafeAreaView; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,15 @@ | ||
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; | ||
/// <reference types="react" /> | ||
import { ImperativeDialogProps, DialogDirections, DialogDirectionsEnum } from './types'; | ||
export { DialogDirections, DialogDirectionsEnum }; | ||
interface _DialogProps extends AlignmentModifiers { | ||
export interface DialogProps extends Omit<ImperativeDialogProps, 'initialVisibility'> { | ||
/** | ||
* Control visibility of the dialog. | ||
* The 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; | ||
directions: typeof import("../panView").PanningDirectionsEnum; | ||
}; | ||
export default Dialog; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { PropsWithChildren } from 'react'; | ||
import { AlignmentModifiers } from '../../commons/modifiers'; | ||
import { ModalProps } from '../../components/modal'; | ||
import { ViewProps } from '../../components/view'; | ||
import { PanningDirections, PanningDirectionsEnum } from '../panView'; | ||
declare type DialogDirections = PanningDirections; | ||
declare const DialogDirectionsEnum: typeof PanningDirectionsEnum; | ||
export { DialogDirections, DialogDirectionsEnum }; | ||
export interface _DialogProps extends AlignmentModifiers, Pick<ViewProps, 'useSafeArea'> { | ||
/** | ||
* The initial visibility of the dialog. | ||
*/ | ||
initialVisibility?: boolean; | ||
/** | ||
* Callback that is called after the dialog's dismiss (after the animation has ended). | ||
*/ | ||
onDismiss?: (props?: ImperativeDialogProps) => void; | ||
/** | ||
* The direction from which and to which the dialog is animating \ panning (default down). | ||
*/ | ||
direction?: DialogDirections; | ||
/** | ||
* 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 ImperativeDialogProps = PropsWithChildren<_DialogProps>; | ||
export interface ImperativeDialogMethods { | ||
open: () => void; | ||
close: () => void; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import React, {useMemo, useCallback, useState, useImperativeHandle, forwardRef} from 'react'; | ||
import {StyleSheet} from 'react-native'; | ||
import View from '../../components/view'; | ||
import Modal from '../../components/modal'; | ||
import TransitionView, {TransitionViewAnimationType} from '../TransitionView'; | ||
import PanView from '../panView'; | ||
import useAlignmentStyle from './helpers/useAlignmentStyle'; | ||
import useSafeAreaView from './helpers/useSafeAreaView'; | ||
import useFadeView from './helpers/useFadeView'; | ||
import {ImperativeDialogProps, ImperativeDialogMethods, DialogDirections, DialogDirectionsEnum} from './types'; | ||
export {DialogDirections, DialogDirectionsEnum}; | ||
|
||
const ImperativeDialog = (props: ImperativeDialogProps, ref: any) => { | ||
const { | ||
initialVisibility = false, | ||
onDismiss, | ||
direction = DialogDirectionsEnum.DOWN, | ||
children, | ||
ignoreBackgroundPress, | ||
modalProps = {}, | ||
useSafeArea, | ||
testID | ||
} = props; | ||
const transitionAnimatorRef = React.createRef<typeof TransitionView>(); | ||
const {overlayBackgroundColor, ...otherModalProps} = modalProps; | ||
const [visible, setVisible] = useState(initialVisibility); | ||
const {alignmentType, alignmentStyle} = useAlignmentStyle(props); | ||
const {topSafeArea, bottomSafeArea} = useSafeAreaView({useSafeArea, alignmentType}); | ||
const {FadeView, hideNow, fade} = useFadeView({ | ||
initialVisibility, | ||
testID: `${testID}.overlayFadingBackground`, | ||
overlayBackgroundColor | ||
}); | ||
|
||
const open = useCallback(() => { | ||
if (!visible) { | ||
setVisible(true); | ||
} | ||
}, [visible, setVisible]); | ||
|
||
const close = useCallback(() => { | ||
if (visible) { | ||
transitionAnimatorRef.current?.animateOut(); | ||
} | ||
}, [visible, transitionAnimatorRef]); | ||
|
||
useImperativeHandle(ref, () => ({ | ||
open, | ||
close | ||
})); | ||
|
||
const directions = useMemo((): DialogDirections[] => { | ||
return [direction]; | ||
}, [direction]); | ||
|
||
const onBackgroundPress = useCallback(() => { | ||
close(); | ||
}, [close]); | ||
|
||
const onPanViewDismiss = useCallback(() => { | ||
hideNow(); | ||
setVisible(false); | ||
onDismiss?.(); | ||
}, [hideNow, onDismiss, setVisible]); | ||
|
||
const onTransitionAnimationEnd = useCallback((type: TransitionViewAnimationType) => { | ||
if (type === 'exit') { | ||
setVisible(false); | ||
onDismiss?.(); | ||
} | ||
}, | ||
[onDismiss, setVisible]); | ||
|
||
const renderDialog = () => { | ||
return ( | ||
<PanView | ||
directions={directions} | ||
dismissible | ||
animateToOrigin | ||
containerStyle={styles.panView} | ||
onDismiss={onPanViewDismiss} | ||
> | ||
<TransitionView | ||
ref={transitionAnimatorRef} | ||
enterFrom={direction} | ||
exitTo={direction} | ||
onAnimationStart={fade} | ||
onAnimationEnd={onTransitionAnimationEnd} | ||
> | ||
{topSafeArea} | ||
{children} | ||
{bottomSafeArea} | ||
</TransitionView> | ||
</PanView> | ||
); | ||
}; | ||
|
||
return ( | ||
<Modal | ||
transparent | ||
animationType={'none'} | ||
{...otherModalProps} | ||
testID={`${testID}.modal`} | ||
useGestureHandlerRootView | ||
visible={visible} | ||
onBackgroundPress={ignoreBackgroundPress ? undefined : onBackgroundPress} | ||
onRequestClose={ignoreBackgroundPress ? undefined : onBackgroundPress} | ||
onDismiss={undefined} | ||
> | ||
{FadeView} | ||
<View pointerEvents={'box-none'} style={alignmentStyle}> | ||
{renderDialog()} | ||
</View> | ||
</Modal> | ||
); | ||
}; | ||
|
||
ImperativeDialog.displayName = 'IGNORE'; | ||
|
||
export default forwardRef<ImperativeDialogMethods, ImperativeDialogProps>(ImperativeDialog); | ||
|
||
const styles = StyleSheet.create({ | ||
panView: { | ||
position: 'absolute' | ||
} | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "Dialog", | ||
"category": "incubator", | ||
"description": "Component for displaying custom content inside a popup dialog", | ||
"note": "Use alignment modifiers to control the dialog position (top, bottom, centerV, centerH, etc... by default the dialog is aligned to center)", | ||
"modifiers": ["alignment"], | ||
"example": "https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/incubatorScreens/IncubatorDialogScreen.js", | ||
"props": [ | ||
{"name": "visible", "type": "boolean", "description": "The visibility of the dialog"}, | ||
{"name": "onDismiss", "type": "(props?: ImperativeDialogProps) => void", "description": "Callback that is called after the dialog's dismiss (after the animation has ended)."}, | ||
{ | ||
"name": "direction", | ||
"type": "up | down | left | right", | ||
"description": "The direction from which and to which the dialog is animating \\ panning (default bottom).", | ||
"default": "down" | ||
}, | ||
{"name": "ignoreBackgroundPress", "type": "boolean", "description": "Whether or not to ignore background press."}, | ||
{"name": "modalProps", "type": "ModalProps", "description": "Pass props to the dialog modal"}, | ||
{"name": "testID", "type": "string", "description": "Used as a testing identifier"} | ||
] | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.