Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS migration] Migrate 'ExpensifyWordmark.js' component to TypeScript #31478

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import {StyleProp, View, ViewStyle} from 'react-native';
import AdHocLogo from '@assets/images/expensify-logo--adhoc.svg';
import DevLogo from '@assets/images/expensify-logo--dev.svg';
import StagingLogo from '@assets/images/expensify-logo--staging.svg';
Expand All @@ -12,40 +10,36 @@ import useTheme from '@styles/themes/useTheme';
import useThemeStyles from '@styles/useThemeStyles';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions';
import withWindowDimensions from './withWindowDimensions';
import type {WindowDimensionsProps} from './withWindowDimensions/types';

const propTypes = {
type ExpensifyWordmarkProps = WindowDimensionsProps & {
/** Additional styles to add to the component */
style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]),

...windowDimensionsPropTypes,
};

const defaultProps = {
style: {},
style?: StyleProp<ViewStyle>;
};

const logoComponents = {
[CONST.ENVIRONMENT.DEV]: DevLogo,
[CONST.ENVIRONMENT.STAGING]: StagingLogo,
[CONST.ENVIRONMENT.PRODUCTION]: ProductionLogo,
[CONST.ENVIRONMENT.ADHOC]: AdHocLogo,
};
Julesssss marked this conversation as resolved.
Show resolved Hide resolved

function ExpensifyWordmark(props) {
function ExpensifyWordmark({isSmallScreenWidth, style}: ExpensifyWordmarkProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {environment} = useEnvironment();
// PascalCase is required for React components, so capitalize the const here
const LogoComponent = environment ? logoComponents[environment] : AdHocLogo;

Julesssss marked this conversation as resolved.
Show resolved Hide resolved
const LogoComponent = logoComponents[environment] || AdHocLogo;
return (
<>
<View
style={[
StyleUtils.getSignInWordmarkWidthStyle(environment, props.isSmallScreenWidth),
StyleUtils.getHeight(props.isSmallScreenWidth ? variables.signInLogoHeightSmallScreen : variables.signInLogoHeight),
props.isSmallScreenWidth && (environment === CONST.ENVIRONMENT.DEV || environment === CONST.ENVIRONMENT.STAGING) ? styles.ml3 : {},
...(_.isArray(props.style) ? props.style : [props.style]),
StyleUtils.getSignInWordmarkWidthStyle(environment, isSmallScreenWidth),
StyleUtils.getHeight(isSmallScreenWidth ? variables.signInLogoHeightSmallScreen : variables.signInLogoHeight),
isSmallScreenWidth && (environment === CONST.ENVIRONMENT.DEV || environment === CONST.ENVIRONMENT.STAGING) ? styles.ml3 : {},
style,
]}
>
<LogoComponent fill={theme.success} />
Expand All @@ -55,6 +49,5 @@ function ExpensifyWordmark(props) {
}

ExpensifyWordmark.displayName = 'ExpensifyWordmark';
ExpensifyWordmark.defaultProps = defaultProps;
ExpensifyWordmark.propTypes = propTypes;

export default withWindowDimensions(ExpensifyWordmark);
2 changes: 1 addition & 1 deletion src/styles/StyleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ function getBorderColorStyle(borderColor: string): ViewStyle {
/**
* Returns the width style for the wordmark logo on the sign in page
*/
function getSignInWordmarkWidthStyle(environment: string, isSmallScreenWidth: boolean): ViewStyle {
function getSignInWordmarkWidthStyle(environment: ValueOf<typeof CONST.ENVIRONMENT> | undefined, isSmallScreenWidth: boolean): ViewStyle {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a shorthand way to set the param type here? Asking as I'm new to Typescript but familiar with Kotlin/Swift.

Also, is making this optional really necessary? It looks like the only usage of this function will reliably return an Environment... or is this due to a potential issue with EnvironmentContext? Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Julesssss We can switch environment and isSmallScreenWidth params places and then mark environment param as optional this way:

function getSignInWordmarkWidthStyle(isSmallScreenWidth: boolean, environment?: ValueOf<typeof CONST.ENVIRONMENT>): ViewStyle {

Yeah, since EnvironmentContext can be null, it's better to keep it optional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay thanks.

I'm not too bothered about the param ordering, but environment?: seems a bit cleaner to me. But if this goes against typical formatting rules please ignore me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Julesssss Updated 🙂

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabioh8010 @Julesssss @VickyStash Shouldn't environment be required? I think we should throw an exception instead of returning an empty object in useEnvironment because EnrivonmentProvider is passed in root app. So that will allow us to remove possible null from getSignInWordmarkWidthStyle. I think there is no case when the environment is null.
What do you think about this approach?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ArekChr yeah if it is possible to enforce a non-optional environment, that sounds good to me. Happy to review a PR if you could raise one

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ArekChr @fabioh8010
I think we can also try to use these default values for the EnvironmentContext instead of null.

const EnvironmentContext = createContext<EnvironmentContextValue>({
    environment: CONST.ENVIRONMENT.PRODUCTION,
    environmentURL: CONST.NEW_EXPENSIFY_URL,
});

It should be ok since these values are also used as default state values here and this way the environment will be non-optional value.

if (environment === CONST.ENVIRONMENT.DEV) {
return isSmallScreenWidth ? {width: variables.signInLogoWidthPill} : {width: variables.signInLogoWidthLargeScreenPill};
}
Expand Down
Loading