Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added ReactNode support for KeyValueRow tooltip and label #11660

Merged
merged 2 commits into from
Oct 7, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<View style={styles.labelContainer}>
<Label variant={variant} color={color}>
{label}
</Label>
{isPreDefinedKeyValueRowLabel(label) ? (
<Label
variant={label?.variant ?? TextVariant.BodyMDMedium}
color={label?.color ?? TextColor.Default}
>
{label.text}
</Label>
) : (
label
)}
{hasTooltip && (
<ButtonIcon
size={tooltip.size ?? TooltipSizes.Md}
iconColor={IconColor.Muted}
iconName={IconName.Info}
iconName={IconName.Question}
accessibilityRole="button"
accessibilityLabel={`${tooltip.title}} tooltip`}
accessibilityLabel={`${tooltip.title} tooltip`}
onPress={onNavigateToTooltipModal}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -38,42 +39,56 @@ export const KeyValueRow = {
<View style={styles.listItem}>
<KeyValueRowComponent
field={{
text: 'Sample Key Text',
label: {
text: 'Sample Key Text',
},
}}
value={{ text: 'Sample Key Text' }}
value={{ label: { text: 'Sample Value Text' } }}
/>
<KeyValueRowComponent
field={{
text: 'Sample Key Text',
variant: TextVariant.BodySM,
color: TextColor.Alternative,
label: {
text: 'Sample Key Text',
variant: TextVariant.BodySM,
color: TextColor.Alternative,
},
}}
value={{
text: 'Sample Value Text',
variant: TextVariant.BodySMBold,
color: TextColor.Success,
label: {
text: 'Sample Value Text',
variant: TextVariant.BodySMBold,
color: TextColor.Success,
},
tooltip: {
title: 'Sample Title',
text: 'Sample Tooltip',
content:
'Pariatur nisi pariatur ex veniam ad. Non tempor nostrud sint velit cupidatat aliquip elit ut pariatur reprehenderit enim enim commodo eu.',
size: TooltipSizes.Sm,
},
}}
/>
<KeyValueRowComponent
field={{
text: 'Sample Key Text',
label: {
text: 'Sample Key Text',
},
tooltip: {
title: 'Sample Tooltip',
text: 'Pariatur nisi pariatur ex veniam ad. Non tempor nostrud sint velit cupidatat aliquip elit ut pariatur reprehenderit enim enim commodo eu.',
content:
'Pariatur nisi pariatur ex veniam ad. Non tempor nostrud sint velit cupidatat aliquip elit ut pariatur reprehenderit enim enim commodo eu.',
},
}}
value={{
text: 'Sample Value Text',
label: {
text: 'Sample Value Text',
},
}}
/>
<KeyValueRowComponent
field={{
text: 'Sample Key Text',
label: {
text: 'Sample Key Text',
},
icon: {
name: IconName.Wifi,
color: IconColor.Primary,
Expand All @@ -82,7 +97,9 @@ export const KeyValueRow = {
},
}}
value={{
text: 'Sample Value Text',
label: {
text: 'Sample Value Text',
},
icon: {
name: IconName.Wifi,
color: IconColor.Primary,
Expand All @@ -91,6 +108,28 @@ export const KeyValueRow = {
},
}}
/>
{/* Using Custom ReactNode */}
<KeyValueRowComponent
field={{
label: { text: 'Sample Key' },
icon: { name: IconName.UserCircleAdd, color: IconColor.Primary },
tooltip: {
title: 'Sample Tooltip',
content:
'Pariatur nisi pariatur ex veniam ad. Non tempor nostrud sint velit cupidatat aliquip elit ut pariatur reprehenderit enim enim commodo eu.',
},
}}
value={{
label: (
<Button
variant={ButtonVariants.Link}
label="Sample button"
// eslint-disable-next-line no-alert
onPress={() => alert('test')}
/>
),
}}
/>
</View>
</View>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ describe('KeyValueRow', () => {
it('should render when there is only text', () => {
const { toJSON } = render(
<KeyValueRow
field={{ text: 'Sample Key Text' }}
value={{ text: 'Sample Value Text' }}
field={{ label: { text: 'Sample Key Text' } }}
value={{ label: { text: 'Sample Value Text' } }}
/>,
);

Expand All @@ -31,17 +31,17 @@ describe('KeyValueRow', () => {
const { toJSON } = render(
<KeyValueRow
field={{
text: 'Key Text',
label: { text: 'Key Text' },
tooltip: {
title: 'Sample Tooltip 1',
text: 'Tooltip 1 text',
content: 'Tooltip 1 text',
},
}}
value={{
text: 'Value Text',
label: { text: 'Value Text' },
tooltip: {
title: 'Sample Tooltip 2',
text: 'Tooltip 2 text',
content: 'Tooltip 2 text',
},
}}
/>,
Expand All @@ -54,13 +54,13 @@ describe('KeyValueRow', () => {
const { toJSON } = render(
<KeyValueRow
field={{
text: 'Key Text',
label: { text: 'Key Text' },
icon: {
name: IconName.Activity,
},
}}
value={{
text: 'Value Text',
label: { text: 'Value Text' },
icon: {
name: IconName.Add,
},
Expand All @@ -75,23 +75,23 @@ describe('KeyValueRow', () => {
const { toJSON } = render(
<KeyValueRow
field={{
text: 'Key Text',
label: { text: 'Key Text' },
icon: {
name: IconName.Activity,
},
tooltip: {
title: 'Sample Tooltip 2',
text: 'Tooltip 2 text',
content: 'Tooltip 2 text',
},
}}
value={{
text: 'Value Text',
label: { text: 'Value Text' },
icon: {
name: IconName.Add,
},
tooltip: {
title: 'Sample Tooltip 2',
text: 'Tooltip 2 text',
content: 'Tooltip 2 text',
},
}}
/>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -45,12 +44,7 @@ const KeyValueRow = React.memo(({ field, value, style }: KeyValueRowProps) => {
(fieldIcon.side === KeyValueRowFieldIconSides.LEFT ||
fieldIcon.side === KeyValueRowFieldIconSides.BOTH ||
!fieldIcon?.side) && <Icon {...fieldIcon} />}
<KeyValueRowLabel
label={field.text}
variant={field.variant}
color={field.color}
tooltip={field.tooltip}
/>
<KeyValueRowLabel label={field.label} tooltip={field.tooltip} />
{shouldShowFieldIcon &&
(fieldIcon?.side === KeyValueRowFieldIconSides.RIGHT ||
fieldIcon?.side === KeyValueRowFieldIconSides.BOTH) && (
Expand All @@ -64,12 +58,7 @@ const KeyValueRow = React.memo(({ field, value, style }: KeyValueRowProps) => {
(valueIcon?.side === KeyValueRowFieldIconSides.LEFT ||
valueIcon?.side === KeyValueRowFieldIconSides.BOTH ||
!valueIcon?.side) && <Icon {...valueIcon} />}
<KeyValueRowLabel
label={value.text}
variant={value.variant}
color={value.color}
tooltip={value.tooltip}
/>
<KeyValueRowLabel label={value.label} tooltip={value.tooltip} />
{shouldShowValueIcon &&
(valueIcon?.side === KeyValueRowFieldIconSides.RIGHT ||
valueIcon?.side === KeyValueRowFieldIconSides.BOTH) && (
Expand All @@ -79,7 +68,7 @@ const KeyValueRow = React.memo(({ field, value, style }: KeyValueRowProps) => {
</KeyValueSection>
</KeyValueRowRoot>
);
}, areKeyValueRowPropsEqual);
});

/**
* Exported sub-components to provide a base for new KeyValueRow variants.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
*/
Expand All @@ -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
Expand All @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Loading
Loading