diff --git a/android/app/build.gradle b/android/app/build.gradle index 6d3168382073..e135d44eb834 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001043201 - versionName "1.4.32-1" + versionCode 1001043202 + versionName "1.4.32-2" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 6e62db6dea30..c636ced8e7f9 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.32.1 + 1.4.32.2 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 45e0b42db439..ef1ef0d998d5 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.32.1 + 1.4.32.2 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 2f0ce291dfc7..16439b1d24d9 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleShortVersionString 1.4.32 CFBundleVersion - 1.4.32.1 + 1.4.32.2 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 5a774298babd..543a1366f8d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.32-1", + "version": "1.4.32-2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.32-1", + "version": "1.4.32-2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 055958b9a375..8ceac3912660 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.32-1", + "version": "1.4.32-2", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", diff --git a/src/components/StatePicker/StateSelectorModal.js b/src/components/StatePicker/StateSelectorModal.tsx similarity index 73% rename from src/components/StatePicker/StateSelectorModal.js rename to src/components/StatePicker/StateSelectorModal.tsx index 003211478529..798d3be7a698 100644 --- a/src/components/StatePicker/StateSelectorModal.js +++ b/src/components/StatePicker/StateSelectorModal.tsx @@ -1,7 +1,5 @@ import {CONST as COMMON_CONST} from 'expensify-common/lib/CONST'; -import PropTypes from 'prop-types'; import React, {useEffect, useMemo} from 'react'; -import _ from 'underscore'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import Modal from '@components/Modal'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -9,40 +7,36 @@ import SelectionList from '@components/SelectionList'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import searchCountryOptions from '@libs/searchCountryOptions'; +import type {CountryData} from '@libs/searchCountryOptions'; import StringUtils from '@libs/StringUtils'; import CONST from '@src/CONST'; -const propTypes = { +type State = keyof typeof COMMON_CONST.STATES; + +type StateSelectorModalProps = { /** Whether the modal is visible */ - isVisible: PropTypes.bool.isRequired, + isVisible: boolean; /** State value selected */ - currentState: PropTypes.string, + currentState?: State; /** Function to call when the user selects a State */ - onStateSelected: PropTypes.func, + onStateSelected?: (state: CountryData) => void; /** Function to call when the user closes the State modal */ - onClose: PropTypes.func, + onClose?: () => void; /** The search value from the selection list */ - searchValue: PropTypes.string.isRequired, + searchValue: string; /** Function to call when the user types in the search input */ - setSearchValue: PropTypes.func.isRequired, + setSearchValue: (value: string) => void; /** Label to display on field */ - label: PropTypes.string, -}; - -const defaultProps = { - currentState: '', - onClose: () => {}, - onStateSelected: () => {}, - label: undefined, + label?: string; }; -function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, searchValue, setSearchValue, label}) { +function StateSelectorModal({currentState, isVisible, onClose = () => {}, onStateSelected = () => {}, searchValue, setSearchValue, label}: StateSelectorModalProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -53,11 +47,11 @@ function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, setSearchValue(''); }, [isVisible, setSearchValue]); - const countryStates = useMemo( + const countryStates: CountryData[] = useMemo( () => - _.map(_.keys(COMMON_CONST.STATES), (state) => { - const stateName = translate(`allStates.${state}.stateName`); - const stateISO = translate(`allStates.${state}.stateISO`); + Object.keys(COMMON_CONST.STATES).map((state) => { + const stateName = translate(`allStates.${state as State}.stateName`); + const stateISO = translate(`allStates.${state as State}.stateISO`); return { value: stateISO, keyForList: stateISO, @@ -88,12 +82,16 @@ function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, testID={StateSelectorModal.displayName} > void; /** Label to display on field */ - label: PropTypes.string, + label?: string; /** Callback to call when the picker modal is dismissed */ - onBlur: PropTypes.func, -}; - -const defaultProps = { - value: undefined, - forwardedRef: undefined, - errorText: '', - onInputChange: () => {}, - label: undefined, - onBlur: () => {}, + onBlur?: () => void; }; -function StatePicker({value, errorText, onInputChange, forwardedRef, label, onBlur}) { +function StatePicker({value, onInputChange, label, onBlur, errorText = ''}: StatePickerProps, ref: ForwardedRef) { const styles = useThemeStyles(); const {translate} = useLocalize(); const [isPickerVisible, setIsPickerVisible] = useState(false); @@ -51,29 +39,31 @@ function StatePicker({value, errorText, onInputChange, forwardedRef, label, onBl const hidePickerModal = (shouldBlur = true) => { if (shouldBlur) { - onBlur(); + onBlur?.(); } setIsPickerVisible(false); }; - const updateStateInput = (state) => { + const updateStateInput = (state: CountryData) => { if (state.value !== value) { - onInputChange(state.value); + onInputChange?.(state.value); } // If the user selects any state, call the hidePickerModal function with shouldBlur = false // to prevent the onBlur function from being called. hidePickerModal(false); }; - const title = value && _.keys(COMMON_CONST.STATES).includes(value) ? translate(`allStates.${value}.stateName`) : ''; + const title = value && Object.keys(COMMON_CONST.STATES).includes(value) ? translate(`allStates.${value}.stateName`) : ''; const descStyle = title.length === 0 ? styles.textNormal : null; return ( ( - -)); - -StatePickerWithRef.displayName = 'StatePickerWithRef'; - -export default StatePickerWithRef; +export default React.forwardRef(StatePicker); diff --git a/src/libs/searchCountryOptions.ts b/src/libs/searchCountryOptions.ts index 8fb1cc9c37f3..1fc5d343f556 100644 --- a/src/libs/searchCountryOptions.ts +++ b/src/libs/searchCountryOptions.ts @@ -37,3 +37,4 @@ function searchCountryOptions(searchValue: string, countriesData: CountryData[]) } export default searchCountryOptions; +export type {CountryData};