Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
cd65e37
refactor: rename StyleUtils safe area padding function
chrispader Jan 22, 2025
a4e915c
refactor: simplify code in `useStyledSafeAreaInsets` hook
chrispader Jan 22, 2025
0fbfb27
feat: implement android navigation bar type specific bottom safe area…
chrispader Jan 22, 2025
124cc53
fix: add source url
chrispader Jan 22, 2025
e602c2f
fix: use CONST values and add comments
chrispader Jan 22, 2025
490e560
update comment about navigation bar height threshold
chrispader Jan 22, 2025
e17118e
fix: revert navigation bar changes in `getPlatformSafeAreaPadding`
chrispader Feb 17, 2025
9c23b7c
feat: disable bottom safe area padding handling completely
chrispader Feb 17, 2025
cdccefa
fix: syntax and eslint error in ScreenWrapper
chrispader Feb 19, 2025
1bbb3b7
fix: safe area padding in CategorySelectorModal (SelectionList flag)
chrispader Feb 19, 2025
ffcf463
fix: missing parantheses -> wrong bottom safe area padding
chrispader Feb 19, 2025
f27e1b0
feat: simplify `useStyledSafeAreaInsets` hook
chrispader Feb 19, 2025
26f9d5c
feat: add BaseModal flag for disabling bottom safe area spacing
chrispader Feb 19, 2025
0999a97
fix: unmodifiedPaddings was removed
chrispader Feb 20, 2025
042a464
rename temporary flag for bottom safe area handling
chrispader Feb 20, 2025
5aa0b04
feat: implement `NavBarManager.setBackgroundColor` for Android transl…
chrispader Feb 20, 2025
06c73c6
fix: implement NavigationBar component and use instead of native NavB…
chrispader Feb 21, 2025
56e4fdc
fix: ScreenWrapper context properties
chrispader Feb 21, 2025
161e66b
revert changes in AuthScreens
chrispader Feb 21, 2025
18958b2
feat: add flag to ScreenWrapper
chrispader Feb 21, 2025
2c420fa
Update AuthScreens.tsx
chrispader Feb 21, 2025
4f8c568
fix: update comments of flags
chrispader Feb 21, 2025
3789062
feat: implement `addBottomSafeAreaPaddingToContent`
chrispader Feb 21, 2025
fbb4e37
feat: extract contentContainerStyle logic with safe area padding and …
chrispader Feb 21, 2025
4cf3a7c
fix: ESLint and TS errors
chrispader Feb 21, 2025
b4e830b
fix: contentContainerStyleProp might be nullish
chrispader Feb 22, 2025
6f7657b
feat: implement `shouldCompensateForBottomSafeAreaPadding` flag to `K…
chrispader Feb 22, 2025
b584804
fix: always use edge-to-edge insets/paddings in `useContentContainerS…
chrispader Feb 22, 2025
00f694f
feat: allow submit button to stick to the bottom of the screen in Forms
chrispader Feb 22, 2025
9775d09
feat: add flag in `ScreenWrapper` to enable `KeyboardAvoidingView` bo…
chrispader Feb 22, 2025
b617141
fix: add FormElement styles to sticky submit button
chrispader Feb 22, 2025
355eec3
fix: rename prop
chrispader Feb 22, 2025
39d5ea4
fix: rename SelectionListProps type
chrispader Feb 22, 2025
b05db03
feat: implement bottom safe area handling in `FixedFooter` component
chrispader Feb 22, 2025
2fc3edf
refactor: rename prop
chrispader Feb 22, 2025
37ca0ae
feat: add flag for bottom sticky footer content
chrispader Feb 22, 2025
a7a91d2
fix: component names and spacing in KeyboardAvoidingView
chrispader Feb 22, 2025
1e9c8e1
feat: add `shouldBlendOpacity` prop to `Button`
chrispader Feb 22, 2025
e72b319
fix: eslint errors
chrispader Feb 22, 2025
a0433b3
fix: comment
chrispader Feb 22, 2025
788c8a4
feat: implement native function to detect soft-keys vs. gesture-bar o…
chrispader Feb 23, 2025
15e38aa
refactor: rename hook
chrispader Feb 23, 2025
2e72d04
feat: add default padding bottom for confirm button in SelectionList
chrispader Feb 23, 2025
5b53463
fix: blend button automatically, when default footer content is used
chrispader Feb 23, 2025
ffc43a7
feat: add bottom safe area handling to BlockingViews
chrispader Feb 23, 2025
a9ef544
feat: pass addBottomSafeAreaPadding prop in EmptyStateComponent
chrispader Feb 23, 2025
7484d61
fix: improve logic in useBottomSafeSafeAreaPaddingStyle
chrispader Feb 23, 2025
0a5573f
fix: don't apply bottom safe area twice in SelectionList
chrispader Feb 23, 2025
c9b15c8
Update useBottomSafeSafeAreaPaddingStyle.ts
chrispader Feb 23, 2025
ac4dca5
rename param
chrispader Feb 23, 2025
e9cc422
fix: automatically blend opacity of footerContent in SelectionList
chrispader Feb 24, 2025
8ec614e
fix: missing type declaration
chrispader Feb 24, 2025
c1d0964
fix: only apply bottom safe area padding when footer content sticky o…
chrispader Feb 25, 2025
415656e
fix: improve offline indicator bottom safe area handling
chrispader Feb 25, 2025
22e490e
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Feb 25, 2025
f60d658
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Feb 25, 2025
574e9bd
refactor: simplify bottom content style in ScreenWrapper
chrispader Feb 25, 2025
82d954c
fix: offline indicator simplification
chrispader Feb 25, 2025
8786045
fix: rename variable
chrispader Feb 26, 2025
42d5b74
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Feb 26, 2025
0719cdb
fix: Button dependency array
chrispader Feb 26, 2025
98ff98b
fix: make ScreenWrapper use KeyboardAvoidingView offset by default
chrispader Feb 26, 2025
f69747a
refactor: rename `useStyledSafeAreaInsets` hook and update comments/docs
chrispader Feb 26, 2025
33423bd
fix: eslint errors
chrispader Feb 26, 2025
4404a99
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Feb 26, 2025
044c1de
fix: more es lint errors
chrispader Feb 26, 2025
b73aa0b
fix: wrong hook import
chrispader Feb 26, 2025
12531a9
fix: prettier
chrispader Feb 26, 2025
e796192
Update BlockingView.tsx
chrispader Mar 3, 2025
3f38b59
Update FullPageNotFoundView.tsx
chrispader Mar 3, 2025
27eccb1
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Mar 3, 2025
42cc412
fix: address issues regarding prop JSDoc and additional comments
chrispader Mar 3, 2025
0a678d0
Update src/components/SectionList/BaseSectionList.tsx
chrispader Mar 3, 2025
de9fac7
Update src/components/KeyboardAvoidingView/BaseKeyboardAvoidingView/i…
chrispader Mar 3, 2025
2b10eb5
fix: address more issues
chrispader Mar 3, 2025
2c44891
fix: improve styling code in Button component
chrispader Mar 3, 2025
714997c
fix: remove `shouldFooterContentStickToBottom ` prop from SelectionList
chrispader Mar 4, 2025
14fbe29
chore(deps): update `react-native-keyboard-controller`
chrispader Mar 5, 2025
edd6745
Revert "chore(deps): update `react-native-keyboard-controller`"
chrispader Mar 6, 2025
a2fccdd
Merge branch 'main' into pr/57128
chrispader Mar 6, 2025
7a9be91
fix: remove trailing semicolon in Kotlin file
chrispader Mar 6, 2025
22fbc11
fix: extract style util function type and fix import
chrispader Mar 6, 2025
51acd01
Merge branch 'main' into pr/57281
chrispader Mar 6, 2025
d23c715
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Mar 6, 2025
7d27607
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Mar 12, 2025
f525144
fix: old artifact after merge
chrispader Mar 12, 2025
61a15da
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Mar 12, 2025
a804499
fix: prettier
chrispader Mar 12, 2025
ebff006
fix: more prettier
chrispader Mar 12, 2025
afe075a
Merge branch 'main' into @chrispader/add-flags-for-disabling-bottom-s…
chrispader Mar 14, 2025
a6644d7
fix: side pane imports
chrispader Mar 14, 2025
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,10 +1,12 @@
package com.expensify.chat.navbar

