Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion src/design-system/components/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useMemo, type ReactNode, type Ref } from 'react';
import { Text as NativeText, type StyleProp, type TextStyle } from 'react-native';
import { Text as NativeText, type NativeSyntheticEvent, type StyleProp, type TextLayoutEventData, type TextStyle } from 'react-native';

import { SILENCE_EMOJI_WARNINGS } from 'react-native-dotenv';

Expand Down Expand Up @@ -30,6 +30,7 @@ export type TextProps = {
uppercase?: boolean;
weight?: TextWeight;
onPress?: () => void;
onTextLayout?: (event: NativeSyntheticEvent<TextLayoutEventData>) => void;
} & (
| {
containsEmoji: true;
Expand All @@ -54,6 +55,7 @@ export function Text({
uppercase,
weight,
onPress,
onTextLayout,
style,
ref,
}: TextProps) {
Expand Down Expand Up @@ -95,6 +97,7 @@ export function Text({
style={[textStyle, style || {}]}
testID={testID}
onPress={onPress}
onTextLayout={onTextLayout}
>
{IS_IOS && containsEmojiProp && nodeIsString(children) ? renderStringWithEmoji(children) : children}
{lineHeightFixNode}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { format } from 'date-fns';

import { getColorValueForThemeWorklet } from '@/__swaps__/utils/swaps';
import ButtonPressAnimation from '@/components/animations/ButtonPressAnimation';
import { EasingGradient } from '@/components/easing-gradient/EasingGradient';
import { Box, globalColors, Text, TextIcon, TextShadow, useColorMode } from '@/design-system';
import { CATEGORIES } from '@/features/polymarket/constants';
import { type PolymarketEvent, type PolymarketMarketEvent } from '@/features/polymarket/types/polymarket-event';
import { ExpandableDescriptionCard } from '@/framework/ui/components/ExpandableDescriptionCard';
import { opacity } from '@/framework/ui/utils/opacity';
import * as i18n from '@/languages';
import Navigation from '@/navigation/Navigation';
Expand Down Expand Up @@ -54,48 +54,22 @@ const Description = memo(function Description({
const backgroundColor = isDarkMode
? getSolidColorEquivalent({ background: screenBackgroundColor, foreground: '#F5F8FF', opacity: 0.04 })
: getSolidColorEquivalent({ background: screenBackgroundColor, foreground: '#09111F', opacity: 0.02 });
const borderColor = opacity(isDarkMode ? '#F5F8FF' : '#09111F', 0.02);

return (
<ButtonPressAnimation
<ExpandableDescriptionCard
backgroundColor={backgroundColor}
borderColor={borderColor}
borderWidth={isDarkMode ? 2 : THICK_BORDER_WIDTH}
ctaColor="label"
ctaIcon="􀆊"
ctaLabel={i18n.t(i18n.l.predictions.event.show_rules)}
description={description}
onPress={() => {
Navigation.handleAction(Routes.POLYMARKET_MARKET_DESCRIPTION_SHEET, { description });
}}
scaleTo={0.95}
>
<Box
width="full"
backgroundColor={backgroundColor}
borderRadius={26}
padding={'20px'}
borderWidth={isDarkMode ? 2 : THICK_BORDER_WIDTH}
borderColor={{ custom: opacity(isDarkMode ? '#F5F8FF' : '#09111F', 0.02) }}
>
<Text color="labelTertiary" size="17pt / 150%" weight="medium" numberOfLines={3}>
{description}
</Text>
<Box height={26} position="absolute" bottom={{ custom: 12 }} right={{ custom: 14 }} zIndex={1}>
<Box flexDirection="row" alignItems="center" justifyContent="center">
<EasingGradient
startPosition={'left'}
endPosition={'right'}
endColor={backgroundColor}
startColor={backgroundColor}
endOpacity={1}
startOpacity={0}
style={{ height: 26, width: 100 }}
/>
<Box flexDirection="row" alignItems="center" gap={4} backgroundColor={backgroundColor}>
<Text color="label" size="15pt" weight="bold">
{i18n.t(i18n.l.predictions.event.show_rules)}
</Text>
<TextIcon size="icon 12px" weight="heavy" color="label">
{'􀆊'}
</TextIcon>
</Box>
</Box>
</Box>
</Box>
</ButtonPressAnimation>
/>
);
});

Expand Down
106 changes: 106 additions & 0 deletions src/framework/ui/components/ExpandableDescriptionCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { memo, useCallback, useState } from 'react';
import { StyleSheet, View, type NativeSyntheticEvent, type TextLayoutEventData } from 'react-native';

import ButtonPressAnimation from '@/components/animations/ButtonPressAnimation';
import { EasingGradient } from '@/components/easing-gradient/EasingGradient';
import { Box, Text, TextIcon } from '@/design-system';
import { type TextProps } from '@/design-system/components/Text/Text';

const CTA_GRADIENT_WIDTH = 100;
const DEFAULT_NUMBER_OF_LINES = 3;

type ExpandableDescriptionCardProps = {
backgroundColor: string;
borderColor: string;
borderWidth: number;
ctaColor: TextProps['color'];
ctaIcon: string;
ctaLabel: string;
description: string;
onPress: () => void;
numberOfLines?: number;
scaleTo?: number;
textColor?: TextProps['color'];
textSize?: TextProps['size'];
textWeight?: TextProps['weight'];
};

export const ExpandableDescriptionCard = memo(function ExpandableDescriptionCard({
backgroundColor,
borderColor,
borderWidth,
ctaColor,
ctaIcon,
ctaLabel,
description,
onPress,
numberOfLines = DEFAULT_NUMBER_OF_LINES,
scaleTo = 0.95,
textColor = 'labelTertiary',
textSize = '17pt / 150%',
textWeight = 'medium',
}: ExpandableDescriptionCardProps) {
const [showCallToAction, setShowCallToAction] = useState(false);

const onDescriptionLayout = useCallback(
({ nativeEvent: { lines } }: NativeSyntheticEvent<TextLayoutEventData>) => {
const nextShowCallToAction = lines.length >= numberOfLines;
setShowCallToAction(currentValue => (currentValue === nextShowCallToAction ? currentValue : nextShowCallToAction));
},
[numberOfLines]
);

return (
<ButtonPressAnimation onPress={showCallToAction ? onPress : undefined} scaleTo={scaleTo}>
<Box
width="full"
backgroundColor={backgroundColor}
borderRadius={26}
padding="20px"
borderWidth={borderWidth}
borderColor={{ custom: borderColor }}
>
<Text color={textColor} size={textSize} weight={textWeight} numberOfLines={numberOfLines} onTextLayout={onDescriptionLayout}>
{description}
</Text>
{showCallToAction && (
<View style={styles.callToActionRow}>
<Box flexDirection="row" alignItems="center" justifyContent="center">
<EasingGradient
startPosition="left"
endPosition="right"
startColor={backgroundColor}
endColor={backgroundColor}
startOpacity={0}
endOpacity={1}
style={styles.callToActionGradient}
/>
<Box flexDirection="row" alignItems="center" gap={4} backgroundColor={backgroundColor}>
<Text color={ctaColor} size="15pt" weight="bold">
{ctaLabel}
</Text>
<TextIcon size="icon 12px" weight="heavy" color={ctaColor}>
{ctaIcon}
</TextIcon>
</Box>
</Box>
</View>
)}
</Box>
</ButtonPressAnimation>
);
});

const styles = StyleSheet.create({
callToActionGradient: {
height: 26,
width: CTA_GRADIENT_WIDTH,
},
callToActionRow: {
bottom: 12,
height: 26,
position: 'absolute',
right: 14,
zIndex: 1,
},
});
Loading