From da8b99a780f3a6eceee426fdda147deae60849f9 Mon Sep 17 00:00:00 2001 From: Matthew Grainger Date: Mon, 7 Oct 2024 12:02:57 -0400 Subject: [PATCH] feat: added ReactNode support for KeyValueRow tooltip and label --- .../KeyValueLabel/KeyValueLabel.tsx | 34 +++++----- .../KeyValueRow/KeyValueRow.stories.tsx | 67 +++++++++++++++---- .../KeyValueRow/KeyValueRow.test.tsx | 24 +++---- .../KeyValueRow/KeyValueRow.tsx | 17 +---- .../KeyValueRow/KeyValueRow.types.ts | 39 +++++------ .../KeyValueRow/KeyValueRow.utils.ts | 15 +++-- .../__snapshots__/KeyValueRow.test.tsx.snap | 16 ++--- .../Views/TooltipModal/ToolTipModal.styles.ts | 5 +- .../Views/TooltipModal/ToolTipModal.types.ts | 4 +- app/components/Views/TooltipModal/index.tsx | 10 ++- app/components/hooks/useTooltipModal.tsx | 3 +- 11 files changed, 133 insertions(+), 101 deletions(-) diff --git a/app/component-library/components-temp/KeyValueRow/KeyValueLabel/KeyValueLabel.tsx b/app/component-library/components-temp/KeyValueRow/KeyValueLabel/KeyValueLabel.tsx index aefa71eecbc..bfc064931ee 100644 --- a/app/component-library/components-temp/KeyValueRow/KeyValueLabel/KeyValueLabel.tsx +++ b/app/component-library/components-temp/KeyValueRow/KeyValueLabel/KeyValueLabel.tsx @@ -14,46 +14,48 @@ import React from 'react'; import { View } from 'react-native'; import { KeyValueRowLabelProps, TooltipSizes } from '../KeyValueRow.types'; import styleSheet from './KeyValueLabel.styles'; +import { isPreDefinedKeyValueRowLabel } from '../KeyValueRow.utils'; /** * A label and tooltip component. * * @param {Object} props - Component props. - * @param {TextVariant} [props.variant] - Optional text variant. Defaults to TextVariant.BodyMDMedium. - * @param {TextVariant} [props.color] - Optional text color. Defaults to TextColor.Default. - * @param {TextVariant} [props.tooltip] - Optional tooltip to render to the right of the label text. + * @param {PreDefinedKeyValueRowLabel | ReactNode} props.label - The label content to display. + * @param {KeyValueRowTooltip} [props.tooltip] - Optional tooltip to render to the right of the label. * * @returns {JSX.Element} The rendered KeyValueRowLabel component. */ -const KeyValueRowLabel = ({ - label, - variant = TextVariant.BodyMDMedium, - color = TextColor.Default, - tooltip, -}: KeyValueRowLabelProps) => { +const KeyValueRowLabel = ({ label, tooltip }: KeyValueRowLabelProps) => { const { styles } = useStyles(styleSheet, {}); const { openTooltipModal } = useTooltipModal(); - const hasTooltip = tooltip?.title && tooltip?.text; + const hasTooltip = tooltip?.title && tooltip?.content; const onNavigateToTooltipModal = () => { if (!hasTooltip) return; - openTooltipModal(tooltip.title, tooltip.text); + openTooltipModal(tooltip.title, tooltip.content); }; return ( - + {isPreDefinedKeyValueRowLabel(label) ? ( + + ) : ( + label + )} {hasTooltip && ( )} diff --git a/app/component-library/components-temp/KeyValueRow/KeyValueRow.stories.tsx b/app/component-library/components-temp/KeyValueRow/KeyValueRow.stories.tsx index e5a440b3276..ee34ef3c4b4 100644 --- a/app/component-library/components-temp/KeyValueRow/KeyValueRow.stories.tsx +++ b/app/component-library/components-temp/KeyValueRow/KeyValueRow.stories.tsx @@ -8,6 +8,7 @@ import KeyValueRowComponent, { import Text, { TextColor, TextVariant } from '../../components/Texts/Text'; import Title from '../../../components/Base/Title'; import { IconColor, IconName, IconSize } from '../../components/Icons/Icon'; +import Button, { ButtonVariants } from '../../components/Buttons/Button'; const KeyValueRowMeta = { title: 'Components Temp / KeyValueRow', @@ -38,42 +39,56 @@ export const KeyValueRow = { + {/* Using Custom ReactNode */} + alert('test')} + /> + ), + }} + /> ), diff --git a/app/component-library/components-temp/KeyValueRow/KeyValueRow.test.tsx b/app/component-library/components-temp/KeyValueRow/KeyValueRow.test.tsx index a9b00ece7e8..389a3213db5 100644 --- a/app/component-library/components-temp/KeyValueRow/KeyValueRow.test.tsx +++ b/app/component-library/components-temp/KeyValueRow/KeyValueRow.test.tsx @@ -19,8 +19,8 @@ describe('KeyValueRow', () => { it('should render when there is only text', () => { const { toJSON } = render( , ); @@ -31,17 +31,17 @@ describe('KeyValueRow', () => { const { toJSON } = render( , @@ -54,13 +54,13 @@ describe('KeyValueRow', () => { const { toJSON } = render( { const { toJSON } = render( , diff --git a/app/component-library/components-temp/KeyValueRow/KeyValueRow.tsx b/app/component-library/components-temp/KeyValueRow/KeyValueRow.tsx index 18c6300b1cf..212396f888e 100644 --- a/app/component-library/components-temp/KeyValueRow/KeyValueRow.tsx +++ b/app/component-library/components-temp/KeyValueRow/KeyValueRow.tsx @@ -8,7 +8,6 @@ import { } from './KeyValueRow.types'; import Icon from '../../components/Icons/Icon'; import { View } from 'react-native'; -import { areKeyValueRowPropsEqual } from './KeyValueRow.utils'; import KeyValueSection from './KeyValueSection/KeyValueSection'; import KeyValueRowLabel from './KeyValueLabel/KeyValueLabel'; import KeyValueRowRoot from './KeyValueRoot/KeyValueRoot'; @@ -45,12 +44,7 @@ const KeyValueRow = React.memo(({ field, value, style }: KeyValueRowProps) => { (fieldIcon.side === KeyValueRowFieldIconSides.LEFT || fieldIcon.side === KeyValueRowFieldIconSides.BOTH || !fieldIcon?.side) && } - + {shouldShowFieldIcon && (fieldIcon?.side === KeyValueRowFieldIconSides.RIGHT || fieldIcon?.side === KeyValueRowFieldIconSides.BOTH) && ( @@ -64,12 +58,7 @@ const KeyValueRow = React.memo(({ field, value, style }: KeyValueRowProps) => { (valueIcon?.side === KeyValueRowFieldIconSides.LEFT || valueIcon?.side === KeyValueRowFieldIconSides.BOTH || !valueIcon?.side) && } - + {shouldShowValueIcon && (valueIcon?.side === KeyValueRowFieldIconSides.RIGHT || valueIcon?.side === KeyValueRowFieldIconSides.BOTH) && ( @@ -79,7 +68,7 @@ const KeyValueRow = React.memo(({ field, value, style }: KeyValueRowProps) => { ); -}, areKeyValueRowPropsEqual); +}); /** * Exported sub-components to provide a base for new KeyValueRow variants. diff --git a/app/component-library/components-temp/KeyValueRow/KeyValueRow.types.ts b/app/component-library/components-temp/KeyValueRow/KeyValueRow.types.ts index 0e9c864d309..fc4e825921e 100644 --- a/app/component-library/components-temp/KeyValueRow/KeyValueRow.types.ts +++ b/app/component-library/components-temp/KeyValueRow/KeyValueRow.types.ts @@ -19,9 +19,9 @@ interface KeyValueRowTooltip { */ title: string; /** - * The text displayed within the tooltip body. + * The content displayed within the tooltip body. */ - text: string; + content: string | ReactNode; /** * Optional size of the tooltip icon. * @default TooltipSizes.Md @@ -47,19 +47,9 @@ export enum KeyValueRowFieldIconSides { */ interface KeyValueRowField { /** - * The text to display. - */ - text: string; - /** - * Optional text variant. - * @default TextVariant.BodyMDMedium + * The label content displayed. */ - variant?: TextProps['variant']; - /** - * Optional text color. - * @default TextColor.Default - */ - color?: TextProps['color']; + label: PreDefinedKeyValueRowLabel | ReactNode; /** * Optional icon to display. If undefined, no icon is displayed. */ @@ -74,16 +64,11 @@ export const IconSizes = IconSize; export const TooltipSizes = ButtonIconSizes; -/** - * The KeyValueRowLabel prop interface. - * - * @see KeyValueRowLabel in ./KeyValueRow.tsx - */ -export interface KeyValueRowLabelProps { +export interface PreDefinedKeyValueRowLabel { /** * Text to display. */ - label: string; + text: string; /** * Optional text variant. * @default TextVariant.BodyMDMedium @@ -94,6 +79,18 @@ export interface KeyValueRowLabelProps { * @default TextColor.Default */ color?: TextProps['color']; +} + +/** + * The KeyValueRowLabel prop interface. + * + * @see KeyValueRowLabel in ./KeyValueRow.tsx + */ +export interface KeyValueRowLabelProps { + /** + * The label content displayed. + */ + label: PreDefinedKeyValueRowLabel | ReactNode; /** * Optional tooltip. If undefined, the tooltip won't be displayed. */ diff --git a/app/component-library/components-temp/KeyValueRow/KeyValueRow.utils.ts b/app/component-library/components-temp/KeyValueRow/KeyValueRow.utils.ts index bf4c38843e4..3361cb4d66f 100644 --- a/app/component-library/components-temp/KeyValueRow/KeyValueRow.utils.ts +++ b/app/component-library/components-temp/KeyValueRow/KeyValueRow.utils.ts @@ -1,8 +1,9 @@ -import { KeyValueRowProps } from './KeyValueRow.types'; +import { + KeyValueRowLabelProps, + PreDefinedKeyValueRowLabel, +} from './KeyValueRow.types'; -export const areKeyValueRowPropsEqual = ( - prevProps: KeyValueRowProps, - newProps: KeyValueRowProps, -) => - JSON.stringify(prevProps.field) === JSON.stringify(newProps.field) && - JSON.stringify(prevProps.value) === JSON.stringify(newProps.value); +export const isPreDefinedKeyValueRowLabel = ( + label: KeyValueRowLabelProps['label'], +): label is PreDefinedKeyValueRowLabel => + !!label && typeof label === 'object' && 'text' in label; diff --git a/app/component-library/components-temp/KeyValueRow/__snapshots__/KeyValueRow.test.tsx.snap b/app/component-library/components-temp/KeyValueRow/__snapshots__/KeyValueRow.test.tsx.snap index c83d3a4fd5f..a4c9e5f6bfe 100644 --- a/app/component-library/components-temp/KeyValueRow/__snapshots__/KeyValueRow.test.tsx.snap +++ b/app/component-library/components-temp/KeyValueRow/__snapshots__/KeyValueRow.test.tsx.snap @@ -201,7 +201,7 @@ exports[`KeyValueRow Prebuilt Component KeyValueRow should render text with icon Key Text StyleSheet.create({ - container: { - paddingBottom: 16, - }, content: { paddingBottom: 16, - paddingHorizontal: 16, + paddingHorizontal: 32, flexDirection: 'row', justifyContent: 'center', }, diff --git a/app/components/Views/TooltipModal/ToolTipModal.types.ts b/app/components/Views/TooltipModal/ToolTipModal.types.ts index da5a68d64d3..4265dae991c 100644 --- a/app/components/Views/TooltipModal/ToolTipModal.types.ts +++ b/app/components/Views/TooltipModal/ToolTipModal.types.ts @@ -1,8 +1,10 @@ +import { ReactNode } from 'react'; + export interface TooltipModalProps { /** * Props that are passed in while navigating to screen. */ route: { - params: { title: string; tooltip: string }; + params: { title: string; tooltip: string | ReactNode }; }; } diff --git a/app/components/Views/TooltipModal/index.tsx b/app/components/Views/TooltipModal/index.tsx index 12e14b277d7..ddd0eb7ec8f 100644 --- a/app/components/Views/TooltipModal/index.tsx +++ b/app/components/Views/TooltipModal/index.tsx @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useRef, isValidElement } from 'react'; import { View } from 'react-native'; import BottomSheet, { BottomSheetRef, @@ -23,12 +23,16 @@ const TooltipModal = ({ route }: TooltipModalProps) => { return ( - + {title} - {tooltip} + {isValidElement(tooltip) ? ( + tooltip + ) : ( + {tooltip} + )} diff --git a/app/components/hooks/useTooltipModal.tsx b/app/components/hooks/useTooltipModal.tsx index 2970067c175..4fa504295dd 100644 --- a/app/components/hooks/useTooltipModal.tsx +++ b/app/components/hooks/useTooltipModal.tsx @@ -1,10 +1,11 @@ import { useNavigation } from '@react-navigation/native'; import Routes from '../../constants/navigation/Routes'; +import { ReactNode } from 'react'; const useTooltipModal = () => { const { navigate } = useNavigation(); - const openTooltipModal = (title: string, tooltip: string) => + const openTooltipModal = (title: string, tooltip: string | ReactNode) => navigate(Routes.MODAL.ROOT_MODAL_FLOW, { screen: Routes.SHEET.TOOLTIP_MODAL, params: { title, tooltip },