import android.content.res.Resources
import androidx.core.view.WindowInsetsControllerCompat
import com.expensify.chat.R
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.UiThreadUtil

class NavBarManagerModule(
private val mReactContext: ReactApplicationContext,
Expand All @@ -24,4 +26,18 @@ class NavBarManagerModule(
}
}
}

@ReactMethod

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No need to make these changes to the Mobile-Expensify?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

checking on it!

fun getType(): String {
val resources = mReactContext.resources
val resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android");
if (resourceId > 0) {
val navBarInteractionMode = resources.getInteger(resourceId)
when (navBarInteractionMode) {
0, 1 -> return "soft-keys"
2 -> return "gesture-bar"
}
}
return "soft-keys";
}
}
8 changes: 4 additions & 4 deletions contributingGuides/FORMS.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Browsers use the name prop to autofill information into the input. Here's a [ref

```jsx
<InputWrapper
InputComponent={TextInput}
InputComponent={TextInput}
name="fname"
/>
```
Expand Down Expand Up @@ -118,7 +118,7 @@ Once a user has “touched” an input, i.e. blurred the input, we will also sta

All form fields will additionally be validated when the form is submitted. Although we are validating on blur this additional step is necessary to cover edge cases where forms are auto-filled or when a form is submitted by pressing enter (i.e. there will be only a ‘submit’ event and no ‘blur’ event to hook into).

