Skip to content

Commit 00e81a1

Browse files
[DSRN] Aligned AvatarAccount (#606)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR updates the `AvatarAccount` component in the `@metamask/design-system-react-native` package - added jazziconProps, blockiesProps, maskiconProps - updated tests - updated descriptions and README <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Related issues** Fixes: #590 ## **Manual testing steps** 1. Run `yarn storybook:ios` from root 2. Check to make sure AvatarAccount is still functional 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/a811d973-097e-4817-9921-6fce7eb06e6b <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Co-authored-by: George Marshall <[email protected]>
1 parent af515b7 commit 00e81a1

File tree

4 files changed

+91
-14
lines changed

4 files changed

+91
-14
lines changed

packages/design-system-react-native/src/components/AvatarAccount/AvatarAccount.test.tsx

+25-8
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,28 @@ import { AvatarAccountSize, AvatarAccountVariant } from '../../types';
55
import AvatarAccount from './AvatarAccount';
66
import { SAMPLE_AVATARACCOUNT_ADDRESSES } from './AvatarAccount.constants';
77

8+
jest.mock('react-native-svg', () => {
9+
const React = require('react');
10+
return {
11+
SvgXml: (props: any) => React.createElement('SvgXml', props, props.xml),
12+
};
13+
});
14+
jest.mock('react-native-jazzicon', () => {
15+
return jest.fn(() => null);
16+
});
17+
818
describe('AvatarAccount', () => {
9-
it('renders Jazzicon by default when no variant is provided', () => {
19+
it('renders Jazzicon by default when no variant is provided', async () => {
1020
const address = SAMPLE_AVATARACCOUNT_ADDRESSES[0];
1121

12-
const { getByTestId } = render(<AvatarAccount address={address} />);
13-
14-
expect(getByTestId('jazzicon')).toBeTruthy();
22+
const { findByTestId } = render(
23+
<AvatarAccount
24+
address={address}
25+
jazziconProps={{ testID: 'jazzicon' }}
26+
/>,
27+
);
28+
const jazzicon = await findByTestId('jazzicon');
29+
expect(jazzicon).toBeTruthy();
1530
});
1631

1732
it('renders Blockies when variant is blockies', () => {
@@ -21,6 +36,7 @@ describe('AvatarAccount', () => {
2136
<AvatarAccount
2237
address={address}
2338
variant={AvatarAccountVariant.Blockies}
39+
blockiesProps={{ testID: 'blockies' }}
2440
/>,
2541
);
2642

@@ -34,7 +50,7 @@ describe('AvatarAccount', () => {
3450
<AvatarAccount
3551
address={address}
3652
variant={AvatarAccountVariant.Maskicon}
37-
testID="maskicon"
53+
maskiconProps={{ testID: 'maskicon' }}
3854
/>,
3955
);
4056

@@ -57,17 +73,18 @@ describe('AvatarAccount', () => {
5773
);
5874
});
5975

60-
it('overrides the size if provided', () => {
76+
it('overrides the size if provided', async () => {
6177
const address = SAMPLE_AVATARACCOUNT_ADDRESSES[0];
62-
const { getByTestId } = render(
78+
const { findByTestId, getByTestId } = render(
6379
<AvatarAccount
6480
address={address}
6581
size={AvatarAccountSize.Xl}
6682
testID="avatar-account"
83+
jazziconProps={{ testID: 'jazzicon' }}
6784
/>,
6885
);
6986

70-
const jazzicon = getByTestId('jazzicon');
87+
const jazzicon = await findByTestId('jazzicon');
7188
expect(jazzicon).toBeTruthy();
7289
const avatarAccount = getByTestId('avatar-account');
7390
expect(avatarAccount).toBeDefined();

packages/design-system-react-native/src/components/AvatarAccount/AvatarAccount.tsx

+12-5
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,39 @@ const AvatarAccount = ({
1616
address,
1717
variant = AvatarAccountVariant.Jazzicon,
1818
size = AvatarAccountSize.Md,
19-
shape = AvatarBaseShape.Circle,
19+
blockiesProps,
20+
jazziconProps,
21+
maskiconProps,
2022
...props
2123
}: AvatarAccountProps) => {
2224
let AvatarArtComponent;
2325

2426
switch (variant) {
2527
case AvatarAccountVariant.Blockies:
2628
AvatarArtComponent = (
27-
<Blockies address={address} size={Number(size)} testID="blockies" />
29+
<Blockies address={address} size={Number(size)} {...blockiesProps} />
2830
);
2931
break;
3032
case AvatarAccountVariant.Maskicon:
3133
AvatarArtComponent = (
32-
<Maskicon address={address} size={Number(size)} testID="maskicon" />
34+
<Maskicon address={address} size={Number(size)} {...maskiconProps} />
3335
);
3436
break;
3537
case AvatarAccountVariant.Jazzicon:
3638
default:
3739
AvatarArtComponent = (
38-
<Jazzicon address={address} size={Number(size)} testID="jazzicon" />
40+
<Jazzicon address={address} size={Number(size)} {...jazziconProps} />
3941
);
4042
break;
4143
}
4244

4345
return (
44-
<AvatarBase size={size} shape={shape} accessibilityRole="image" {...props}>
46+
<AvatarBase
47+
size={size}
48+
shape={AvatarBaseShape.Circle}
49+
accessibilityRole="image"
50+
{...props}
51+
>
4552
{AvatarArtComponent}
4653
</AvatarBase>
4754
);

packages/design-system-react-native/src/components/AvatarAccount/AvatarAccount.types.ts

+15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { AvatarAccountVariant } from '../../types';
22
import { AvatarBaseProps } from '../AvatarBase';
3+
import { BlockiesProps } from '../temp-components/Blockies';
4+
import { JazziconProps } from '../temp-components/Jazzicon';
5+
import { MaskiconProps } from '../temp-components/Maskicon';
36

47
/**
58
* AvatarAccount component props.
@@ -14,4 +17,16 @@ export type AvatarAccountProps = {
1417
* @default AvatarAccountVariant.Jazzicon
1518
*/
1619
variant?: AvatarAccountVariant;
20+
/**
21+
* Optional props to be passed to the Blockies component
22+
*/
23+
blockiesProps?: Partial<BlockiesProps>;
24+
/**
25+
* Optional props to be passed to the Jazzicon component
26+
*/
27+
jazziconProps?: Partial<JazziconProps>;
28+
/**
29+
* Optional props to be passed to the Maskicon component
30+
*/
31+
maskiconProps?: Partial<MaskiconProps>;
1732
} & Omit<AvatarBaseProps, 'children' | 'fallbackText' | 'fallbackTextProps'>;

packages/design-system-react-native/src/components/AvatarAccount/README.md

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# AvatarAccount
22

3-
The `AvatarAccount` component is reserved for representing accounts inside of an avatar. It extends the functionality of [`AvatarBase`](../AvatarBase/) by incorporating an Account and severity levels, making it useful for visually representing statuses, alerts, or simply user avatars with Accounts.
3+
The `AvatarAccount` component is reserved for representing accounts inside of an avatar.
4+
5+
_Developer Note: It extends the functionality of [`AvatarBase`](../AvatarBase/) by incorporating an Account and severity levels, making it useful for visually representing statuses, alerts, or simply user avatars with Accounts._
46

57
---
68

@@ -32,6 +34,42 @@ Required address used as a unique identifier to generate the AvatarAccount art.
3234

3335
---
3436

37+
### `blockiesProps`
38+
39+
Optional props to be passed to the `Blockies` component when the variant is `Blockies`.
40+
41+
| TYPE | REQUIRED | DEFAULT |
42+
| ------------------------ | -------- | ----------- |
43+
| `Partial<BlockiesProps>` | No | `undefined` |
44+
45+
Used to customize the `Blockies` identicon, such as block size or color settings.
46+
47+
---
48+
49+
### `jazziconProps`
50+
51+
Optional props to be passed to the `Jazzicon` component when the variant is `Jazzicon`.
52+
53+
| TYPE | REQUIRED | DEFAULT |
54+
| ------------------------ | -------- | ----------- |
55+
| `Partial<JazziconProps>` | No | `undefined` |
56+
57+
Used to customize the `Jazzicon` identicon, such as diameter or address seed.
58+
59+
---
60+
61+
### `maskiconProps`
62+
63+
Optional props to be passed to the `Maskicon` component itself.
64+
65+
| TYPE | REQUIRED | DEFAULT |
66+
| ------------------------ | -------- | ----------- |
67+
| `Partial<MaskiconProps>` | No | `undefined` |
68+
69+
Useful for forwarding additional `SvgProps`, accessibility attributes, or animation styles.
70+
71+
---
72+
3573
### Other Props
3674

3775
`AvatarAccount` supports all props from [`AvatarBase`](#) except `children`, `fallbackText`, and `fallbackTextProps`. This includes:

0 commit comments

Comments
 (0)