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 KeyValueRow to component-library/components-temp #11294

Merged
merged 25 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
632eefc
feat: added KeyValueRow to component-library/components-temp
Matt561 Sep 18, 2024
be40200
feat: minor refactoring
Matt561 Sep 18, 2024
7b8036c
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 18, 2024
bd90edc
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 18, 2024
1f66c79
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 19, 2024
120b2b4
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 19, 2024
9a30ae5
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 19, 2024
de96d65
fix: renamed KeyValueRow-specific interfaces to be less generic
Matt561 Sep 19, 2024
73fbd64
feat: added jsdoc comments to KeyValueRow
Matt561 Sep 19, 2024
6aa32dc
temp: eod commit, finishing cleanup based on pr review comments
Matt561 Sep 19, 2024
db41aa4
feat: refactored and simplified KeyValueRow
Matt561 Sep 20, 2024
2020309
feat: broke out KeyValueRow stubs into their own directories
Matt561 Sep 20, 2024
6cbc408
feat: updated KeyValueRow tests and snapshots to reflect refactor
Matt561 Sep 20, 2024
1e0ece0
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 20, 2024
ab6ed9b
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 20, 2024
5e44704
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 23, 2024
f1e0a9e
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 23, 2024
04b5e29
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 23, 2024
d8b9379
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 24, 2024
e51a2cd
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 24, 2024
da9d4f4
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 24, 2024
a4c66f5
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 24, 2024
b6fc2fb
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 24, 2024
a5f3f07
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 24, 2024
ad5f60f
Merge branch 'main' into feat/stake-829-create-key-value-row-component
Matt561 Sep 24, 2024
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
1 change: 1 addition & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
'../app/component-library/components/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/base-components/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components-temp/TagColored/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components-temp/KeyValueRow/**/*.stories.?(ts|tsx|js|jsx)',
],
addons: ['@storybook/addon-ondevice-controls'],
framework: '@storybook/react-native',
Expand Down
10 changes: 8 additions & 2 deletions .storybook/storybook.requires.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ global.STORIES = [
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components-temp\\/TagColored(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: "",
directory: "./app/component-library/components-temp/KeyValueRow",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components-temp\\/KeyValueRow(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
];

import "@storybook/addon-ondevice-controls/register";
Expand Down Expand Up @@ -115,8 +122,7 @@ const getStories = () => {
"./app/component-library/components/Toast/Toast.stories.tsx": require("../app/component-library/components/Toast/Toast.stories.tsx"),
"./app/component-library/base-components/TagBase/TagBase.stories.tsx": require("../app/component-library/base-components/TagBase/TagBase.stories.tsx"),
"./app/component-library/components-temp/TagColored/TagColored.stories.tsx": require("../app/component-library/components-temp/TagColored/TagColored.stories.tsx"),
"./app/components/Views/AssetDetails/AssetDetailsActions/AssetDetailsActions.stories.tsx": require("../app/components/Views/AssetDetails/AssetDetailsActions/AssetDetailsActions.stories.tsx"),

"./app/component-library/components-temp/KeyValueRow/KeyValueRow.stories.tsx": require("../app/component-library/components-temp/KeyValueRow/KeyValueRow.stories.tsx"),
};
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { StyleSheet } from 'react-native';

const styleSheet = () =>
StyleSheet.create({
labelContainer: {
flexDirection: 'row',
alignItems: 'center',
},
});

export default styleSheet;
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import ButtonIcon from '../../../../component-library/components/Buttons/ButtonIcon';
import Label from '../../../../component-library/components/Form/Label';
import {
IconColor,
IconName,
} from '../../../../component-library/components/Icons/Icon';
import {
TextVariant,
TextColor,
} from '../../../../component-library/components/Texts/Text';
import { useStyles } from '../../../../component-library/hooks';
import useTooltipModal from '../../../../components/hooks/useTooltipModal';
import React from 'react';
import { View } from 'react-native';
import { KeyValueRowLabelProps, TooltipSizes } from '../KeyValueRow.types';
import styleSheet from './KeyValueLabel.styles';

/**
* 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.
*
* @returns {JSX.Element} The rendered KeyValueRowLabel component.
*/
const KeyValueRowLabel = ({
label,
variant = TextVariant.BodyMDMedium,
color = TextColor.Default,
tooltip,
}: KeyValueRowLabelProps) => {
const { styles } = useStyles(styleSheet, {});

const { openTooltipModal } = useTooltipModal();

const hasTooltip = tooltip?.title && tooltip?.text;

const onNavigateToTooltipModal = () => {
if (!hasTooltip) return;
openTooltipModal(tooltip.title, tooltip.text);
};

return (
<View style={styles.labelContainer}>
<Label variant={variant} color={color}>
{label}
</Label>
{hasTooltip && (
<ButtonIcon
size={tooltip.size ?? TooltipSizes.Md}
iconColor={IconColor.Muted}
iconName={IconName.Info}
accessibilityRole="button"
accessibilityLabel={`${tooltip.title}} tooltip`}
onPress={onNavigateToTooltipModal}
/>
)}
</View>
);
};

export default KeyValueRowLabel;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { StyleSheet } from 'react-native';

const styleSheet = () =>
StyleSheet.create({
rootContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
overflow: 'hidden',
},
});

export default styleSheet;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useStyles } from '../../../hooks';
import React from 'react';
import { View } from 'react-native';
import { KeyValueRowRootProps } from '../KeyValueRow.types';
import styleSheet from './KeyValueRoot.styles';

