Skip to content

Commit d8e6d75

Browse files
authored
feat: Update DaoDataListItem component to support isExternal property (#421)
1 parent b6d1597 commit d8e6d75

File tree

4 files changed

+53
-16
lines changed

4 files changed

+53
-16
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Update `<DaoDataListItem.Structure />` module component to support new `isExternal` property
13+
1014
### Changed
1115

1216
- Update Manrope font weight for Regular variant from 500 to 400

src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.stories.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,21 @@ type Story = StoryObj<typeof DaoDataListItemStructure>;
2020
export const Default: Story = {
2121
args: {
2222
name: 'Patito DAO',
23-
logoSrc: 'https://cdn.discordapp.com/icons/672466989217873929/acffa3e9e09ac5962ff803a5f8649040.webp?size=240',
23+
logoSrc: 'https://pbs.twimg.com/profile_images/1851934141782331394/Z0ZqlyIo_400x400.png',
2424
description:
2525
'Papito DAO is responsible for maximizing effective coordination and collaboration between different Patito teams and enabling them to perform at their best ability with the highest velocity they can achieve. Our main focus is on managing the day-to-day tasks of the Patito Guilds, such as enabling contractual relationships, legal operations, accounting, finance, and HR. We are also responsible for addressing any issues that may arise within the teams and deploying new tools, and infrastructure to ensure smooth operations.',
26-
network: 'Ethereum Mainnet',
27-
ens: 'patito.dao.eth',
26+
network: 'Ethereum',
27+
address: '0xc6B61B776367b236648399ACF4A0bc5aDe70708F',
2828
},
2929
};
3030

3131
/* Usage with extra long strings for name & ENS */
3232
export const LongNames: Story = {
3333
args: {
3434
name: 'A DAO With An Extremely Long Name That Should Be Truncated DAO',
35-
logoSrc: 'https://cdn.discordapp.com/icons/672466989217873929/acffa3e9e09ac5962ff803a5f8649040.webp?size=240',
3635
description:
3736
'Papito DAO is responsible for maximizing effective coordination and collaboration between different Patito teams and enabling them to perform at their best ability with the highest velocity they can achieve. Our main focus is on managing the day-to-day tasks of the Patito Guilds, such as enabling contractual relationships, legal operations, accounting, finance, and HR. We are also responsible for addressing any issues that may arise within the teams and deploying new tools, and infrastructure to ensure smooth operations.',
38-
network: 'Ethereum Mainnet',
37+
network: 'Ethereum',
3938
ens: 'a_dao_with_an_extremely_long_ens_name_that_should_be_truncated.dao.eth',
4039
},
4140
};
@@ -48,9 +47,25 @@ export const Fallback: Story = {
4847
name: 'Patito DAO',
4948
description:
5049
'Papito DAO is responsible for maximizing effective coordination and collaboration between different Patito teams and enabling them to perform at their best ability with the highest velocity they can achieve. Our main focus is on managing the day-to-day tasks of the Patito Guilds, such as enabling contractual relationships, legal operations, accounting, finance, and HR. We are also responsible for addressing any issues that may arise within the teams and deploying new tools, and infrastructure to ensure smooth operations.',
51-
network: 'Ethereum Mainnet',
50+
network: 'Ethereum',
5251
ens: 'patito.dao.eth',
5352
},
5453
};
5554

55+
/**
56+
* Usage of the DaoDataListItem component with external link.
57+
*/
58+
export const External: Story = {
59+
args: {
60+
name: 'Lido',
61+
logoSrc: 'https://pbs.twimg.com/profile_images/1721880644345622528/G2czctJJ_400x400.jpg',
62+
description:
63+
"The Lido DAO governs key parameters of Ethereum's largest liquid staking protocol using the voting power of LDO.",
64+
network: 'Ethereum',
65+
href: 'https://vote.lido.fi/',
66+
target: '_blank',
67+
isExternal: true,
68+
},
69+
};
70+
5671
export default meta;

src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.test.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { render, screen } from '@testing-library/react';
2+
import { IconType } from '../../../../../core';
3+
import { addressUtils } from '../../../../utils';
24
import { DaoDataListItemStructure, type IDaoDataListItemStructureProps } from './daoDataListItemStructure';
35

