Merge pull request #746 from 0xProject/feature/website/relayer-grid-polish
Relayer grid polish
This commit is contained in:
@@ -42,7 +42,11 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
||||
onboardingElement = <Animation type="easeUpFromBottom">{this._renderOnboardignCard()}</Animation>;
|
||||
} else {
|
||||
onboardingElement = (
|
||||
<Popper referenceElement={this._getElementForStep()} placement={this._getCurrentStep().placement}>
|
||||
<Popper
|
||||
referenceElement={this._getElementForStep()}
|
||||
placement={this._getCurrentStep().placement}
|
||||
positionFixed={true}
|
||||
>
|
||||
{this._renderPopperChildren.bind(this)}
|
||||
</Popper>
|
||||
);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { colors, constants as sharedConstants, Styles } from '@0xproject/react-shared';
|
||||
import { colors, constants as sharedConstants } from '@0xproject/react-shared';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet';
|
||||
@@ -107,26 +107,7 @@ const TOP_BAR_HEIGHT = TopBar.heightForDisplayType(TopBarDisplayType.Expanded);
|
||||
const LEFT_COLUMN_WIDTH = 346;
|
||||
const MENU_PADDING_LEFT = 185;
|
||||
const LARGE_LAYOUT_MAX_WIDTH = 1200;
|
||||
|
||||
const styles: Styles = {
|
||||
root: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: colors.lightestGrey,
|
||||
},
|
||||
body: {
|
||||
height: `calc(100vh - ${TOP_BAR_HEIGHT}px)`,
|
||||
},
|
||||
leftColumn: {
|
||||
width: LEFT_COLUMN_WIDTH,
|
||||
height: '100%',
|
||||
},
|
||||
scrollContainer: {
|
||||
height: `calc(100vh - ${TOP_BAR_HEIGHT}px)`,
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
overflow: 'auto',
|
||||
},
|
||||
};
|
||||
const LARGE_LAYOUT_MARGIN = 30;
|
||||
|
||||
export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
private _blockchain: Blockchain;
|
||||
@@ -245,7 +226,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
? TokenVisibility.UNTRACKED
|
||||
: TokenVisibility.TRACKED;
|
||||
return (
|
||||
<div style={styles.root}>
|
||||
<Container>
|
||||
<DocumentTitle title="0x Portal DApp" />
|
||||
<TopBar
|
||||
userAddress={this.props.userAddress}
|
||||
@@ -259,10 +240,15 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
blockchain={this._blockchain}
|
||||
translate={this.props.translate}
|
||||
displayType={TopBarDisplayType.Expanded}
|
||||
style={{ backgroundColor: colors.lightestGrey }}
|
||||
style={{
|
||||
backgroundColor: colors.lightestGrey,
|
||||
position: 'fixed',
|
||||
// Hack: used to make onboarding z-index logic work for both mobile and desktop
|
||||
zIndex: utils.isMobile(this.props.screenWidth) ? zIndex.topBar : undefined,
|
||||
}}
|
||||
maxWidth={LARGE_LAYOUT_MAX_WIDTH}
|
||||
/>
|
||||
<div id="portal" style={styles.body}>
|
||||
<Container marginTop={TOP_BAR_HEIGHT} minHeight="100vh" backgroundColor={colors.lightestGrey}>
|
||||
<Switch>
|
||||
<Route path={`${WebsitePaths.Portal}/:route`} render={this._renderOtherRoutes.bind(this)} />
|
||||
<Route
|
||||
@@ -301,13 +287,8 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
tokenByAddress={this.props.tokenByAddress}
|
||||
tokenVisibility={tokenVisibility}
|
||||
/>
|
||||
</div>
|
||||
<PortalOnboardingFlow
|
||||
blockchain={this._blockchain}
|
||||
trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
|
||||
refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
private _renderMainRoute(): React.ReactNode {
|
||||
@@ -341,41 +322,48 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
}
|
||||
private _renderWallet(): React.ReactNode {
|
||||
const startOnboarding = this._renderStartOnboarding();
|
||||
const isMobile = this.props.screenWidth === ScreenWidths.Sm;
|
||||
const isMobile = utils.isMobile(this.props.screenWidth);
|
||||
// We need room to scroll down for mobile onboarding
|
||||
const marginBottom = isMobile ? '200px' : '15px';
|
||||
return (
|
||||
<div>
|
||||
{isMobile && <Container marginBottom="15px">{startOnboarding}</Container>}
|
||||
<Container marginBottom={marginBottom}>
|
||||
<Wallet
|
||||
style={
|
||||
!isMobile && this.props.isPortalOnboardingShowing
|
||||
? { zIndex: zIndex.aboveOverlay, position: 'relative' }
|
||||
: undefined
|
||||
}
|
||||
userAddress={this.props.userAddress}
|
||||
networkId={this.props.networkId}
|
||||
blockchain={this._blockchain}
|
||||
blockchainIsLoaded={this.props.blockchainIsLoaded}
|
||||
blockchainErr={this.props.blockchainErr}
|
||||
dispatcher={this.props.dispatcher}
|
||||
tokenByAddress={this.props.tokenByAddress}
|
||||
trackedTokens={this._getCurrentTrackedTokens()}
|
||||
userEtherBalanceInWei={this.props.userEtherBalanceInWei}
|
||||
lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
|
||||
injectedProviderName={this.props.injectedProviderName}
|
||||
providerType={this.props.providerType}
|
||||
screenWidth={this.props.screenWidth}
|
||||
location={this.props.location}
|
||||
trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
|
||||
onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
|
||||
onAddToken={this._onAddToken.bind(this)}
|
||||
onRemoveToken={this._onRemoveToken.bind(this)}
|
||||
refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
|
||||
/>
|
||||
<Container>
|
||||
{isMobile && <Container marginBottom="15px">{startOnboarding}</Container>}
|
||||
<Container marginBottom={marginBottom}>
|
||||
<Wallet
|
||||
style={
|
||||
!isMobile && this.props.isPortalOnboardingShowing
|
||||
? { zIndex: zIndex.aboveOverlay, position: 'relative' }
|
||||
: undefined
|
||||
}
|
||||
userAddress={this.props.userAddress}
|
||||
networkId={this.props.networkId}
|
||||
blockchain={this._blockchain}
|
||||
blockchainIsLoaded={this.props.blockchainIsLoaded}
|
||||
blockchainErr={this.props.blockchainErr}
|
||||
dispatcher={this.props.dispatcher}
|
||||
tokenByAddress={this.props.tokenByAddress}
|
||||
trackedTokens={this._getCurrentTrackedTokens()}
|
||||
userEtherBalanceInWei={this.props.userEtherBalanceInWei}
|
||||
lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
|
||||
injectedProviderName={this.props.injectedProviderName}
|
||||
providerType={this.props.providerType}
|
||||
screenWidth={this.props.screenWidth}
|
||||
location={this.props.location}
|
||||
trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
|
||||
onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
|
||||
onAddToken={this._onAddToken.bind(this)}
|
||||
onRemoveToken={this._onRemoveToken.bind(this)}
|
||||
refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
|
||||
/>
|
||||
</Container>
|
||||
{!isMobile && <Container marginTop="15px">{startOnboarding}</Container>}
|
||||
</Container>
|
||||
{!isMobile && <Container marginTop="15px">{startOnboarding}</Container>}
|
||||
<PortalOnboardingFlow
|
||||
blockchain={this._blockchain}
|
||||
trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
|
||||
refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -551,7 +539,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
private _renderRelayerIndexSection(): React.ReactNode {
|
||||
return (
|
||||
<Section
|
||||
header={<TextHeader labelText="Explore 0x Relayers" />}
|
||||
header={<TextHeader labelText="0x Relayers" />}
|
||||
body={<RelayerIndex networkId={this.props.networkId} screenWidth={this.props.screenWidth} />}
|
||||
/>
|
||||
);
|
||||
@@ -709,12 +697,16 @@ interface LargeLayoutProps {
|
||||
const LargeLayout = (props: LargeLayoutProps) => {
|
||||
return (
|
||||
<div className="mx-auto flex flex-center" style={{ maxWidth: LARGE_LAYOUT_MAX_WIDTH }}>
|
||||
<div className="flex-last px2">
|
||||
<div style={styles.leftColumn}>{props.left}</div>
|
||||
</div>
|
||||
<div className="flex-auto px2" style={styles.scrollContainer}>
|
||||
{props.right}
|
||||
<div className="flex-last">
|
||||
<Container width={LEFT_COLUMN_WIDTH} position="fixed" marginLeft={LARGE_LAYOUT_MARGIN}>
|
||||
{props.left}
|
||||
</Container>
|
||||
</div>
|
||||
<Container className="flex-auto" marginLeft={LEFT_COLUMN_WIDTH + LARGE_LAYOUT_MARGIN}>
|
||||
<Container className="flex-auto" marginLeft={LARGE_LAYOUT_MARGIN} marginRight={LARGE_LAYOUT_MARGIN}>
|
||||
{props.right}
|
||||
</Container>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -725,9 +717,7 @@ interface SmallLayoutProps {
|
||||
const SmallLayout = (props: SmallLayoutProps) => {
|
||||
return (
|
||||
<div className="flex flex-center">
|
||||
<div className="flex-auto px3" style={styles.scrollContainer}>
|
||||
{props.content}
|
||||
</div>
|
||||
<div className="flex-auto px3">{props.content}</div>
|
||||
</div>
|
||||
);
|
||||
}; // tslint:disable:max-file-line-count
|
||||
|
@@ -1,21 +1,16 @@
|
||||
import { Styles } from '@0xproject/react-shared';
|
||||
import { colors } from '@0xproject/react-shared';
|
||||
import * as React from 'react';
|
||||
|
||||
import { Text } from 'ts/components/ui/text';
|
||||
|
||||
export interface TextHeaderProps {
|
||||
labelText: string;
|
||||
}
|
||||
|
||||
const styles: Styles = {
|
||||
title: {
|
||||
fontWeight: 'bold',
|
||||
fontSize: 20,
|
||||
},
|
||||
};
|
||||
|
||||
export const TextHeader = (props: TextHeaderProps) => {
|
||||
return (
|
||||
<div className="py3" style={styles.title}>
|
||||
<Text className="pt3 pb2" fontWeight="bold" fontSize="16px" fontColor={colors.darkestGrey}>
|
||||
{props.labelText}
|
||||
</div>
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { constants as sharedConstants, Styles } from '@0xproject/react-shared';
|
||||
import * as _ from 'lodash';
|
||||
import { GridTile } from 'material-ui/GridList';
|
||||
import { GridTile as PlainGridTile } from 'material-ui/GridList';
|
||||
import * as React from 'react';
|
||||
import { analytics } from 'ts/utils/analytics';
|
||||
|
||||
@@ -9,7 +9,9 @@ import { Container } from 'ts/components/ui/container';
|
||||
import { Image } from 'ts/components/ui/image';
|
||||
import { Island } from 'ts/components/ui/island';
|
||||
import { colors } from 'ts/style/colors';
|
||||
import { styled } from 'ts/style/theme';
|
||||
import { WebsiteBackendRelayerInfo } from 'ts/types';
|
||||
import { utils } from 'ts/utils/utils';
|
||||
|
||||
export interface RelayerGridTileProps {
|
||||
relayerInfo: WebsiteBackendRelayerInfo;
|
||||
@@ -19,29 +21,23 @@ export interface RelayerGridTileProps {
|
||||
const styles: Styles = {
|
||||
root: {
|
||||
boxSizing: 'border-box',
|
||||
// All material UI components have position: relative
|
||||
// which creates a new stacking context and makes z-index stuff impossible. So reset.
|
||||
position: 'static',
|
||||
},
|
||||
innerDiv: {
|
||||
padding: 6,
|
||||
height: '100%',
|
||||
boxSizing: 'border-box',
|
||||
},
|
||||
header: {
|
||||
height: '50%',
|
||||
width: '100%',
|
||||
borderBottomRightRadius: 4,
|
||||
borderBottomLeftRadius: 4,
|
||||
borderTopRightRadius: 4,
|
||||
borderTopLeftRadius: 4,
|
||||
borderWidth: 1,
|
||||
borderStyle: 'solid',
|
||||
borderColor: colors.walletBorder,
|
||||
},
|
||||
body: {
|
||||
paddingLeft: 6,
|
||||
paddingRight: 6,
|
||||
height: '50%',
|
||||
width: '100%',
|
||||
boxSizing: 'border-box',
|
||||
padding: 12,
|
||||
},
|
||||
weeklyTradeVolumeLabel: {
|
||||
fontSize: 14,
|
||||
@@ -69,7 +65,10 @@ export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = (
|
||||
const weeklyTxnVolume = props.relayerInfo.weeklyTxnVolume;
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[props.networkId];
|
||||
const eventLabel = `${props.relayerInfo.name}-${networkName}`;
|
||||
const trackRelayerClick = () => analytics.logEvent('Portal', 'Relayer Click', eventLabel);
|
||||
const onClick = () => {
|
||||
analytics.logEvent('Portal', 'Relayer Click', eventLabel);
|
||||
utils.openUrl(link);
|
||||
};
|
||||
const headerImageUrl = props.relayerInfo.logoImgUrl;
|
||||
const headerBackgroundColor =
|
||||
!_.isUndefined(headerImageUrl) && !_.isUndefined(props.relayerInfo.primaryColor)
|
||||
@@ -77,22 +76,17 @@ export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = (
|
||||
: FALLBACK_PRIMARY_COLOR;
|
||||
return (
|
||||
<Island style={styles.root} Component={GridTile}>
|
||||
<div style={styles.innerDiv}>
|
||||
<a href={link} target="_blank" style={{ textDecoration: 'none' }} onClick={trackRelayerClick}>
|
||||
<div
|
||||
className="flex items-center"
|
||||
style={{ ...styles.header, backgroundColor: headerBackgroundColor }}
|
||||
>
|
||||
<Image
|
||||
className="mx-auto"
|
||||
src={props.relayerInfo.logoImgUrl}
|
||||
fallbackSrc={FALLBACK_IMG_SRC}
|
||||
height={RELAYER_ICON_HEIGHT}
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
<div style={styles.innerDiv} onClick={onClick}>
|
||||
<div className="flex items-center" style={{ ...styles.header, backgroundColor: headerBackgroundColor }}>
|
||||
<Image
|
||||
className="mx-auto"
|
||||
src={props.relayerInfo.logoImgUrl}
|
||||
fallbackSrc={FALLBACK_IMG_SRC}
|
||||
height={RELAYER_ICON_HEIGHT}
|
||||
/>
|
||||
</div>
|
||||
<div style={styles.body}>
|
||||
<div className="py1" style={styles.relayerNameLabel}>
|
||||
<div className="pb1" style={styles.relayerNameLabel}>
|
||||
{props.relayerInfo.name}
|
||||
</div>
|
||||
<Section titleText="Weekly Trade Volume">
|
||||
@@ -111,6 +105,14 @@ export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = (
|
||||
);
|
||||
};
|
||||
|
||||
const GridTile = styled(PlainGridTile)`
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease;
|
||||
&:hover {
|
||||
transform: translate(0px, -3px);
|
||||
}
|
||||
`;
|
||||
|
||||
interface SectionProps {
|
||||
titleText: string;
|
||||
children?: React.ReactNode;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { Styles } from '@0xproject/react-shared';
|
||||
import * as _ from 'lodash';
|
||||
import CircularProgress from 'material-ui/CircularProgress';
|
||||
import { GridList } from 'material-ui/GridList';
|
||||
@@ -6,7 +5,6 @@ import * as React from 'react';
|
||||
|
||||
import { RelayerGridTile } from 'ts/components/relayer_index/relayer_grid_tile';
|
||||
import { Retry } from 'ts/components/ui/retry';
|
||||
import { colors } from 'ts/style/colors';
|
||||
import { ScreenWidths, WebsiteBackendRelayerInfo } from 'ts/types';
|
||||
import { backendClient } from 'ts/utils/backend_client';
|
||||
|
||||
@@ -20,22 +18,6 @@ interface RelayerIndexState {
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
const styles: Styles = {
|
||||
root: {
|
||||
width: '100%',
|
||||
},
|
||||
item: {
|
||||
backgroundColor: colors.white,
|
||||
borderBottomRightRadius: 10,
|
||||
borderBottomLeftRadius: 10,
|
||||
borderTopRightRadius: 10,
|
||||
borderTopLeftRadius: 10,
|
||||
boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`,
|
||||
overflow: 'hidden',
|
||||
padding: 4,
|
||||
},
|
||||
};
|
||||
|
||||
const CELL_HEIGHT = 290;
|
||||
const NUMBER_OF_COLUMNS_LARGE = 3;
|
||||
const NUMBER_OF_COLUMNS_MEDIUM = 2;
|
||||
@@ -76,18 +58,16 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
|
||||
} else {
|
||||
const numberOfColumns = this._numberOfColumnsForScreenWidth(this.props.screenWidth);
|
||||
return (
|
||||
<div style={styles.root}>
|
||||
<GridList
|
||||
cellHeight={CELL_HEIGHT}
|
||||
cols={numberOfColumns}
|
||||
padding={GRID_PADDING}
|
||||
style={styles.gridList}
|
||||
>
|
||||
{this.state.relayerInfos.map((relayerInfo: WebsiteBackendRelayerInfo, index) => (
|
||||
<RelayerGridTile key={index} relayerInfo={relayerInfo} networkId={this.props.networkId} />
|
||||
))}
|
||||
</GridList>
|
||||
</div>
|
||||
<GridList
|
||||
cellHeight={CELL_HEIGHT}
|
||||
cols={numberOfColumns}
|
||||
padding={GRID_PADDING}
|
||||
style={{ marginTop: -10, marginBottom: 0 }}
|
||||
>
|
||||
{this.state.relayerInfos.map((relayerInfo: WebsiteBackendRelayerInfo, index) => (
|
||||
<RelayerGridTile key={index} relayerInfo={relayerInfo} networkId={this.props.networkId} />
|
||||
))}
|
||||
</GridList>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -70,7 +70,10 @@ class TokenLink extends React.Component<TokenLinkProps, TokenLinkState> {
|
||||
};
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const eventLabel = `${this.props.tokenInfo.symbol}-${networkName}`;
|
||||
const trackTokenClick = () => analytics.logEvent('Portal', 'Token Click', eventLabel);
|
||||
const onClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||
event.stopPropagation();
|
||||
analytics.logEvent('Portal', 'Token Click', eventLabel);
|
||||
};
|
||||
return (
|
||||
<a
|
||||
href={tokenLinkFromToken(this.props.tokenInfo, this.props.networkId)}
|
||||
@@ -78,7 +81,7 @@ class TokenLink extends React.Component<TokenLinkProps, TokenLinkState> {
|
||||
style={style}
|
||||
onMouseEnter={this._onToggleHover.bind(this, true)}
|
||||
onMouseLeave={this._onToggleHover.bind(this, false)}
|
||||
onClick={trackTokenClick}
|
||||
onClick={onClick}
|
||||
>
|
||||
{this.props.tokenInfo.symbol}
|
||||
</a>
|
||||
|
@@ -11,13 +11,15 @@ const PlainAnimation: React.StatelessComponent<AnimationProps> = props => <div {
|
||||
|
||||
const appearFromBottomFrames = keyframes`
|
||||
from {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
bottom: -500px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
to {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@@ -15,6 +15,7 @@ export interface ContainerProps {
|
||||
borderRadius?: StringOrNum;
|
||||
maxWidth?: StringOrNum;
|
||||
width?: StringOrNum;
|
||||
minHeight?: StringOrNum;
|
||||
isHidden?: boolean;
|
||||
className?: string;
|
||||
position?: 'absolute' | 'fixed' | 'relative' | 'unset';
|
||||
|
@@ -29,6 +29,7 @@ import { WrapEtherItem } from 'ts/components/wallet/wrap_ether_item';
|
||||
import { AllowanceToggle } from 'ts/containers/inputs/allowance_toggle';
|
||||
import { Dispatcher } from 'ts/redux/dispatcher';
|
||||
import { colors } from 'ts/style/colors';
|
||||
import { styled } from 'ts/style/theme';
|
||||
import {
|
||||
BlockchainErrs,
|
||||
ProviderType,
|
||||
@@ -138,6 +139,12 @@ const USD_DECIMAL_PLACES = 2;
|
||||
const NO_ALLOWANCE_TOGGLE_SPACE_WIDTH = 56;
|
||||
const ACCOUNT_PATH = `${WebsitePaths.Portal}/account`;
|
||||
|
||||
const ActionButton = styled(FloatingActionButton)`
|
||||
button {
|
||||
position: static !important;
|
||||
}
|
||||
`;
|
||||
|
||||
export class Wallet extends React.Component<WalletProps, WalletState> {
|
||||
public static defaultProps = {
|
||||
style: {},
|
||||
@@ -244,17 +251,12 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
|
||||
<ListItem
|
||||
primaryText={
|
||||
<div className="flex">
|
||||
<FloatingActionButton mini={true} zDepth={0} onClick={this.props.onAddToken}>
|
||||
<ActionButton mini={true} zDepth={0} onClick={this.props.onAddToken}>
|
||||
<ContentAdd />
|
||||
</FloatingActionButton>
|
||||
<FloatingActionButton
|
||||
mini={true}
|
||||
zDepth={0}
|
||||
className="px1"
|
||||
onClick={this.props.onRemoveToken}
|
||||
>
|
||||
</ActionButton>
|
||||
<ActionButton mini={true} zDepth={0} className="px1" onClick={this.props.onRemoveToken}>
|
||||
<ContentRemove />
|
||||
</FloatingActionButton>
|
||||
</ActionButton>
|
||||
<div
|
||||
style={{
|
||||
paddingLeft: 10,
|
||||
|
Reference in New Issue
Block a user