import { isValidElement, ReactNode } from "react";
import { ImageURISource, View } from "react-native";
import { useIOTheme } from "../../context";
import {
IOColors,
IOListItemLogoMargin,
IOListItemStyles,
IOListItemVisualParams,
IOVisualCostants
} from "../../core";
import { WithTestID } from "../../utils/types";
import { isImageUri } from "../../utils/url";
import { Avatar } from "../avatar/Avatar";
import { Badge } from "../badge/Badge";
import { LogoPaymentWithFallback } from "../common/LogoPaymentWithFallback";
import { IOIconSizeScale, Icon } from "../icons";
import { HStack, VStack } from "../layout";
import { IOLogoPaymentType } from "../logos";
import { IOSkeleton } from "../skeleton";
import { BodySmall, H6 } from "../typography";
import {
PressableBaseProps,
PressableListItemBase
} from "./PressableListItemBase";
export type ListItemTransactionBadge = {
text: string;
variant: Badge["variant"];
};
export type ListItemTransactionLogo =
| IOLogoPaymentType
| ImageURISource
| ReactNode;
export type ListItemTransaction = WithTestID<
PressableBaseProps & {
showChevron?: boolean;
isLoading?: boolean;
loadingAccessibilityLabel?: string;
/**
* A logo that will be displayed on the left of the list item.
*
* Must be a {@link IOLogoPaymentType} or an {@link ImageURISource} or an {@link Icon}.
*/
paymentLogoIcon?: ListItemTransactionLogo;
subtitle: string;
title: string;
/**
* The maximum number of lines to display for the title.
* @default 2
*/
numberOfLines?: number;
accessible?: boolean;
} & (
| {
transaction: {
amount: string;
amountAccessibilityLabel: string;
badge?: never;
refund?: boolean;
};
}
| {
transaction: {
amount?: string;
amountAccessibilityLabel?: string;
badge: ListItemTransactionBadge;
refund?: never;
};
}
)
>;
const CARD_LOGO_SIZE: IOIconSizeScale = 24;
const MUNICIPALITY_LOGO_SIZE = 44;
// this is the 's "small" size,
// since it is bigger than the card logos, we use
// it as a base size for homogeneous sizing via container size.
const ListItemTransactionContent = ({
paymentLogoIcon,
numberOfLines,
title,
subtitle,
badge,
amountAccessibilityLabel,
showChevron,
amount,
refund
}: Pick<
ListItemTransaction,
"paymentLogoIcon" | "numberOfLines" | "title" | "subtitle" | "showChevron"
> & {
badge: ListItemTransactionBadge | undefined;
amount: string | undefined;
amountAccessibilityLabel: string | undefined;
refund: boolean | undefined;
}) => {
const theme = useIOTheme();
const interactiveColor: IOColors = theme["interactiveElem-default"];
const amountColor: IOColors = refund
? theme.successText
: theme["textBody-default"];
return (
<>
{paymentLogoIcon && (
)}
{title}
{subtitle}
{badge ? (
) : (
{amount}
)}
{showChevron && (
)}
>
);
};
const StartComponent = ({
logoIcon
}: {
logoIcon: ListItemTransactionLogo;
}) => {
if (isImageUri(logoIcon)) {
return ;
}
if (isValidElement(logoIcon)) {
return <>{logoIcon}>;
}
return (
);
};
export const ListItemTransaction = ({
accessibilityLabel,
loadingAccessibilityLabel,
showChevron = false,
isLoading = false,
paymentLogoIcon,
onPress,
subtitle,
testID,
title,
transaction: { amount, amountAccessibilityLabel, badge, refund },
numberOfLines = 2,
accessible
}: ListItemTransaction) => {
if (isLoading) {
return (
);
}
const contentProps = {
paymentLogoIcon,
numberOfLines,
title,
subtitle,
badge,
amountAccessibilityLabel,
showChevron,
amount,
refund
} as const;
if (onPress) {
return (
);
} else {
return (
);
}
};
const ListItemTransactionSkeleton = ({
loadingAccessibilityLabel
}: Pick) => (
);