mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add tx list-item component (#8195)
* Add tx list-item component New list item compoent for transaction history * Simplify component logic and remove type checks * Address remaining feedback * Remove extra line * Place className prop on its own line * Rename to primaryCurrency and secondaryCurrency * Make the title `isRequired` * Fix no-undef * Remove more + buttons to be implemented in seperate PR * Add minimal store and I18nProvider to storybook * Use Component to support translations * Add `metamask` to store * Rename decorator
This commit is contained in:
parent
4d38a59182
commit
8ba35f673e
@ -1,7 +1,11 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { addDecorator, addParameters } from '@storybook/react'
|
import { addDecorator, addParameters } from '@storybook/react'
|
||||||
import { withKnobs } from '@storybook/addon-knobs/react'
|
import { withKnobs } from '@storybook/addon-knobs/react'
|
||||||
|
import I18nProvider from '../ui/app/helpers/higher-order-components/i18n-provider'
|
||||||
|
import { Provider } from 'react-redux'
|
||||||
|
import configureStore from '../ui/app/store/store'
|
||||||
import '../ui/app/css/index.scss'
|
import '../ui/app/css/index.scss'
|
||||||
|
import en from '../app/_locales/en/messages'
|
||||||
|
|
||||||
addParameters({
|
addParameters({
|
||||||
backgrounds: [
|
backgrounds: [
|
||||||
@ -17,11 +21,24 @@ const styles = {
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
}
|
}
|
||||||
|
|
||||||
const CenterDecorator = story => (
|
const store = configureStore({
|
||||||
|
metamask: { metamask: { currentLocale: 'en' } },
|
||||||
|
|
||||||
|
localeMessages: {
|
||||||
|
current: en,
|
||||||
|
en: en,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const metamaskDecorator = story => (
|
||||||
|
<Provider store={store}>
|
||||||
|
<I18nProvider>
|
||||||
<div style={styles}>
|
<div style={styles}>
|
||||||
{ story() }
|
{ story() }
|
||||||
</div>
|
</div>
|
||||||
|
</I18nProvider>
|
||||||
|
</Provider>
|
||||||
)
|
)
|
||||||
|
|
||||||
addDecorator(withKnobs)
|
addDecorator(withKnobs)
|
||||||
addDecorator(CenterDecorator)
|
addDecorator(metamaskDecorator)
|
||||||
|
3
ui/app/components/ui/list-item/index.js
Normal file
3
ui/app/components/ui/list-item/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import ListItem from './list-item.component'
|
||||||
|
|
||||||
|
export default ListItem
|
64
ui/app/components/ui/list-item/index.scss
Normal file
64
ui/app/components/ui/list-item/index.scss
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
.list-item {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 374px;
|
||||||
|
min-height: 86px;
|
||||||
|
margin: 0 20px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
padding: 24px 16px;
|
||||||
|
@extend %font;
|
||||||
|
border-top: 1px solid $mercury;
|
||||||
|
border-bottom: 1px solid $mercury;
|
||||||
|
color: $Grey-500;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
margin: 8px 14px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__col {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__heading {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 160%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&-wrap {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__subheading {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__status {
|
||||||
|
&--unapproved {
|
||||||
|
color: $flamingo;
|
||||||
|
}
|
||||||
|
&--failed {
|
||||||
|
color: $valencia;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__approved {
|
||||||
|
.list-item__heading {
|
||||||
|
color: $shark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__amount {
|
||||||
|
margin: 0 0 0 auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
138
ui/app/components/ui/list-item/list-item.component.js
Normal file
138
ui/app/components/ui/list-item/list-item.component.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
import React, { Component } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import Approve from '../icon/approve-icon.component'
|
||||||
|
import Interaction from '../icon/interaction-icon.component'
|
||||||
|
import Preloader from '../icon/preloader'
|
||||||
|
import Send from '../icon/send-icon.component'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
|
||||||
|
const SendIcon = () => (
|
||||||
|
<Send
|
||||||
|
className="list-item__icon"
|
||||||
|
size={28}
|
||||||
|
color="#2F80ED"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const InteractionIcon = () => (
|
||||||
|
<Interaction
|
||||||
|
className="list-item__icon"
|
||||||
|
size={28}
|
||||||
|
color="#2F80ED"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const ApproveIcon = () => (
|
||||||
|
<Approve
|
||||||
|
className="list-item__icon"
|
||||||
|
size={28}
|
||||||
|
color="#2F80ED"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const FailIcon = () => (
|
||||||
|
<Interaction
|
||||||
|
className="list-item__icon"
|
||||||
|
size={28}
|
||||||
|
color="#D73A49"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default class ListItem extends Component {
|
||||||
|
static contextTypes = {
|
||||||
|
t: PropTypes.func,
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
status: PropTypes.string,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
subtitle: PropTypes.string,
|
||||||
|
children: PropTypes.node,
|
||||||
|
primaryCurrency: PropTypes.string,
|
||||||
|
secondaryCurrency: PropTypes.string,
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
status: 'pending',
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const {
|
||||||
|
className,
|
||||||
|
status,
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
children,
|
||||||
|
primaryCurrency,
|
||||||
|
secondaryCurrency,
|
||||||
|
} = this.props
|
||||||
|
const { t } = this.context
|
||||||
|
|
||||||
|
const isApproved = status === 'approved'
|
||||||
|
const isUnapproved = status === 'unapproved'
|
||||||
|
const isPending = status === 'pending'
|
||||||
|
const isFailed = status === 'failed'
|
||||||
|
|
||||||
|
let icon = <InteractionIcon />
|
||||||
|
if (isApproved) {
|
||||||
|
icon = <ApproveIcon />
|
||||||
|
} else if (isPending) {
|
||||||
|
icon = <SendIcon />
|
||||||
|
} else if (isFailed) {
|
||||||
|
icon = <FailIcon />
|
||||||
|
}
|
||||||
|
|
||||||
|
let subtitleStatus = null
|
||||||
|
if (isUnapproved) {
|
||||||
|
subtitleStatus = (
|
||||||
|
<span><span className="list-item__status--unapproved">{t('unapproved')}</span> · </span>
|
||||||
|
)
|
||||||
|
} else if (isFailed) {
|
||||||
|
subtitleStatus = (
|
||||||
|
<span><span className="list-item__status--failed">{t('failed')}</span> · </span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={className}>
|
||||||
|
<div className="list-item__col">
|
||||||
|
{ icon }
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={classnames('list-item__col', {
|
||||||
|
'list-item__approved': isApproved,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<h2 className="list-item__heading">
|
||||||
|
{ title } {isPending && (
|
||||||
|
<span className="list-item__heading-wrap">
|
||||||
|
<Preloader
|
||||||
|
size={16}
|
||||||
|
color="#D73A49"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</h2>
|
||||||
|
<h3 className="list-item__subheading">
|
||||||
|
{subtitleStatus}
|
||||||
|
{subtitle}
|
||||||
|
</h3>
|
||||||
|
{children && (
|
||||||
|
<div className="list-item__more">
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={classnames('list-item__col list-item__amount', {
|
||||||
|
'list-item__approved': isApproved,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<h2 className="list-item__heading">{primaryCurrency}</h2>
|
||||||
|
<h3 className="list-item__subheading">{secondaryCurrency}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
51
ui/app/components/ui/list-item/list-item.stories.js
Normal file
51
ui/app/components/ui/list-item/list-item.stories.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import ListItem from './list-item.component'
|
||||||
|
import { text } from '@storybook/addon-knobs/react'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'ListItem',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const send = () => (
|
||||||
|
<ListItem
|
||||||
|
title={text('title', 'Send DAI')}
|
||||||
|
className="list-item"
|
||||||
|
status="pending"
|
||||||
|
subtitle={text('subtitle', 'Sept 20 · To: 00X4...3058')}
|
||||||
|
primaryCurrency={text('primaryCurrency', '- 0.0732 DAI')}
|
||||||
|
secondaryCurrency={text('secondaryCurrency', '- $6.04 USD')}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const pending = () => (
|
||||||
|
<ListItem
|
||||||
|
title={text('title', 'Hatch Turtles')}
|
||||||
|
className="list-item"
|
||||||
|
status="unapproved"
|
||||||
|
subtitle={text('subtitle', 'Turtlefarm.com')}
|
||||||
|
primaryCurrency={text('primaryCurrency', '- 0.0732 ETH')}
|
||||||
|
secondaryCurrency={text('secondaryCurrency', '- $6.00 USD')}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const approve = () => (
|
||||||
|
<ListItem
|
||||||
|
title={text('title', 'Approve spend limit')}
|
||||||
|
className="list-item"
|
||||||
|
status="approved"
|
||||||
|
subtitle={text('subtitle', 'Sept 20 · oxuniverse.com')}
|
||||||
|
primaryCurrency={text('primaryCurrency', '0.00070 DAI')}
|
||||||
|
secondaryCurrency={text('secondaryCurrency', '$0.02 USD')}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
export const failed = () => (
|
||||||
|
<ListItem
|
||||||
|
title={text('title', 'Hatch Turtles')}
|
||||||
|
className="list-item"
|
||||||
|
status="failed"
|
||||||
|
subtitle={text('subtitle', 'Turtlefarm.com')}
|
||||||
|
primaryCurrency={text('primaryCurrency', '- 0.0732 ETH')}
|
||||||
|
secondaryCurrency={text('secondaryCurrency', '- $6.00 USD')}
|
||||||
|
/>
|
||||||
|
)
|
@ -1,6 +1,7 @@
|
|||||||
@import '../../../components/ui/button/buttons';
|
@import '../../../components/ui/button/buttons';
|
||||||
@import '../../../components/ui/dialog/dialog';
|
@import '../../../components/ui/dialog/dialog';
|
||||||
@import '../../../components/ui/snackbar/index';
|
@import '../../../components/ui/snackbar/index';
|
||||||
|
@import '../../../components/ui/list-item/index';
|
||||||
@import '../../../components/ui/icon/preloader/index';
|
@import '../../../components/ui/icon/preloader/index';
|
||||||
|
|
||||||
@import './footer.scss';
|
@import './footer.scss';
|
||||||
|
@ -17,6 +17,8 @@ $white-linen: #faf6f0; // formerly 'faint orange (textfield shades)'
|
|||||||
$rajah: #f5c26d; // formerly 'light orange (button shades)'
|
$rajah: #f5c26d; // formerly 'light orange (button shades)'
|
||||||
$buttercup: #f5a623; // formerly 'dark orange (text)'
|
$buttercup: #f5a623; // formerly 'dark orange (text)'
|
||||||
$tundora: #4a4a4a; // formerly 'borders/font/any gray'
|
$tundora: #4a4a4a; // formerly 'borders/font/any gray'
|
||||||
|
$flamingo: #F56821;
|
||||||
|
$valencia: #D73A49;
|
||||||
$gallery: #efefef;
|
$gallery: #efefef;
|
||||||
$alabaster: #f7f7f7;
|
$alabaster: #f7f7f7;
|
||||||
$shark: #22232c;
|
$shark: #22232c;
|
||||||
@ -60,6 +62,8 @@ $polar: #fafcfe;
|
|||||||
$blizzard-blue: #bfdef3;
|
$blizzard-blue: #bfdef3;
|
||||||
$mischka: #dddee9;
|
$mischka: #dddee9;
|
||||||
$web-orange: #f2a202;
|
$web-orange: #f2a202;
|
||||||
|
$mercury: #E5E5E5;
|
||||||
|
$lochmara: #037DD6;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
notification and error message colors
|
notification and error message colors
|
||||||
|
Loading…
Reference in New Issue
Block a user