Skip to content
Open
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
46 changes: 46 additions & 0 deletions app/components/custom-modal/CustomModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { type FC, type ReactElement } from 'react';
import { StyleSheet, View } from 'react-native';
import Modal, { type ModalProps } from 'react-native-modal';
import { useTheme } from '../../hooks';
import { screenHeight } from '../../theme';
import styleSheet from './CustomModalStyles';
import type { CustomModalPropsType } from './CustomModalTypes';

/**
* The custom modal component.
* @param {CustomModalPropsType} props - the props for the custom modal component.
* @param {StyleProp<ViewStyle>} [props.modalStyle] - Optional styles for the modal.
* @param {StyleProp<ViewStyle>} [props.contentContainerStyle] - Optional styles for the content container.
* @param {() => void} [props.onBackdropPress] - Optional callback function invoked when the backdrop is pressed.
* @param {boolean} props.isVisible - Whether the modal is visible or not.
* @returns {React.ReactElement} A React Element.
*/
const CustomModal: FC<CustomModalPropsType & Partial<ModalProps>> = ({
modalStyle,
contentContainerStyle,
onBackdropPress = () => {},
isVisible,
children,
...rest
}): ReactElement => {
const { styles } = useTheme(styleSheet);

return (
<Modal
useNativeDriverForBackdrop
avoidKeyboard
statusBarTranslucent
isVisible={isVisible}
deviceHeight={screenHeight}
style={StyleSheet.flatten([styles.modalStyle, modalStyle])}
Comment on lines +33 to +35
onBackdropPress={onBackdropPress}
{...rest}
Comment on lines +35 to +37
>
<View style={StyleSheet.flatten([styles.contentContainerStyle, contentContainerStyle])}>
{children}
</View>
</Modal>
);
};

export default CustomModal;
22 changes: 22 additions & 0 deletions app/components/custom-modal/CustomModalStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { StyleSheet } from 'react-native';
import { ApplicationStyles, Colors, scale, type ThemeMode } from '../../theme';

/**
* Create a custom style sheet for the given theme.
* @param {StyleSheetOption} theme - The theme mode to use for generating the style sheet.
* @returns A custom style sheet that can be injected into the component.
*/
const styles = (theme: ThemeMode) =>
StyleSheet.create({
...ApplicationStyles(theme),
contentContainerStyle: {
backgroundColor: Colors[theme]?.white,
borderRadius: scale(16),
padding: scale(16)
},
modalStyle: {
justifyContent: 'center'
}
});

export default styles;
10 changes: 10 additions & 0 deletions app/components/custom-modal/CustomModalTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { StyleProp, ViewStyle } from 'react-native';
import type { ReactNode } from 'react';

export interface CustomModalPropsType {
modalStyle?: StyleProp<ViewStyle>;
contentContainerStyle?: StyleProp<ViewStyle>;
onBackdropPress?: () => void;
isVisible: boolean;
children: ReactNode;
}
1 change: 1 addition & 0 deletions app/components/custom-modal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as CustomModal } from './CustomModal';
1 change: 1 addition & 0 deletions app/modules/task-listing/TaskListingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useTaskListing } from './useTaskListing';
* TaskListingScreen component displays a list of tasks.
* Uses FlatList for optimal performance and TaskItem component for rendering individual tasks.
* @param {TaskListingProps} props - The props for the TaskListing component.
* @param {(task: Task) => void} [props.onTaskPress] - Optional callback function invoked when a task is pressed.
* @returns {React.ReactElement} A React element displaying the task list.
*/
const TaskListingScreen: FC<TaskListingProps> = ({ onTaskPress }): React.ReactElement => {
Expand Down
18 changes: 17 additions & 1 deletion app/theme/Metrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,25 @@ const getDimensions = (): DimensionsType => {
return { width, height };
};

/**
* Get the width and height of the device screen including the status bar and navigation bar.
* @returns {DimensionsType} - the width and height of the device screen.
*/
const getScreenDimensions = (): DimensionsType => {
let { width, height }: ScaledSize = Dimensions.get('screen');

if (width > height) {
[width, height] = [height, width];
}
return { width, height };
};

// Get dimensions
const { width, height }: DimensionsType = getDimensions();

// Get screen dimensions including status bar and navigation bar
const { width: screenWidth, height: screenHeight }: DimensionsType = getScreenDimensions();

//Guideline sizes are based on standard ~5" screen mobile device
const guidelineBaseWidth: number = 375;

Expand Down Expand Up @@ -79,4 +95,4 @@ const globalMetrics: GlobalMetricsType = {
isWeb: Platform.OS === 'web'
};

export { globalMetrics, scale, width, height };
export { globalMetrics, scale, width, height, screenWidth, screenHeight };
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@
}
},
"dependencies": {
"@react-native/codegen": "0.81.1",
"@react-navigation/core": "6.4.17",
"@react-navigation/native": "6.1.18",
"@react-navigation/native-stack": "6.11.0",
"@react-navigation/routers": "6.1.9",
"@react-native/codegen": "0.81.1",
"@reduxjs/toolkit": "2.5.0",
"@sentry/react-native": "6.20.0",
"apisauce": "3.2.0",
"axios": "1.10.0",
"@sentry/react-native": "6.20.0",
"formik": "2.4.6",
"i18next": "23.12.2",
"lodash": "4.17.21",
Expand All @@ -51,6 +51,7 @@
"react-native-gesture-handler": "2.28.0",
"react-native-localize": "3.5.2",
"react-native-mmkv": "3.3.3",
"react-native-modal": "^14.0.0-rc.1",
"react-native-permissions": "4.1.5",
"react-native-safe-area-context": "5.6.1",
"react-native-screens": "4.14.0",
Expand All @@ -70,22 +71,22 @@
"@react-native/metro-config": "0.81.4",
"@react-native/typescript-config": "0.81.4",
"@react-navigation/devtools": "6.0.27",
"@types/lodash": "4.17.7",
"@types/jest": "29.5.13",
"@types/lodash": "4.17.7",
"@types/react": "19.1.0",
"@types/react-native": "0.73.0",
"@types/react-test-renderer": "19.1.0",
"@typescript-eslint/eslint-plugin": "8.0.1",
"@typescript-eslint/parser": "8.0.1",
"babel-jest": "29.7.0",
"cspell": "8.13.1",
"babel-plugin-transform-remove-console": "6.9.4",
"cspell": "8.13.1",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-import-resolver-typescript": "3.6.3",
"eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jest": "28.8.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-prettier": "5.2.1",
"eslint-plugin-react-native": "4.1.0",
"husky": "8.0.3",
Expand All @@ -110,4 +111,4 @@
"engines": {
"node": ">=20"
}
}
}