Skip to content

Commit

Permalink
Merge pull request #334 from etn-ccis/fix/refactor-card
Browse files Browse the repository at this point in the history
Refactor WorkflowCard
  • Loading branch information
manojleaton committed Feb 5, 2024
2 parents ed760e0 + 13e6b03 commit 553176f
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 126 deletions.
4 changes: 2 additions & 2 deletions login-workflow/docs/components/workflow-card.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ import {
| Prop Name | Type | Description | Default |
| --------------- | --------- | ------------------------------------------------------------------------- | ------- |
| loading | `boolean` | A boolean that indicates whether the loading spinner should be displayed. | `false` |
| backgroundImage | `string` | The background image to display behind the card. | |
| backgroundImage | [`ImageSourcePropType`](https://reactnative.dev/docs/image#imagesource) | The background image to display behind the card. | |

The properties of the underlying React Native [View](https://reactnative.dev/docs/view#props) component are also available.
The properties of the underlying React Native [ImageBackground](https://reactnative.dev/docs/imagebackground#props) component are also available.

## WorkflowCardBody

Expand Down
12 changes: 6 additions & 6 deletions login-workflow/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1357,9 +1357,9 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
boost: d211fef46701a9df276bef51f7e86992e22929eb
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
DoubleConversion: b50f832cfe4030d3500ef82f095f609c8c0668f3
FBLazyVector: fbc4957d9aa695250b55d879c1d86f79d7e69ab4
FBReactNativeSpec: 86de768f89901ef6ed3207cd686362189d64ac88
Flipper: c7a0093234c4bdd456e363f2f19b2e4b27652d44
Expand All @@ -1371,11 +1371,11 @@ SPEC CHECKSUMS:
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
FlipperKit: 37525a5d056ef9b93d1578e04bc3ea1de940094f
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
hermes-engine: b361c9ef5ef3cda53f66e195599b47e1f84ffa35
glog: e519f94633ae20b610529d26c963d713c678b0b6
hermes-engine: ef490160118aea4fd2ee0a625a388642c204d901
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
RCT-Folly: e6540a6bc74fdcd89a210fcb7775d50ef41b301b
RCTRequired: 9b1e7e262745fb671e33c51c1078d093bd30e322
RCTTypeSafety: a759e3b086eccf3e2cbf2493d22f28e082f958e6
React: 805f5dd55bbdb92c36b4914c64aaae4c97d358dc
Expand Down Expand Up @@ -1430,4 +1430,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 0102c6fabdf4b18c8262ef30a5501363fc491918

COCOAPODS: 1.12.1
COCOAPODS: 1.14.3
12 changes: 2 additions & 10 deletions login-workflow/example/ios/example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -616,11 +616,7 @@
"-DFOLLY_USE_LIBCPP=1",
"-DFOLLY_CFG_NO_COROUTINES=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
"-Wl",
"-ld_classic",
);
OTHER_LDFLAGS = "$(inherited)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
Expand Down Expand Up @@ -688,11 +684,7 @@
"-DFOLLY_USE_LIBCPP=1",
"-DFOLLY_CFG_NO_COROUTINES=1",
);
OTHER_LDFLAGS = (
"$(inherited)",
"-Wl",
"-ld_classic",
);
OTHER_LDFLAGS = "$(inherited)";
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = true;
Expand Down
34 changes: 4 additions & 30 deletions login-workflow/example/src/screens/WorkFlowCardExample.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,29 @@
import React from 'react';
import { View } from 'react-native';
import { Header } from '@brightlayer-ui/react-native-components';
import { StackNavigationProp } from '@react-navigation/stack';
import { RootStackParamList } from '../navigation';
import { HelperText, Text, TextInput } from 'react-native-paper';
import { HelperText, TextInput } from 'react-native-paper';
import {
WorkflowCard,
WorkflowCardHeader,
WorkflowCardBody,
WorkflowCardInstructions,
WorkflowCardActions,
} from '@brightlayer-ui/react-native-auth-workflow';
import { useThemeContext } from '../context/ThemeContext';
import { useExtendedTheme } from '@brightlayer-ui/react-native-themes';
import { UserMenuExample } from '../components/UserMenuExample';
import { toggleRTL } from './home';

type AppProps = {
navigation: StackNavigationProp<RootStackParamList, 'WorkFlowCardExample'>;
};

const WorkFlowCardExample: React.FC<AppProps> = ({ navigation }): JSX.Element => {
const theme = useExtendedTheme();
const { theme: themeType, setTheme } = useThemeContext();
const [errorFilledText, setErrorFilledText] = React.useState('Hello');
const [hasError, setHasError] = React.useState(true);

return (
<>
<Header
title={'Workflow Card Example'}
icon={{ name: 'menu' }}
onIconPress={(): void => {
navigation.openDrawer();
}}
actionItems={[
{
icon: { name: 'more' },
onPress: (): void => {},
component: (
<UserMenuExample
onToggleRTL={toggleRTL}
onToggleTheme={(): void => setTheme(themeType === 'light' ? 'dark' : 'light')}
/>
),
},
]}
/>
<WorkflowCard>
{/* @todo replace WorkflowCardHeader component once created */}
<View>
<Text>Workflow Card Header</Text>
</View>
<WorkflowCardHeader />
<WorkflowCardInstructions instructions={'Test Instructions'} />
<WorkflowCardBody>
<TextInput
Expand Down Expand Up @@ -78,6 +51,7 @@ const WorkFlowCardExample: React.FC<AppProps> = ({ navigation }): JSX.Element =>
currentStep={2}
totalSteps={7}
fullWidthButton={false}
onPrevious={() => navigation.navigate('Home')}
/>
</WorkflowCard>
</>
Expand Down
121 changes: 66 additions & 55 deletions login-workflow/src/components/WorkflowCard/WorkflowCard.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from 'react';
import { ImageBackground, ImageSourcePropType, View, ViewProps } from 'react-native';
import { Card, CardActionsProps, CardTitleProps } from 'react-native-paper';
import { ImageBackground, ImageBackgroundProps, ImageSourcePropType, StyleSheet } from 'react-native';
import { Card, CardActionsProps, CardProps, CardTitleProps } from 'react-native-paper';
import { WorkflowCardInstructionProps } from './WorkflowCardInstructions';
import { useScreenWidth } from '../../hooks/useScreenWidth';
import { useExtendedTheme } from '@brightlayer-ui/react-native-themes';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { WorkflowCardBody } from './WorkflowCardBody';
import { useScreenDimensions } from '../../hooks/useScreenDimensions';
import { ExtendedTheme, useExtendedTheme } from '@brightlayer-ui/react-native-themes';
import { EdgeInsets, useSafeAreaInsets } from 'react-native-safe-area-context';
import { Spinner } from '../Spinner';
import defaultImage from '../../assets/images/background.png';
import { WorkflowCardHeader } from './WorkflowCardHeader';

const MAX_CARD_HEIGHT = 730;
const MAX_CARD_WIDTH = 450;
/**
* Component that renders the workflow card that is used for all screen components.
*
Expand All @@ -17,7 +19,7 @@ import defaultImage from '../../assets/images/background.png';
*
* @category Component
*/
export type WorkflowCardBaseProps = ViewProps & {
export type WorkflowCardBaseProps = ImageBackgroundProps & {
/**
* If true, a blocking progress spinner will be displayed over the card
*/
Expand All @@ -28,6 +30,31 @@ export type WorkflowCardBaseProps = ViewProps & {
backgroundImage?: ImageSourcePropType;
};

const makeStyles = ({
insets,
theme,
}: {
insets: EdgeInsets;
theme: ExtendedTheme;
}): StyleSheet.NamedStyles<{
mobile: CardProps['style'];
tablet: CardProps['style'];
}> =>
StyleSheet.create({
mobile: {
paddingBottom: insets.bottom,
height: '100%',
width: '100%',
borderRadius: 0,
},
tablet: {
height: MAX_CARD_HEIGHT,
width: MAX_CARD_WIDTH,
borderRadius: theme.roundness * 2,
overflow: 'hidden',
},
});

export type WorkflowCardHeaderProps = CardTitleProps;

export type WorkflowCardActionsProps = CardActionsProps;
Expand All @@ -40,66 +67,50 @@ export type WorkflowCardProps = {
};

function hasWorkflowCardHeaderRecursive(children: any): boolean {
return React.Children.toArray(children).some((child) => {
// @todo replace with WorkflowCardHeader once it's created
if (child.type === WorkflowCardBody) {
return true; // Found it!
} else if (React.isValidElement(child)) {
// Recursively check children of this element
return hasWorkflowCardHeaderRecursive(child.props.children);
}
return false;
});
return React.Children.toArray(children).some((child) => (child as JSX.Element).type === WorkflowCardHeader);
}

export const WorkflowCard: React.FC<WorkflowCardBaseProps> = (props) => {
const { loading, backgroundImage, children, ...otherViewProps } = props;
const { loading, backgroundImage, children, style, ...otherImageProps } = props;
const theme = useExtendedTheme();
const isTablet = useScreenWidth();
const { isTablet, width, height } = useScreenDimensions();

const hasWorkflowCardHeader = hasWorkflowCardHeaderRecursive(children);

const insets = useSafeAreaInsets();
const statusBarHeight = isTablet ? 0 : hasWorkflowCardHeader ? 0 : insets.top;
const styles = makeStyles({ insets, theme });

return (
<View
style={{
height: '100%',
width: '100%',
display: 'flex',
flex: 1,
backgroundColor: theme.colors.background,
}}
{...otherViewProps}
>
<ImageBackground
source={backgroundImage ? backgroundImage : defaultImage}
resizeMode="cover"
style={{
<ImageBackground
source={backgroundImage ? backgroundImage : defaultImage}
resizeMode="repeat"
style={[
{
flex: 1,
height: '100%',
width: '100%',
justifyContent: 'center',
alignItems: 'center',
paddingTop: statusBarHeight,
paddingBottom: isTablet ? insets.bottom : 0,
alignItems: isTablet ? 'center' : 'stretch',
backgroundColor: theme.colors.primary,
},
...(Array.isArray(style) ? style : [style]),
]}
{...otherImageProps}
>
<Card
style={{
maxHeight: height,
maxWidth: width,
}}
contentStyle={[
isTablet ? styles.tablet : styles.mobile,
{
backgroundColor: theme.colors.surface,
paddingTop: !isTablet && !hasWorkflowCardHeader ? insets.top : 0,
},
]}
>
<Card
contentStyle={{
height: '100%',
width: '100%',
display: 'flex',
maxHeight: isTablet ? 730 : 'none',
maxWidth: isTablet ? 450 : 'none',
}}
style={{
borderRadius: isTablet ? 4 : 0,
paddingBottom: isTablet ? 0 : insets.bottom,
}}
>
{loading ? <Spinner visible={loading} /> : children}
</Card>
</ImageBackground>
</View>
{loading ? <Spinner visible={loading} /> : children}
</Card>
</ImageBackground>
);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { ScrollView, StyleSheet, ViewStyle } from 'react-native';
import { Card, CardContentProps } from 'react-native-paper';
import { useScreenWidth } from '../../hooks/useScreenWidth';
import { useScreenDimensions } from '../../hooks/useScreenDimensions';

const makeStyles = (
isTablet: boolean
Expand All @@ -26,7 +26,7 @@ const makeStyles = (
*/
export const WorkflowCardBody: React.FC<CardContentProps> = (props) => {
const { children, style, ...otherCardContentProps } = props;
const isTablet = useScreenWidth();
const { isTablet } = useScreenDimensions();
const defaultStyles = makeStyles(isTablet);

return (
Expand Down
14 changes: 14 additions & 0 deletions login-workflow/src/components/WorkflowCard/WorkflowCardHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useScreenDimensions } from '../../hooks/useScreenDimensions';

/**
* THIS IS A MOCK IMPLEMENTATION FOR TESTING PURPOSES
*/
export const WorkflowCardHeader: React.FC = () => {
const insets = useSafeAreaInsets();
const { isTablet } = useScreenDimensions();

return <View style={{ backgroundColor: 'red', height: isTablet ? 56 : 56 + insets.top }} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { StyleSheet, ViewStyle, View } from 'react-native';
import { Divider, Text, TextProps } from 'react-native-paper';
import { useScreenWidth } from '../../hooks/useScreenWidth';
import { useScreenDimensions } from '../../hooks/useScreenDimensions';

export type WorkflowCardInstructionProps = Omit<TextProps<'bodyLarge'>, 'children' | 'theme' | 'variant'> & {
/**
Expand Down Expand Up @@ -44,7 +44,7 @@ const makeStyles = (

export const WorkflowCardInstructions: React.FC<WorkflowCardInstructionProps> = (props) => {
const { instructions, divider = true, style, ...otherProps } = props;
const isTablet = useScreenWidth();
const { isTablet } = useScreenDimensions();
const styles = makeStyles(isTablet);
return (
<>
Expand Down
1 change: 1 addition & 0 deletions login-workflow/src/components/WorkflowCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './WorkflowCard';
export * from './WorkflowCardBody';
export * from './WorkflowCardInstructions';
export * from './WorkflowCardActions';
export * from './WorkflowCardHeader';
20 changes: 20 additions & 0 deletions login-workflow/src/hooks/useScreenDimensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @packageDocumentation
* @module Hooks
* @internal
*/
import { useWindowDimensions } from 'react-native';

type ScreenWidthProps = {
width: number;
height: number;
isTablet: boolean;
};
export const useScreenDimensions = (): ScreenWidthProps => {
const { height, width } = useWindowDimensions();
return {
isTablet: width >= 768,
width: width,
height: height,
};
};
19 changes: 0 additions & 19 deletions login-workflow/src/hooks/useScreenWidth.ts

This file was deleted.

0 comments on commit 553176f

Please sign in to comment.