1 import { useState } from 'react';
3 import { c, msgid } from 'ttag';
5 import { Button } from '@proton/atoms';
6 import Icon from '@proton/components/components/icon/Icon';
7 import type { PartialMemberAddress } from '@proton/shared/lib/interfaces';
8 import clsx from '@proton/utils/clsx';
10 const amountOfDisplayedAddresses = 3;
12 interface MemberAddressesProps {
13 addresses: PartialMemberAddress[] | undefined;
16 const MemberAddresses = ({ addresses = [] }: MemberAddressesProps) => {
17 const [expanded, setExpanded] = useState(false);
19 const handleExpandClick = () => {
23 const amountOfAddresses = addresses.length;
25 const renderListItem = ({ ID, Email }: PartialMemberAddress, index: number) => {
27 * By default, the addresses list shows 3 addresses as well as
28 * a clickable text saying "x more addresses", which, when clicked,
29 * expands the addresses list and shows all addresses.
31 * While not expanded the last list-item is colored more lightly as
32 * if to indicate a fade.
34 const isLastDisplayedAddress = index === amountOfDisplayedAddresses - 1;
36 const displayAsFade = !expanded && isLastDisplayedAddress && amountOfAddresses > amountOfDisplayedAddresses;
38 const listItemClassName = clsx([displayAsFade && 'color-weak', 'my-2']);
41 <li key={ID} className={listItemClassName}>
43 className="text-ellipsis block"
45 data-testid="users-and-addresses-table:memberAddress"
53 const initiallyDisplayedAddresses = addresses.slice(0, amountOfDisplayedAddresses).map(renderListItem);
55 const remainingAddresses = addresses.slice(amountOfDisplayedAddresses).map(renderListItem);
57 const getAddressesListItems = () => {
58 if (amountOfAddresses === 0) {
59 let n = amountOfAddresses;
62 <span className="md:hidden">{n}</span>
63 <span className="hidden md:inline">
65 // translator: addresses mean "email addresses" in this context
66 c('Info').ngettext(msgid`${n} address`, `${n} addresses`, n)
74 return [...initiallyDisplayedAddresses, ...remainingAddresses];
77 if (remainingAddresses.length > 0) {
78 const expandButton = (
79 <li key="expand" className="mb-2">
81 onClick={handleExpandClick}
85 className="flex flex-nowrap text-left items-center"
87 <span className="md:hidden">
89 // translator: we speak about email addresses in this context
91 msgid`${remainingAddresses.length} more`,
92 `${remainingAddresses.length} more`,
93 remainingAddresses.length
97 <span className="hidden md:inline">
99 // translator: addresses mean email addresses in this context
101 msgid`${remainingAddresses.length} more address`,
102 `${remainingAddresses.length} more addresses`,
103 remainingAddresses.length
107 <Icon size={3} className="ml-1" name="chevron-down" />
112 return [...initiallyDisplayedAddresses, expandButton];
115 return initiallyDisplayedAddresses;
119 <ul className="unstyled my-custom" style={{ '--my-custom': 'calc(var(--space-2) * -1)' }}>
120 {getAddressesListItems()}
125 export default MemberAddresses;