/**
* The main container for the KeyValueRow component.
* When creating custom KeyValueRow components, this must be the outermost component wrapping the two <KeyValueSection/> components.
*
* e.g.
* ```
* <KeyValueRowRoot>
* <KeyValueSection></KeyValueSection>
* <KeyValueSection></KeyValueSection>
* </KeyValueRowRoot>
* ```
*
* @component
* @param {Object} props - Component props.
* @param {Array<ReactNode>} props.children - The two <KeyValueSection> children.
* @param {ViewProps} [props.style] - Optional styling
*
* @returns {JSX.Element} The rendered Root component.
*/
const KeyValueRowRoot = ({
children,
style: customStyles,
}: KeyValueRowRootProps) => {
const { styles: defaultStyles } = useStyles(styleSheet, {});

const styles = [defaultStyles.rootContainer, customStyles];

return <View style={styles}>{children}</View>;
};

export default KeyValueRowRoot;
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React from 'react';
import { withNavigation } from '../../../../storybook/decorators';
import { View, StyleSheet } from 'react-native';
import KeyValueRowComponent, {
KeyValueRowFieldIconSides,
TooltipSizes,
} from './index';
import Text, { TextColor, TextVariant } from '../../components/Texts/Text';
import Title from '../../../components/Base/Title';
import { IconColor, IconName, IconSize } from '../../components/Icons/Icon';

const KeyValueRowMeta = {
title: 'Components Temp / KeyValueRow',
component: KeyValueRowComponent,
decorators: [withNavigation],
Matt561 marked this conversation as resolved.
Show resolved Hide resolved
};

export default KeyValueRowMeta;

const styles = StyleSheet.create({
container: {
padding: 16,
},
listItem: {
marginVertical: 16,
gap: 16,
},
});

export const KeyValueRow = {
render: () => (
<View style={styles.container}>
<Title>KeyValueRow Component</Title>
<Text variant={TextVariant.BodySM}>
Prebuilt component displayed below but KeyValueRow stubs are available
to create new KeyValueRow variants.
</Text>
<View style={styles.listItem}>
<KeyValueRowComponent
field={{
text: 'Sample Key Text',
}}
value={{ text: 'Sample Key Text' }}
/>
<KeyValueRowComponent
field={{
text: 'Sample Key Text',
variant: TextVariant.BodySM,
color: TextColor.Alternative,
}}
value={{
text: 'Sample Value Text',
variant: TextVariant.BodySMBold,
color: TextColor.Success,
tooltip: {
title: 'Sample Title',
text: 'Sample Tooltip',
size: TooltipSizes.Sm,
},
}}
/>
<KeyValueRowComponent
field={{
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.',
},
}}
value={{
text: 'Sample Value Text',
}}
/>
<KeyValueRowComponent
field={{
text: 'Sample Key Text',
icon: {
name: IconName.Wifi,
color: IconColor.Primary,
size: IconSize.Sm,
side: KeyValueRowFieldIconSides.BOTH,
},
}}
value={{
text: 'Sample Value Text',
icon: {
name: IconName.Wifi,
color: IconColor.Primary,
size: IconSize.Sm,
side: KeyValueRowFieldIconSides.BOTH,
},
}}
/>
</View>
</View>
),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { StyleSheet } from 'react-native';

const styleSheet = () =>
StyleSheet.create({
flexRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
});

export default styleSheet;
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React from 'react';
import { render } from '@testing-library/react-native';
import KeyValueRow from './KeyValueRow';
import { IconName } from '../../components/Icons/Icon';

jest.mock('@react-navigation/native', () => {
const actualNav = jest.requireActual('@react-navigation/native');
return {
...actualNav,
useNavigation: () => ({
navigate: jest.fn(),
}),
};
});

describe('KeyValueRow', () => {
describe('Prebuilt Component', () => {
describe('KeyValueRow', () => {
it('should render when there is only text', () => {
const { toJSON } = render(
<KeyValueRow
field={{ text: 'Sample Key Text' }}
value={{ text: 'Sample Value Text' }}
/>,
);

expect(toJSON()).toMatchSnapshot();
});

it('should render text with tooltips', () => {
const { toJSON } = render(
<KeyValueRow
field={{
text: 'Key Text',
tooltip: {
title: 'Sample Tooltip 1',
text: 'Tooltip 1 text',
},
}}
value={{
text: 'Value Text',
tooltip: {
title: 'Sample Tooltip 2',
text: 'Tooltip 2 text',
},
}}
/>,
);

expect(toJSON()).toMatchSnapshot();
});

it('should render text with icons', () => {
const { toJSON } = render(
<KeyValueRow
field={{
text: 'Key Text',
icon: {
name: IconName.Activity,
},
}}
value={{
text: 'Value Text',
icon: {
name: IconName.Add,
},
}}
/>,
);

expect(toJSON()).toMatchSnapshot();
});

it('should render text with icons and tooltips', () => {
const { toJSON } = render(
<KeyValueRow
field={{
text: 'Key Text',
icon: {
name: IconName.Activity,
},
tooltip: {
title: 'Sample Tooltip 2',
text: 'Tooltip 2 text',
},
}}
value={{
text: 'Value Text',
icon: {
name: IconName.Add,
},
tooltip: {
title: 'Sample Tooltip 2',
text: 'Tooltip 2 text',
},
}}
/>,
);

expect(toJSON()).toMatchSnapshot();
});
});
});
});
Loading
Loading