The Form component takes care of validation internally and the only requirement is that we pass a validate callback prop. The validate callback takes in the input values as argument and should return an object with shape `{[inputID]: errorMessage}`.
The Form component takes care of validation internally and the only requirement is that we pass a validate callback prop. The validate callback takes in the input values as argument and should return an object with shape `{[inputID]: errorMessage}`.

Here's an example for a form that has two inputs, `routingNumber` and `accountNumber`:

Expand Down Expand Up @@ -332,10 +332,10 @@ An example of this can be seen in the [ACHContractStep](https://github.com/Expen
### Safe Area Padding

Any `FormProvider.tsx` that has a button at the bottom. If the `<FormProvider>` is inside a `<ScreenWrapper>`, the bottom safe area inset is handled automatically (`includeSafeAreaPaddingBottom` needs to be set to `true`, but its the default).
If you have custom requirements and can't use `<ScreenWrapper includeSafeAreaPaddingBottom={true}>`, you can use the `useStyledSafeAreaInsets()` hook:
If you have custom requirements and can't use `<ScreenWrapper includeSafeAreaPaddingBottom={true}>`, you can use the `useSafeAreaPaddings()` hook:

```jsx
const { paddingTop, paddingBottom, safeAreaPaddingBottomStyle } = useStyledSafeAreaInsets();
const { paddingTop, paddingBottom, safeAreaPaddingBottomStyle } = useSafeAreaPaddings();

<View styles={[safeAreaPaddingBottomStyle, styles.pb5]}>
<FormProvider>
Expand Down
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import InitialURLContextProvider from './components/InitialURLContextProvider';
import {InputBlurContextProvider} from './components/InputBlurContext';
import KeyboardProvider from './components/KeyboardProvider';
import {LocaleContextProvider} from './components/LocaleContextProvider';
import NavigationBar from './components/NavigationBar';
import OnyxProvider from './components/OnyxProvider';
import PopoverContextProvider from './components/PopoverProvider';
import {ProductTrainingContextProvider} from './components/ProductTrainingContext';
Expand Down Expand Up @@ -118,6 +119,7 @@ function App({url, hybridAppSettings, timestamp}: AppProps) {
<Expensify />
</ColorSchemeWrapper>
</ErrorBoundary>
<NavigationBar />
</ComposeProviders>
</GestureHandlerRootView>
</InitialURLContextProvider>
Expand Down
14 changes: 14 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,20 @@ const CONST = {
LIGHT: 'light',
DARK: 'dark',
},
NAVIGATION_BAR_TYPE: {
// We consider there to be no navigation bar in one of these cases:
// 1. The device has physical navigation buttons
// 2. The device uses gesture navigation without a gesture bar.
// 3. The device uses hidden (auto-hiding) soft keys.
NONE: 'none',
SOFT_KEYS: 'soft-keys',
GESTURE_BAR: 'gesture-bar',
},
// Currently, in Android there is no native API to detect the type of navigation bar (soft keys vs. gesture).
// The navigation bar on (standard) Android devices is around 30-50dpi tall. (Samsung: 40dpi, Huawei: ~34dpi)
// To leave room to detect soft-key navigation bars on non-standard Android devices,
// we set this height threshold to 30dpi, since gesture bars will never be taller than that. (Samsung & Huawei: ~14-15dpi)
NAVIGATION_BAR_ANDROID_SOFT_KEYS_MINIMUM_HEIGHT_THRESHOLD: 30,
TRANSACTION: {
DEFAULT_MERCHANT: 'Expense',
UNKNOWN_MERCHANT: 'Unknown Merchant',
Expand Down
4 changes: 2 additions & 2 deletions src/components/Attachments/AttachmentView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Text from '@components/Text';
import {usePlaybackContext} from '@components/VideoPlayerContexts/PlaybackContext';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useStyledSafeAreaInsets from '@hooks/useStyledSafeAreaInsets';
import useSafeAreaPaddings from '@hooks/useSafeAreaPaddings';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down Expand Up @@ -116,7 +116,7 @@ function AttachmentView({
const {updateCurrentlyPlayingURL} = usePlaybackContext();

const theme = useTheme();
const {safeAreaPaddingBottomStyle} = useStyledSafeAreaInsets();
const {safeAreaPaddingBottomStyle} = useSafeAreaPaddings();
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const [loadComplete, setLoadComplete] = useState(false);
Expand Down
2 changes: 1 addition & 1 deletion src/components/AutoCompleteSuggestions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function AutoCompleteSuggestions<TSuggestion>({measureParentContainerAndReportCu
const StyleUtils = useStyleUtils();
const insets = useSafeAreaInsets();
const {keyboardHeight, isKeyboardAnimatingRef} = useKeyboardState();
const {paddingBottom: bottomInset, paddingTop: topInset} = StyleUtils.getSafeAreaPadding(insets ?? undefined);
const {paddingBottom: bottomInset, paddingTop: topInset} = StyleUtils.getPlatformSafeAreaPadding(insets ?? undefined);

useEffect(() => {
const container = containerRef.current;
Expand Down
9 changes: 8 additions & 1 deletion src/components/BlockingViews/BlockingView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Lottie from '@components/Lottie';
import type DotLottieAnimation from '@components/LottieAnimations/types';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useBottomSafeSafeAreaPaddingStyle from '@hooks/useBottomSafeSafeAreaPaddingStyle';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
Expand Down Expand Up @@ -47,6 +48,9 @@ type BaseBlockingViewProps = {

/** Additional styles to apply to the container */
containerStyle?: StyleProp<ViewStyle>;

/** Whether to add bottom safe area padding to the view. */
addBottomSafeAreaPadding?: boolean;
};

type BlockingViewIconProps = {
Expand Down Expand Up @@ -94,7 +98,8 @@ function BlockingView({
animationWebStyle = {},
CustomSubtitle,
contentFitImage,
containerStyle,
containerStyle: containerStyleProp,
addBottomSafeAreaPadding = false,
}: BlockingViewProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
Expand Down Expand Up @@ -132,6 +137,8 @@ function BlockingView({
);
}, [styles, subtitleText, shouldEmbedLinkWithSubtitle, CustomSubtitle]);

const containerStyle = useBottomSafeSafeAreaPaddingStyle({addBottomSafeAreaPadding, style: containerStyleProp});

return (
<View style={[styles.flex1, styles.alignItemsCenter, styles.justifyContentCenter, styles.ph10, containerStyle]}>
{!!animation && (
Expand Down
5 changes: 5 additions & 0 deletions src/components/BlockingViews/FullPageNotFoundView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ type FullPageNotFoundViewProps = {

/** Whether we should display the button that opens new SearchRouter */
shouldDisplaySearchRouter?: boolean;

/** Whether to add bottom safe area padding to the view. */
addBottomSafeAreaPadding?: boolean;
};

// eslint-disable-next-line rulesdir/no-negated-variables
Expand All @@ -67,6 +70,7 @@ function FullPageNotFoundView({
shouldForceFullScreen = false,
subtitleStyle,
shouldDisplaySearchRouter,
addBottomSafeAreaPadding = true,
}: FullPageNotFoundViewProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
Expand All @@ -93,6 +97,7 @@ function FullPageNotFoundView({
shouldShowLink={shouldShowLink}
onLinkPress={onLinkPress}
subtitleStyle={subtitleStyle}
addBottomSafeAreaPadding={addBottomSafeAreaPadding}
/>
</View>
</ForceFullScreenView>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import useTheme from '@hooks/useTheme';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import BlockingView from './BlockingView';

function FullPageOfflineBlockingView({children}: ChildrenProps) {
type FullPageOfflineBlockingViewProps = ChildrenProps & {
/** Whether to add bottom safe area padding to the view. */
addBottomSafeAreaPadding?: boolean;
};

function FullPageOfflineBlockingView({children, addBottomSafeAreaPadding = true}: FullPageOfflineBlockingViewProps) {
const {translate} = useLocalize();
const {isOffline} = useNetwork();

Expand All @@ -19,6 +24,7 @@ function FullPageOfflineBlockingView({children}: ChildrenProps) {
iconColor={theme.offline}
title={translate('common.youAppearToBeOffline')}
subtitle={translate('common.thisFeatureRequiresInternet')}
addBottomSafeAreaPadding={addBottomSafeAreaPadding}
/>
);
}
Expand Down
76 changes: 62 additions & 14 deletions src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {useIsFocused} from '@react-navigation/native';
import type {ForwardedRef} from 'react';
import React, {useCallback, useMemo, useState} from 'react';
import type {GestureResponderEvent, LayoutChangeEvent, StyleProp, TextStyle, ViewStyle} from 'react-native';
import {ActivityIndicator, View} from 'react-native';
import {ActivityIndicator, StyleSheet, View} from 'react-native';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
Expand Down Expand Up @@ -152,6 +152,12 @@ type ButtonProps = Partial<ChildrenProps> & {

/** The text displays under the first line */
secondLineText?: string;

/**
* Whether the button should have a background layer in the color of theme.appBG.
* This is needed for buttons that allow content to display under them.
*/
shouldBlendOpacity?: boolean;
};

type KeyboardShortcutComponentProps = Pick<ButtonProps, 'isDisabled' | 'isLoading' | 'onPress' | 'pressOnEnter' | 'allowBubble' | 'enterKeyEventListenerPriority' | 'isPressOnEnterActive'>;
Expand Down Expand Up @@ -255,6 +261,7 @@ function Button(
isPressOnEnterActive,
isNested = false,
secondLineText = '',
shouldBlendOpacity = false,
...rest
}: ButtonProps,
ref: ForwardedRef<View>,
Expand Down Expand Up @@ -356,6 +363,57 @@ function Button(
return textComponent;
};

const buttonStyles = useMemo<StyleProp<ViewStyle>>(
() => [
styles.button,
StyleUtils.getButtonStyleWithIcon(styles, small, medium, large, !!icon, !!(text?.length > 0), shouldShowRightIcon),
success ? styles.buttonSuccess : undefined,
danger ? styles.buttonDanger : undefined,
isDisabled ? styles.buttonOpacityDisabled : undefined,
isDisabled && !danger && !success ? styles.buttonDisabled : undefined,
shouldRemoveRightBorderRadius ? styles.noRightBorderRadius : undefined,
shouldRemoveLeftBorderRadius ? styles.noLeftBorderRadius : undefined,
text && shouldShowRightIcon ? styles.alignItemsStretch : undefined,
innerStyles,
link && styles.bgTransparent,
],
[
StyleUtils,
danger,
icon,
innerStyles,
isDisabled,
large,
link,
medium,
shouldRemoveLeftBorderRadius,
shouldRemoveRightBorderRadius,
shouldShowRightIcon,
small,
styles,
success,
text,
],
);

const buttonContainerStyles = useMemo<StyleProp<ViewStyle>>(
() => [buttonStyles, shouldBlendOpacity && styles.buttonBlendContainer],
[buttonStyles, shouldBlendOpacity, styles.buttonBlendContainer],
);

const buttonBlendForegroundStyle = useMemo<StyleProp<ViewStyle>>(() => {
if (!shouldBlendOpacity) {
return undefined;
}

const {backgroundColor, opacity} = StyleSheet.flatten(buttonStyles);

return {
backgroundColor,
opacity,
};
}, [buttonStyles, shouldBlendOpacity]);

return (
<>
{pressOnEnter && (
Expand Down Expand Up @@ -402,6 +460,7 @@ function Button(
onPressIn={onPressIn}
onPressOut={onPressOut}
onMouseDown={onMouseDown}
shouldBlendOpacity={shouldBlendOpacity}
disabled={isLoading || isDisabled}
wrapperStyle={[
isDisabled ? {...styles.cursorDisabled, ...styles.noSelect} : {},
Expand All @@ -410,19 +469,7 @@ function Button(
shouldRemoveLeftBorderRadius ? styles.noLeftBorderRadius : undefined,
style,
]}
style={[
styles.button,
StyleUtils.getButtonStyleWithIcon(styles, small, medium, large, !!icon, !!(text?.length > 0), shouldShowRightIcon),
success ? styles.buttonSuccess : undefined,
danger ? styles.buttonDanger : undefined,
isDisabled ? styles.buttonOpacityDisabled : undefined,
isDisabled && !danger && !success ? styles.buttonDisabled : undefined,
shouldRemoveRightBorderRadius ? styles.noRightBorderRadius : undefined,
shouldRemoveLeftBorderRadius ? styles.noLeftBorderRadius : undefined,
text && shouldShowRightIcon ? styles.alignItemsStretch : undefined,
innerStyles,
link && styles.bgTransparent,
]}
style={buttonContainerStyles}
isNested={isNested}
hoverStyle={[
shouldUseDefaultHover && !isDisabled ? styles.buttonDefaultHovered : undefined,
Expand All @@ -439,6 +486,7 @@ function Button(
onHoverIn={() => setIsHovered(true)}
onHoverOut={() => setIsHovered(false)}
>
{shouldBlendOpacity && <View style={[StyleSheet.absoluteFill, buttonBlendForegroundStyle]} />}
{renderContent()}
{isLoading && (
<ActivityIndicator
Expand Down
3 changes: 3 additions & 0 deletions src/components/CurrencySelectionList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function CurrencySelectionList({
canSelectMultiple = false,
recentlyUsedCurrencies,
excludedCurrencies = [],
...restProps
}: CurrencySelectionListProps) {
const [currencyList] = useOnyx(ONYXKEYS.CURRENCY_LIST);
const [searchValue, setSearchValue] = useState('');
Expand Down Expand Up @@ -91,6 +92,8 @@ function CurrencySelectionList({

return (
<SelectionList
// eslint-disable-next-line react/jsx-props-no-spreading
{...restProps}
sections={sections}
ListItem={canSelectMultiple ? SelectableListItem : RadioListItem}
textInputLabel={searchInputLabel}
Expand Down
4 changes: 2 additions & 2 deletions src/components/CurrencySelectionList/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type {ListItem} from '@components/SelectionList/types';
import type {ListItem, SelectionListProps} from '@components/SelectionList/types';

type CurrencyListItem = ListItem & {
currencyName: string;
currencyCode: string;
};

type CurrencySelectionListProps = {
type CurrencySelectionListProps = Partial<SelectionListProps<CurrencyListItem>> & {
/** Label for the search text input */
searchInputLabel: string;

Expand Down
2 changes: 2 additions & 0 deletions src/components/EmptyStateComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function EmptyStateComponent({
lottieWebViewStyles,
showsVerticalScrollIndicator,
minModalHeight = 400,
addBottomSafeAreaPadding = false,
}: EmptyStateComponentProps) {
const styles = useThemeStyles();
const [videoAspectRatio, setVideoAspectRatio] = useState(VIDEO_ASPECT_RATIO);
Expand Down Expand Up @@ -88,6 +89,7 @@ function EmptyStateComponent({
showsVerticalScrollIndicator={showsVerticalScrollIndicator}
contentContainerStyle={[{minHeight: minModalHeight}, styles.flexGrow1, styles.flexShrink0, containerStyles]}
style={styles.flex1}
addBottomSafeAreaPadding={addBottomSafeAreaPadding}
>
<View style={[styles.skeletonBackground, styles.overflowHidden]}>
<SkeletonComponent
Expand Down
3 changes: 3 additions & 0 deletions src/components/EmptyStateComponent/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type SharedProps<T> = {
lottieWebViewStyles?: React.CSSProperties | undefined;
minModalHeight?: number;
showsVerticalScrollIndicator?: boolean;

/** Whether to add bottom safe area padding to the view. */
addBottomSafeAreaPadding?: boolean;
};

type MediaType<HeaderMedia, T extends MediaTypes> = SharedProps<T> & {
Expand Down
Loading