Skip to content

Commit 0b6d13a

Browse files
committed
fix: blue border
1 parent e26acfb commit 0b6d13a

4 files changed

Lines changed: 38 additions & 8 deletions

File tree

src/components/Modal/BaseModal.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ import ModalContext from './ModalContext';
2929
import ReanimatedModal from './ReanimatedModal';
3030
import type ReanimatedModalProps from './ReanimatedModal/types';
3131
import type BaseModalProps from './types';
32+
import type {FocusTrapOptions} from './types';
3233

3334
const REANIMATED_MODAL_TYPES: Array<ValueOf<typeof CONST.MODAL.MODAL_TYPE>> = [CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED, CONST.MODAL.MODAL_TYPE.FULLSCREEN];
3435

3536
type ModalComponentProps = (ReactNativeModalProps | ReanimatedModalProps) & {
3637
type?: ValueOf<typeof CONST.MODAL.MODAL_TYPE>;
3738
shouldUseReanimatedModal?: boolean;
39+
shouldPreventScrollOnFocus?: boolean;
40+
initialFocus?: FocusTrapOptions['initialFocus'];
3841
};
3942

4043
function ModalComponent({type, shouldUseReanimatedModal, ...props}: ModalComponentProps) {
@@ -334,6 +337,8 @@ function BaseModal(
334337
onDismiss={handleDismissModal}
335338
onSwipeComplete={onClose}
336339
swipeDirection={swipeDirection}
340+
shouldPreventScrollOnFocus={shouldPreventScrollOnFocus}
341+
initialFocus={initialFocus}
337342
swipeThreshold={swipeThreshold}
338343
isVisible={isVisible}
339344
backdropColor={theme.overlay}
@@ -363,18 +368,27 @@ function BaseModal(
363368
onModalWillShow={saveFocusState}
364369
onDismiss={handleDismissModal}
365370
>
366-
<FocusTrapForModal
367-
active={isVisible}
368-
initialFocus={initialFocus}
369-
shouldPreventScroll={shouldPreventScrollOnFocus}
370-
>
371+
{type && !REANIMATED_MODAL_TYPES.includes(type) && !shouldUseReanimatedModal ? (
372+
<FocusTrapForModal
373+
active={isVisible}
374+
initialFocus={initialFocus}
375+
shouldPreventScroll={shouldPreventScrollOnFocus}
376+
>
377+
<Animated.View
378+
style={[styles.defaultModalContainer, modalContainerStyle, modalPaddingStyles, !isVisible && styles.pointerEventsNone, sidePanelReanimatedStyle]}
379+
ref={ref}
380+
>
381+
<ColorSchemeWrapper>{children}</ColorSchemeWrapper>
382+
</Animated.View>
383+
</FocusTrapForModal>
384+
) : (
371385
<Animated.View
372386
style={[styles.defaultModalContainer, modalContainerStyle, modalPaddingStyles, !isVisible && styles.pointerEventsNone, sidePanelReanimatedStyle]}
373387
ref={ref}
374388
>
375389
<ColorSchemeWrapper>{children}</ColorSchemeWrapper>
376390
</Animated.View>
377-
</FocusTrapForModal>
391+
)}
378392
</ModalContent>
379393
{!keyboardStateContextValue?.isKeyboardActive && <NavigationBar />}
380394
</ModalComponent>

src/components/Modal/ReanimatedModal/index.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
33
import type {NativeEventSubscription, ViewStyle} from 'react-native';
44
import {BackHandler, Dimensions, InteractionManager, Modal, View} from 'react-native';
55
import {LayoutAnimationConfig} from 'react-native-reanimated';
6+
import FocusTrapForModal from '@components/FocusTrap/FocusTrapForModal';
67
import KeyboardAvoidingView from '@components/KeyboardAvoidingView';
78
import useThemeStyles from '@hooks/useThemeStyles';
89
import getPlatform from '@libs/getPlatform';
@@ -41,6 +42,8 @@ function ReanimatedModal({
4142
onSwipeComplete,
4243
swipeDirection,
4344
swipeThreshold,
45+
shouldPreventScrollOnFocus,
46+
initialFocus,
4447
...props
4548
}: ReanimatedModalProps) {
4649
const [isVisibleState, setIsVisibleState] = useState(isVisible);
@@ -213,7 +216,13 @@ function ReanimatedModal({
213216
{isVisibleState && containerView}
214217
</KeyboardAvoidingView>
215218
) : (
216-
isVisibleState && containerView
219+
<FocusTrapForModal
220+
active={isVisibleState || isTransitioning || isContainerOpen !== isVisibleState}
221+
initialFocus={initialFocus}
222+
shouldPreventScroll={shouldPreventScrollOnFocus}
223+
>
224+
{isVisibleState && containerView}
225+
</FocusTrapForModal>
217226
)}
218227
</Modal>
219228
</LayoutAnimationConfig>

src/components/Modal/ReanimatedModal/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {NativeSyntheticEvent, StyleProp, ViewProps, ViewStyle} from 'react-
33
import type {ModalProps as ReactNativeModalProps} from 'react-native-modal';
44
import type {SharedValue} from 'react-native-reanimated';
55
import type {ValueOf} from 'type-fest';
6+
import type {FocusTrapOptions} from '@components/Modal/types';
67
import type CONST from '@src/CONST';
78

89
type GestureProps = {
@@ -136,6 +137,12 @@ type ReanimatedModalProps = ViewProps &
136137

137138
/** Modal type */
138139
type?: ValueOf<typeof CONST.MODAL.MODAL_TYPE>;
140+
141+
/** Whether to prevent scroll on focus */
142+
shouldPreventScrollOnFocus?: boolean;
143+
144+
/** Whether to use a custom backdrop for the modal? (This prevents focus issues on desktop) */
145+
initialFocus?: FocusTrapOptions['initialFocus'];
139146
};
140147

141148
type BackdropProps = {

src/components/Modal/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,4 @@ type BaseModalProps = Partial<ReactNativeModalProps> &
131131
};
132132

133133
export default BaseModalProps;
134-
export type {PopoverAnchorPosition, WindowState};
134+
export type {PopoverAnchorPosition, FocusTrapOptions, WindowState};

0 commit comments

Comments
 (0)