-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(example): create modal in the example (#59)
* Add modal with buttons * Add ability to deactivate a page navigation * Add subtitles modal in program details page * use the useLockSpatialNavigation hook to deactivate parent navigator * clean modal locking process as it was dirty * correct dubious type declaration for GenericModal component * remove isFirstRender as a much more simple solution exists * add navigation event handling, preventing goBack on back key press * extract hook to custom hook for the sake of clarity * displace modal logic to Modal component * clear useLockModal for better clarity * change modal display to have better view * separate modal display from spatial navigation part * use hideModal instead of setIsModalVisible * rename Modal to Overlay * correct placement of Overlay in Modal
- Loading branch information
1 parent
bb98f64
commit 9588f16
Showing
7 changed files
with
209 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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 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,54 @@ | ||
import styled from '@emotion/native'; | ||
import React from 'react'; | ||
import { View, ModalProps } from 'react-native'; | ||
import { Typography } from '../../design-system/components/Typography'; | ||
import { Spacer } from '../../design-system/components/Spacer'; | ||
import { colors } from '../../design-system/theme/colors'; | ||
import { SpatialNavigationOverlay } from './SpatialNavigationOverlay/SpatialNavigationOverlay'; | ||
|
||
type CustomModalProps = ModalProps & { | ||
isModalVisible: boolean; | ||
hideModal: () => void; | ||
children: React.ReactNode; | ||
title: string; | ||
}; | ||
|
||
export const Modal = ({ isModalVisible, hideModal, children, title }: CustomModalProps) => { | ||
if (!isModalVisible) return null; | ||
|
||
return ( | ||
<StyledModal> | ||
<ModalContentContainer> | ||
<Typography variant="title" fontWeight="strong"> | ||
{title} | ||
</Typography> | ||
<Spacer gap="$8" /> | ||
<SpatialNavigationOverlay isModalVisible={isModalVisible} hideModal={hideModal}> | ||
{children} | ||
</SpatialNavigationOverlay> | ||
</ModalContentContainer> | ||
</StyledModal> | ||
); | ||
}; | ||
|
||
const StyledModal = styled(View)({ | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
right: 0, | ||
bottom: 0, | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
}); | ||
|
||
const ModalContentContainer = styled(View)({ | ||
minHeight: 200, | ||
minWidth: 200, | ||
backgroundColor: colors.background.main, | ||
borderWidth: 2, | ||
borderColor: colors.primary.light, | ||
padding: 32, | ||
margin: 16, | ||
borderRadius: 16, | ||
justifyContent: 'center', | ||
}); |
18 changes: 18 additions & 0 deletions
18
packages/example/src/components/modals/SpatialNavigationOverlay/SpatialNavigationOverlay.tsx
This file contains 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,18 @@ | ||
import { SpatialNavigationRoot } from '../../../../../lib/src/spatial-navigation/components/Root'; | ||
import { useLockOverlay } from './useLockOverlay'; | ||
|
||
type SpatialNavigationOverlayProps = { | ||
isModalVisible: boolean; | ||
hideModal: () => void; | ||
children: React.ReactNode; | ||
}; | ||
|
||
export const SpatialNavigationOverlay = ({ | ||
isModalVisible, | ||
hideModal, | ||
children, | ||
}: SpatialNavigationOverlayProps) => { | ||
useLockOverlay({ isModalVisible, hideModal }); | ||
|
||
return <SpatialNavigationRoot>{children}</SpatialNavigationRoot>; | ||
}; |
43 changes: 43 additions & 0 deletions
43
packages/example/src/components/modals/SpatialNavigationOverlay/useLockOverlay.tsx
This file contains 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,43 @@ | ||
import { useEffect } from 'react'; | ||
import { useLockSpatialNavigation } from '../../../../../lib/src/spatial-navigation/context/LockSpatialNavigationContext'; | ||
import { EventArg, useNavigation } from '@react-navigation/native'; | ||
|
||
interface UseLockProps { | ||
isModalVisible: boolean; | ||
hideModal: () => void; | ||
} | ||
|
||
// This hook is used to lock the spatial navigation of parent navigator when a modal is open | ||
// and to prevent the user from closing the modal by pressing the back button | ||
export const useLockOverlay = ({ isModalVisible, hideModal }: UseLockProps) => { | ||
useLockParentSpatialNavigator(isModalVisible); | ||
usePreventNavigationGoBack(isModalVisible, hideModal); | ||
}; | ||
|
||
const useLockParentSpatialNavigator = (isModalVisible: boolean) => { | ||
const { lock, unlock } = useLockSpatialNavigation(); | ||
useEffect(() => { | ||
if (isModalVisible) { | ||
lock(); | ||
return () => { | ||
unlock(); | ||
}; | ||
} | ||
}, [isModalVisible, lock, unlock]); | ||
}; | ||
|
||
const usePreventNavigationGoBack = (isModalVisible: boolean, hideModal: () => void) => { | ||
const navigation = useNavigation(); | ||
useEffect(() => { | ||
if (isModalVisible) { | ||
const navigationListener = (e: EventArg<'beforeRemove', true>) => { | ||
e.preventDefault(); | ||
hideModal(); | ||
}; | ||
navigation.addListener('beforeRemove', navigationListener); | ||
return () => { | ||
navigation.removeListener('beforeRemove', navigationListener); | ||
}; | ||
} | ||
}, [navigation, isModalVisible, hideModal]); | ||
}; |
This file contains 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,58 @@ | ||
import { DefaultFocus } from '../../../../lib/src/spatial-navigation/context/DefaultFocusContext'; | ||
import { Button } from '../../design-system/components/Button'; | ||
import { Spacer } from '../../design-system/components/Spacer'; | ||
import { Modal } from './Modal'; | ||
|
||
interface SubtitlesModalProps { | ||
isModalVisible: boolean; | ||
setIsModalVisible: (isVisible: boolean) => void; | ||
setSubtitles: (subtitles: string) => void; | ||
} | ||
|
||
export const SubtitlesModal = ({ | ||
isModalVisible, | ||
setIsModalVisible, | ||
setSubtitles, | ||
}: SubtitlesModalProps) => { | ||
return ( | ||
<Modal | ||
isModalVisible={isModalVisible} | ||
hideModal={() => setIsModalVisible(false)} | ||
title={'Choose subtitles'} | ||
> | ||
<DefaultFocus> | ||
<Button | ||
label="English" | ||
onSelect={() => { | ||
setSubtitles('English'); | ||
setIsModalVisible(false); | ||
}} | ||
/> | ||
</DefaultFocus> | ||
<Spacer gap="$8" /> | ||
<Button | ||
label="Spanish" | ||
onSelect={() => { | ||
setSubtitles('Spanish'); | ||
setIsModalVisible(false); | ||
}} | ||
/> | ||
<Spacer gap="$8" /> | ||
<Button | ||
label="Portuguese" | ||
onSelect={() => { | ||
setSubtitles('Portuguese'); | ||
setIsModalVisible(false); | ||
}} | ||
/> | ||
<Spacer gap="$8" /> | ||
<Button | ||
label="None" | ||
onSelect={() => { | ||
setSubtitles('No'); | ||
setIsModalVisible(false); | ||
}} | ||
/> | ||
</Modal> | ||
); | ||
}; |
This file contains 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 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