-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58004 from software-mansion-labs/side-pane/stage-2
Side Pane Stage 2: Add baseline content for each major section
- Loading branch information
Showing
15 changed files
with
291 additions
and
158 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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,22 @@ | ||
import type {ParamListBase} from '@react-navigation/native'; | ||
import React from 'react'; | ||
import SidePane from '@components/SidePane'; | ||
import type {PlatformStackNavigationState} from '@libs/Navigation/PlatformStackNavigation/types'; | ||
import TopLevelBottomTabBar from './TopLevelBottomTabBar'; | ||
|
||
type RootNavigatorExtraContentProps = { | ||
state: PlatformStackNavigationState<ParamListBase>; | ||
}; | ||
|
||
function RootNavigatorExtraContent({state}: RootNavigatorExtraContentProps) { | ||
return ( | ||
<> | ||
<TopLevelBottomTabBar state={state} /> | ||
<SidePane /> | ||
</> | ||
); | ||
} | ||
|
||
RootNavigatorExtraContent.displayName = 'RootNavigatorExtraContent'; | ||
|
||
export default RootNavigatorExtraContent; |
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
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 React from 'react'; | ||
import Animated, {Easing, Keyframe} from 'react-native-reanimated'; | ||
import {PressableWithoutFeedback} from '@components/Pressable'; | ||
import useLocalize from '@hooks/useLocalize'; | ||
import useThemeStyles from '@hooks/useThemeStyles'; | ||
import CONST from '@src/CONST'; | ||
|
||
type SidePaneOverlayProps = { | ||
/** Whether the side pane is displayed inside of RHP */ | ||
isInNarrowPaneModal: boolean; | ||
|
||
/** Callback fired when pressing the backdrop */ | ||
onBackdropPress: () => void; | ||
}; | ||
|
||
const easing = Easing.bezier(0.76, 0.0, 0.24, 1.0); | ||
|
||
function SidePaneOverlay({isInNarrowPaneModal, onBackdropPress}: SidePaneOverlayProps) { | ||
const styles = useThemeStyles(); | ||
const {translate} = useLocalize(); | ||
|
||
const CustomFadeIn = new Keyframe({ | ||
from: {opacity: 0}, | ||
to: { | ||
opacity: 0.72, | ||
// @ts-expect-error Types mismatch in reanimated, should to be fixed in 3.17 | ||
easing, | ||
}, | ||
}).duration(CONST.MODAL.ANIMATION_TIMING.DEFAULT_IN); | ||
|
||
const CustomFadeOut = new Keyframe({ | ||
from: {opacity: 0.72}, | ||
to: { | ||
opacity: 0, | ||
// @ts-expect-error Types mismatch in reanimated, should to be fixed in 3.17 | ||
easing, | ||
}, | ||
}).duration(CONST.MODAL.ANIMATION_TIMING.DEFAULT_OUT); | ||
|
||
return ( | ||
<Animated.View | ||
style={styles.sidePaneOverlay(isInNarrowPaneModal)} | ||
entering={isInNarrowPaneModal ? undefined : CustomFadeIn} | ||
exiting={isInNarrowPaneModal ? undefined : CustomFadeOut} | ||
> | ||
<PressableWithoutFeedback | ||
accessible | ||
accessibilityLabel={translate('modal.backdropLabel')} | ||
onPress={onBackdropPress} | ||
style={styles.flex1} | ||
/> | ||
</Animated.View> | ||
); | ||
} | ||
|
||
SidePaneOverlay.displayName = 'SidePaneOverlay'; | ||
|
||
export default SidePaneOverlay; |
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 |
---|---|---|
@@ -1,15 +1,139 @@ | ||
/* eslint-disable @typescript-eslint/naming-convention */ | ||
import type {ReactNode} from 'react'; | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import Text from '@components/Text'; | ||
import type {ThemeStyles} from '@styles/index'; | ||
|
||
const getHelpContent = (styles: ThemeStyles, route: string) => { | ||
type HelpContent = { | ||
/** The content to display for this route */ | ||
content?: (styles: ThemeStyles) => ReactNode; | ||
|
||
/** Any children routes that this route has */ | ||
children?: Record<string, HelpContent>; | ||
|
||
/** Whether this route is an exact match or displays parent content */ | ||
isExact?: boolean; | ||
}; | ||
|
||
const helpContentMap: Record<string, HelpContent> = { | ||
r: { | ||
content: (styles: ThemeStyles) => ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Chat Reports</Text> | ||
<Text style={styles.textNormal}>... general chat reports help ...</Text> | ||
</> | ||
), | ||
children: { | ||
':reportID': { | ||
content: (styles: ThemeStyles) => ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Chat Report</Text> | ||
<Text style={styles.textNormal}>... general chat report help ...</Text> | ||
</> | ||
), | ||
}, | ||
}, | ||
}, | ||
search: { | ||
content: (styles: ThemeStyles) => ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Searching Reports</Text> | ||
<Text style={styles.textNormal}>... general search help ...</Text> | ||
</> | ||
), | ||
}, | ||
settings: { | ||
content: (styles: ThemeStyles) => ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Settings</Text> | ||
<Text style={styles.textNormal}>... general settings help ...</Text> | ||
</> | ||
), | ||
children: { | ||
workspaces: { | ||
content: (styles: ThemeStyles) => ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Workspaces</Text> | ||
<Text style={styles.textNormal}>... general workspaces help ...</Text> | ||
</> | ||
), | ||
children: { | ||
':policyID': { | ||
content: (styles: ThemeStyles) => ( | ||
<> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Workspace Settings</Text> | ||
<Text style={styles.textNormal}>... general workspace settings help ...</Text> | ||
</> | ||
), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
type DiagnosticDataProps = { | ||
styles: ThemeStyles; | ||
route: string; | ||
isExactMatch?: boolean; | ||
children?: ReactNode; | ||
}; | ||
|
||
function DiagnosticData({styles, route, children, isExactMatch}: DiagnosticDataProps) { | ||
const diagnosticTitle = isExactMatch ? 'Help content found for route:' : 'Missing help content for route:'; | ||
|
||
return ( | ||
<View style={styles.ph5}> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>Missing page for route</Text> | ||
<Text style={[styles.textHeadlineH1, styles.mb4]}>{diagnosticTitle}</Text> | ||
<Text style={styles.textNormal}>{route}</Text> | ||
{!!children && ( | ||
<> | ||
<View style={[styles.sectionDividerLine, styles.mv5]} /> | ||
{children} | ||
</> | ||
)} | ||
</View> | ||
); | ||
}; | ||
} | ||
|
||
function getHelpContent(styles: ThemeStyles, route: string, isProduction: boolean): ReactNode { | ||
const [firstPart, ...routeParts] = route.substring(1).split('/'); | ||
let currentNode: HelpContent = helpContentMap[firstPart]; | ||
let isExactMatch = true; | ||
|
||
for (const part of routeParts) { | ||
if (currentNode?.children?.[part]) { | ||
currentNode = currentNode.children[part]; | ||
isExactMatch = true; | ||
} else { | ||
isExactMatch = false; | ||
break; | ||
} | ||
} | ||
|
||
if (currentNode?.content) { | ||
if (isProduction) { | ||
return <View style={styles.ph5}>{currentNode.content(styles)}</View>; | ||
} | ||
|
||
return ( | ||
<DiagnosticData | ||
styles={styles} | ||
route={route} | ||
isExactMatch={isExactMatch} | ||
> | ||
{currentNode.content(styles)} | ||
</DiagnosticData> | ||
); | ||
} | ||
|
||
return ( | ||
<DiagnosticData | ||
styles={styles} | ||
route={route} | ||
/> | ||
); | ||
} | ||
|
||
export default getHelpContent; |
Oops, something went wrong.