46
describe('<DaoDataListItemStructure /> component', () => {
@@ -10,20 +12,20 @@ describe('<DaoDataListItemStructure /> component', () => {
1012
return <DaoDataListItemStructure {...completeProps} />;
1113
};
1214

13-
it('renders ensName and the daoName (in uppercase) as the avatar fallback', () => {
15+
it('renders the dao ens name and its name in uppercase as avatar fallback', () => {
1416
const name = 'a';
1517
const ens = 'a.eth';
1618
render(createTestComponent({ name, ens }));
1719
expect(screen.getByText(name.toUpperCase())).toBeInTheDocument();
1820
expect(screen.getByText(ens)).toBeInTheDocument();
1921
});
2022

21-
it('renders name and the address', () => {
23+
it('renders the dao name and its address', () => {
2224
const name = 'ab';
23-
const address = '0x123';
25+
const address = '0xc6B61B776367b236648399ACF4A0bc5aDe70708F';
2426
render(createTestComponent({ name, address }));
2527
expect(screen.getByText(name.toUpperCase())).toBeInTheDocument();
26-
expect(screen.getByText(address)).toBeInTheDocument();
28+
expect(screen.getByText(addressUtils.truncateAddress(address))).toBeInTheDocument();
2729
});
2830

2931
it('does not render the dao ENS name if it is not provided', () => {
@@ -45,4 +47,10 @@ describe('<DaoDataListItemStructure /> component', () => {
4547
render(createTestComponent({ network }));
4648
expect(screen.getByText(network)).toBeInTheDocument();
4749
});
50+
51+
it('displays an external link icon when the isExternal property is set to true', () => {
52+
const isExternal = true;
53+
render(createTestComponent({ isExternal }));
54+
expect(screen.getByTestId(IconType.LINK_EXTERNAL)).toBeInTheDocument();
55+
});
4856
});

src/modules/components/dao/daoDataListItem/daoDataListItemStructure/daoDataListItemStructure.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type React from 'react';
2-
import { DataList, Heading, Icon, IconType, type IDataListItemProps } from '../../../../../core';
2+
import { AvatarIcon, DataList, Heading, Icon, IconType, type IDataListItemProps } from '../../../../../core';
3+
import { addressUtils } from '../../../../utils';
34
import { DaoAvatar } from '../../daoAvatar';
45

56
export type IDaoDataListItemStructureProps = IDataListItemProps & {
@@ -27,10 +28,16 @@ export type IDaoDataListItemStructureProps = IDataListItemProps & {
2728
* The network on which the DAO operates.
2829
*/
2930
network?: string;
31+
/**
32+
* Displays an external link icon and updates the information shown when set to true.
33+
*/
34+
isExternal?: boolean;
3035
};
3136

3237
export const DaoDataListItemStructure: React.FC<IDaoDataListItemStructureProps> = (props) => {
33-
const { name, logoSrc, description, network, address, ens, ...otherProps } = props;
38+
const { name, logoSrc, description, network, address, ens, isExternal, ...otherProps } = props;
39+
40+
const truncatedAddress = addressUtils.truncateAddress(address);
3441

3542
return (
3643
<DataList.Item className="grid gap-y-3 py-4 md:gap-y-4 md:py-6" {...otherProps}>
@@ -40,15 +47,18 @@ export const DaoDataListItemStructure: React.FC<IDaoDataListItemStructureProps>
4047
{name}
4148
</Heading>
4249
<Heading size="h5" as="h3" className="truncate">
43-
{ens ?? address}
50+
{ens ?? truncatedAddress}
4451
</Heading>
4552
</div>
4653
<DaoAvatar name={name} src={logoSrc} size="md" responsiveSize={{ md: 'lg' }} />
4754
</div>
4855
<p className="line-clamp-2 text-base leading-normal text-neutral-500 md:text-lg">{description}</p>
49-
<div className="mt-1 flex items-center gap-x-1 text-neutral-400 md:mt-0 md:gap-x-2">
50-
<span className="text-sm capitalize leading-tight md:text-base">{network}</span>
51-
<Icon icon={IconType.BLOCKCHAIN_BLOCKCHAIN} size="sm" responsiveSize={{ md: 'md' }} />
56+
<div className="flex flex-row justify-between">
57+
<div className="mt-1 flex items-center gap-x-1 text-neutral-400 md:mt-0 md:gap-x-2">
58+
<span className="text-sm capitalize leading-tight md:text-base">{network}</span>
59+
<Icon icon={IconType.BLOCKCHAIN_BLOCKCHAIN} size="sm" responsiveSize={{ md: 'md' }} />
60+
</div>
61+
{isExternal && <AvatarIcon size="sm" variant="primary" icon={IconType.LINK_EXTERNAL} />}
5262
</div>
5363
</DataList.Item>
5464
);

0 commit comments

Comments
 (0)