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

converted Jazzicon component to functional component and added story #15638

Merged
merged 10 commits into from
Sep 8, 2022
15 changes: 15 additions & 0 deletions ui/components/ui/jazzicon/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';

import Jazzicon from './jazzicon.component';

# Jazzicon

Jazzicon uses the [jazzicon library](https://github.com/MetaMask/jazzicon) to create a graphic identity of an ethereum address

<Canvas>
<Story id="ui-components-ui-jazzicon-jazzicon-stories-js--default-story" />
</Canvas>

## Props

<ArgsTable of={Jazzicon} />
95 changes: 50 additions & 45 deletions ui/components/ui/jazzicon/jazzicon.component.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { createRef, PureComponent } from 'react';
import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import jazzicon from '@metamask/jazzicon';
import iconFactoryGenerator from '../../../helpers/utils/icon-factory';
Expand All @@ -9,56 +9,61 @@ const iconFactory = iconFactoryGenerator(jazzicon);
* Wrapper around the jazzicon library to return a React component, as the library returns an
* HTMLDivElement which needs to be appended.
*/
export default class Jazzicon extends PureComponent {
static propTypes = {
address: PropTypes.string.isRequired,
className: PropTypes.string,
diameter: PropTypes.number,
style: PropTypes.object,
tokenList: PropTypes.object,
};

static defaultProps = {
diameter: 46,
};
function Jazzicon({
address,
className,
diameter = 46,
style,
tokenList = {},
}) {
const container = useRef();

container = createRef();
useEffect(() => {
const _container = container.current;

componentDidMount() {
this.appendJazzicon();
}

componentDidUpdate(prevProps) {
const { address: prevAddress, diameter: prevDiameter } = prevProps;
const { address, diameter } = this.props;

if (address !== prevAddress || diameter !== prevDiameter) {
this.removeExistingChildren();
this.appendJazzicon();
}
}

removeExistingChildren() {
const { children } = this.container.current;

for (let i = 0; i < children.length; i++) {
this.container.current.removeChild(children[i]);
}
}

appendJazzicon() {
const { address, diameter, tokenList } = this.props;
const image = iconFactory.iconForAddress(
// add icon
const imageNode = iconFactory.iconForAddress(
address,
diameter,
tokenList[address.toLowerCase()],
tokenList[address?.toLowerCase()],
);
this.container.current.appendChild(image);
}

render() {
const { className, style } = this.props;
_container?.appendChild(imageNode);

// remove icon
return () => {
while (_container.firstChild) {
_container.firstChild.remove();
}
};
}, [address, diameter, tokenList]);

return <div className={className} ref={this.container} style={style} />;
}
return <div ref={container} className={className} style={style} />;
}

Jazzicon.propTypes = {
/**
* Address used for generating random image
*/
address: PropTypes.string.isRequired,
/**
* Add custom css class
*/
className: PropTypes.string,
/**
* Sets the width and height of the inner img element
* Jazzicon accepts a pixel diameter
*/
diameter: PropTypes.number,
/**
* Add inline style for the component
*/
style: PropTypes.object,
/**
* Add list of token in object
*/
tokenList: PropTypes.object,
};

export default Jazzicon;
28 changes: 28 additions & 0 deletions ui/components/ui/jazzicon/jazzicon.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import README from './README.mdx';
import Jazzicon from './jazzicon.component';

export default {
title: 'Components/UI/Jazzicon',
id: __filename,
component: Jazzicon,
parameters: {
docs: {
page: README,
},
},
argTypes: {
address: { control: 'text' },
className: { control: 'text' },
diameter: { control: 'number' },
tokenList: { control: 'object' },
},
};

export const DefaultStory = (args) => <Jazzicon {...args} />;

DefaultStory.storyName = 'Default';
DefaultStory.args = {
address: '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1',
diameter: 32,
};