Some small component conversions (#1581)
* Some small component conversions * Default exports * Squashing * Some additional components * Linting
This commit is contained in:
parent
61a16ce682
commit
72f803926f
@ -86,18 +86,20 @@ function Banner ({ className, t }: Props): React.ReactElement<Props> | null {
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(styled(Banner)`
|
||||
padding: 0 0.5rem 0.5rem;
|
||||
export default translate(
|
||||
styled(Banner)`
|
||||
padding: 0 0.5rem 0.5rem;
|
||||
|
||||
.box {
|
||||
background: #fff6e5;
|
||||
border-left: 0.25rem solid darkorange;
|
||||
border-radius: 0 0.25rem 0.25rem 0;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem 1.5rem;
|
||||
.box {
|
||||
background: #fff6e5;
|
||||
border-left: 0.25rem solid darkorange;
|
||||
border-radius: 0 0.25rem 0.25rem 0;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem 1.5rem;
|
||||
|
||||
.info {
|
||||
max-width: 50rem;
|
||||
.info {
|
||||
max-width: 50rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
`
|
||||
);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Button, IdentityIcon } from '@polkadot/react-components';
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
@ -18,73 +18,51 @@ interface Props extends BareProps {
|
||||
seed: Uint8Array;
|
||||
}
|
||||
|
||||
interface State {
|
||||
hexSeed: string;
|
||||
}
|
||||
function Match ({ address, className, count, offset, onCreateToggle, onRemove, seed }: Props): React.ReactElement<Props> {
|
||||
const [hexSeed, setHexSeed] = useState('');
|
||||
const _onCreate = (): void => onCreateToggle(hexSeed);
|
||||
const _onRemove = (): void => onRemove(address);
|
||||
|
||||
class Match extends React.PureComponent<Props, State> {
|
||||
public state: State = { hexSeed: '' };
|
||||
useEffect((): void => {
|
||||
setHexSeed(u8aToHex(seed));
|
||||
}, [seed]);
|
||||
|
||||
public static getDerivedStateFromProps ({ seed }: Props): State {
|
||||
return {
|
||||
hexSeed: u8aToHex(seed)
|
||||
};
|
||||
}
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { address, className, count, offset } = this.props;
|
||||
const { hexSeed } = this.state;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className='vanity--Match-item'>
|
||||
<IdentityIcon
|
||||
className='vanity--Match-icon'
|
||||
size={48}
|
||||
value={address}
|
||||
/>
|
||||
<div className='vanity--Match-data'>
|
||||
<div className='vanity--Match-addr'>
|
||||
<span className='no'>{address.slice(0, offset)}</span><span className='yes'>{address.slice(offset, count + offset)}</span><span className='no'>{address.slice(count + offset)}</span>
|
||||
</div>
|
||||
<div className='vanity--Match-seed'>
|
||||
{hexSeed}
|
||||
</div>
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className='vanity--Match-item'>
|
||||
<IdentityIcon
|
||||
className='vanity--Match-icon'
|
||||
size={48}
|
||||
value={address}
|
||||
/>
|
||||
<div className='vanity--Match-data'>
|
||||
<div className='vanity--Match-addr'>
|
||||
<span className='no'>{address.slice(0, offset)}</span><span className='yes'>{address.slice(offset, count + offset)}</span><span className='no'>{address.slice(count + offset)}</span>
|
||||
</div>
|
||||
<div className='vanity--Match-buttons'>
|
||||
<Button
|
||||
icon='plus'
|
||||
isPrimary
|
||||
onClick={this.onCreate}
|
||||
size='tiny'
|
||||
/>
|
||||
<Button
|
||||
icon='close'
|
||||
isNegative
|
||||
onClick={this.onRemove}
|
||||
size='tiny'
|
||||
/>
|
||||
<div className='vanity--Match-seed'>
|
||||
{hexSeed}
|
||||
</div>
|
||||
</div>
|
||||
<div className='vanity--Match-buttons'>
|
||||
<Button
|
||||
icon='plus'
|
||||
isPrimary
|
||||
onClick={_onCreate}
|
||||
size='tiny'
|
||||
/>
|
||||
<Button
|
||||
icon='close'
|
||||
isNegative
|
||||
onClick={_onRemove}
|
||||
size='tiny'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private onCreate = (): void => {
|
||||
const { onCreateToggle } = this.props;
|
||||
const { hexSeed } = this.state;
|
||||
|
||||
onCreateToggle(hexSeed);
|
||||
}
|
||||
|
||||
private onRemove = (): void => {
|
||||
const { address, onRemove } = this.props;
|
||||
|
||||
onRemove(address);
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default styled(Match as React.ComponentClass<Props, State>)`
|
||||
export default styled(Match)`
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
|
||||
@ -44,7 +44,7 @@ const renderDetails = ({ number: blockNumber, extrinsicsRoot, parentHash, stateR
|
||||
);
|
||||
};
|
||||
|
||||
function BlockHeader ({ isSummary, value, withExplorer, withLink }: Props): React.ReactElement<Props> | null {
|
||||
export default function BlockHeader ({ isSummary, value, withExplorer, withLink }: Props): React.ReactElement<Props> | null {
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
@ -82,5 +82,3 @@ function BlockHeader ({ isSummary, value, withExplorer, withLink }: Props): Reac
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
export default BlockHeader;
|
||||
|
||||
@ -13,7 +13,7 @@ interface Props extends BareProps {
|
||||
queue: QueueTx[];
|
||||
}
|
||||
|
||||
function Results ({ queue = [] }: Props): React.ReactElement<Props> | null {
|
||||
export default function Results ({ queue = [] }: Props): React.ReactElement<Props> | null {
|
||||
const filtered = queue
|
||||
.filter(({ error, result }): boolean =>
|
||||
!isUndefined(error) || !isUndefined(result)
|
||||
@ -41,5 +41,3 @@ function Results ({ queue = [] }: Props): React.ReactElement<Props> | null {
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Results;
|
||||
|
||||
@ -115,4 +115,5 @@ const Proposals = withMulti(
|
||||
);
|
||||
|
||||
export default Proposals;
|
||||
|
||||
export const Approvals = (): JSX.Element => <Proposals isApprovals />;
|
||||
|
||||
@ -24,15 +24,6 @@ export interface Props extends I18nProps, BareProps {
|
||||
tip?: BN;
|
||||
}
|
||||
|
||||
const Wrapper = styled.div`
|
||||
.hash .ui--Static {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: unset;
|
||||
word-wrap: unset;
|
||||
}
|
||||
`;
|
||||
|
||||
function Call ({ children, className, style, mortality, tip, value, withHash, t }: Props): React.ReactElement<Props> {
|
||||
const params = GenericCall.filterOrigin(value.meta).map(({ name, type }): { name: string; type: TypeDef } => ({
|
||||
name: name.toString(),
|
||||
@ -47,54 +38,51 @@ function Call ({ children, className, style, mortality, tip, value, withHash, t
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
<div
|
||||
className={classes('ui--Extrinsic', className)}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
{
|
||||
hash
|
||||
? (
|
||||
<Static
|
||||
className='hash'
|
||||
label={t('extrinsic hash')}
|
||||
>
|
||||
{hash.toHex()}
|
||||
</Static>
|
||||
)
|
||||
: null
|
||||
}
|
||||
{
|
||||
mortality
|
||||
? (
|
||||
<Static
|
||||
className='mortality'
|
||||
label={t('lifetime')}
|
||||
>
|
||||
{mortality}
|
||||
</Static>
|
||||
)
|
||||
: null
|
||||
}
|
||||
{
|
||||
(tip && tip.gtn(0))
|
||||
? (
|
||||
<Static
|
||||
className='tip'
|
||||
label={t('tip')}
|
||||
>
|
||||
{formatBalance(tip)}
|
||||
</Static>
|
||||
)
|
||||
: null
|
||||
}
|
||||
{hash && (
|
||||
<Static
|
||||
className='hash'
|
||||
label={t('extrinsic hash')}
|
||||
>
|
||||
{hash.toHex()}
|
||||
</Static>
|
||||
)}
|
||||
{mortality && (
|
||||
<Static
|
||||
className='mortality'
|
||||
label={t('lifetime')}
|
||||
>
|
||||
{mortality}
|
||||
</Static>
|
||||
)}
|
||||
{tip && tip.gtn(0) && (
|
||||
<Static
|
||||
className='tip'
|
||||
label={t('tip')}
|
||||
>
|
||||
{formatBalance(tip)}
|
||||
</Static>
|
||||
)}
|
||||
<Params
|
||||
isDisabled
|
||||
params={params}
|
||||
values={values}
|
||||
/>
|
||||
</Wrapper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(Call);
|
||||
export default translate(
|
||||
styled(Call)`
|
||||
.hash .ui--Static {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: unset;
|
||||
word-wrap: unset;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
@ -2,48 +2,39 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { QueueAction$Add } from './Status/types';
|
||||
import { BareProps, I18nProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
|
||||
import { QueueConsumer } from './Status/Context';
|
||||
import QueueContext from './Status/Context';
|
||||
import Button from './Button';
|
||||
import translate from './translate';
|
||||
import styled from 'styled-components';
|
||||
|
||||
interface Props extends BareProps {
|
||||
interface Props extends BareProps, I18nProps {
|
||||
children?: React.ReactNode;
|
||||
icon?: string;
|
||||
isAddress?: boolean;
|
||||
value?: any;
|
||||
}
|
||||
|
||||
type InnerProps = Props & I18nProps & {
|
||||
queueAction: QueueAction$Add;
|
||||
};
|
||||
function CopyButton ({ children, className, icon = 'copy', isAddress = false, t, value }: Props): React.ReactElement<Props> {
|
||||
const { queueAction } = useContext(QueueContext);
|
||||
|
||||
function onCopy ({ isAddress = false, queueAction, t, value }: InnerProps): () => void {
|
||||
return (): void => {
|
||||
if (isAddress && queueAction) {
|
||||
queueAction({
|
||||
account: value,
|
||||
action: t('clipboard'),
|
||||
status: 'queued',
|
||||
message: t('address copied')
|
||||
});
|
||||
}
|
||||
const _onCopy = (): void => {
|
||||
isAddress && queueAction && queueAction({
|
||||
account: value,
|
||||
action: t('clipboard'),
|
||||
status: 'queued',
|
||||
message: t('address copied')
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function CopyButtonInner (props: InnerProps): React.ReactElement<InnerProps> {
|
||||
const { children, className, icon = 'copy', value } = props;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<CopyToClipboard
|
||||
onCopy={onCopy(props)}
|
||||
onCopy={_onCopy}
|
||||
text={value}
|
||||
>
|
||||
<div className='copyContainer'>
|
||||
@ -62,34 +53,16 @@ function CopyButtonInner (props: InnerProps): React.ReactElement<InnerProps> {
|
||||
);
|
||||
}
|
||||
|
||||
const CopyButtonI18n = translate(CopyButtonInner);
|
||||
|
||||
function CopyButton (props: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<QueueConsumer>
|
||||
{({ queueAction }): React.ReactNode => (
|
||||
<CopyButtonI18n
|
||||
{...props}
|
||||
queueAction={queueAction}
|
||||
/>
|
||||
)}
|
||||
</QueueConsumer>
|
||||
);
|
||||
}
|
||||
|
||||
export default styled(CopyButton)`
|
||||
width: 100%;
|
||||
cursor: copy;
|
||||
|
||||
button.ui.mini.icon.primary.button.iconButton {
|
||||
export default translate(
|
||||
styled(CopyButton)`
|
||||
cursor: copy;
|
||||
}
|
||||
|
||||
.copySpan {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.copyContainer {
|
||||
display: flex;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
`;
|
||||
button.ui.mini.icon.primary.button.iconButton {
|
||||
cursor: copy;
|
||||
}
|
||||
|
||||
.copySpan {
|
||||
white-space: nowrap;
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
|
||||
import { BareProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
|
||||
import { classes } from './util';
|
||||
@ -16,23 +16,27 @@ interface Props extends BareProps {
|
||||
}
|
||||
|
||||
export default function CryptoType ({ accountId, className, label = '' }: Props): React.ReactElement<Props> {
|
||||
let type = 'unknown';
|
||||
const [type, setType] = useState('unknown');
|
||||
|
||||
try {
|
||||
const current = accountId
|
||||
? keyring.getPair(accountId.toString())
|
||||
: null;
|
||||
useEffect((): void => {
|
||||
try {
|
||||
const current = accountId
|
||||
? keyring.getPair(accountId.toString())
|
||||
: null;
|
||||
|
||||
if (current) {
|
||||
type = current.meta.isInjected
|
||||
? 'injected'
|
||||
: current.meta.isExternal
|
||||
? 'external'
|
||||
: current.type;
|
||||
if (current) {
|
||||
setType(
|
||||
current.meta.isInjected
|
||||
? 'injected'
|
||||
: current.meta.isExternal
|
||||
? 'external'
|
||||
: current.type
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
// cannot determine, keep unknown
|
||||
}
|
||||
} catch (error) {
|
||||
// cannot determine, keep unknown
|
||||
}
|
||||
}, [accountId]);
|
||||
|
||||
return (
|
||||
<div className={classes('ui--CryptoType', className)}>
|
||||
|
||||
@ -65,28 +65,9 @@ function getHeaderText ({ mode = 'account', t }: Props): string {
|
||||
}
|
||||
}
|
||||
|
||||
function renderButtons ({ onClose, onForget, t }: Props): React.ReactNode {
|
||||
return (
|
||||
<Modal.Actions>
|
||||
<Button.Group>
|
||||
<Button
|
||||
isNegative
|
||||
onClick={onClose}
|
||||
label={t('Cancel')}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
isPrimary
|
||||
onClick={onForget}
|
||||
label={t('Forget')}
|
||||
/>
|
||||
</Button.Group>
|
||||
</Modal.Actions>
|
||||
);
|
||||
}
|
||||
|
||||
function renderContent (props: Props): React.ReactNode {
|
||||
const { address, code, mode = 'account' } = props;
|
||||
|
||||
switch (mode) {
|
||||
case 'account':
|
||||
case 'address':
|
||||
@ -112,7 +93,8 @@ function renderContent (props: Props): React.ReactNode {
|
||||
}
|
||||
|
||||
function Forget (props: Props): React.ReactElement<Props> {
|
||||
const { onClose } = props;
|
||||
const { onForget, onClose, t } = props;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className='app--accounts-Modal'
|
||||
@ -126,7 +108,21 @@ function Forget (props: Props): React.ReactElement<Props> {
|
||||
<Modal.Content>
|
||||
{renderContent(props)}
|
||||
</Modal.Content>
|
||||
{renderButtons(props)}
|
||||
<Modal.Actions>
|
||||
<Button.Group>
|
||||
<Button
|
||||
isNegative
|
||||
onClick={onClose}
|
||||
label={t('Cancel')}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
isPrimary
|
||||
onClick={onForget}
|
||||
label={t('Forget')}
|
||||
/>
|
||||
</Button.Group>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { BareProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import ReactMd from 'react-markdown';
|
||||
import styled from 'styled-components';
|
||||
|
||||
@ -14,11 +14,37 @@ interface Props extends BareProps {
|
||||
md: string;
|
||||
}
|
||||
|
||||
interface State {
|
||||
isVisible: boolean;
|
||||
function HelpOverlay ({ className, md }: Props): React.ReactElement<Props> {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
const _toggleVisible = (): void => setIsVisible(!isVisible);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div className='help-button'>
|
||||
<Icon
|
||||
name='help circle'
|
||||
onClick={_toggleVisible}
|
||||
/>
|
||||
</div>
|
||||
<div className={`help-slideout ${isVisible ? 'open' : 'closed'}`}>
|
||||
<div className='help-button'>
|
||||
<Icon
|
||||
name='close'
|
||||
onClick={_toggleVisible}
|
||||
/>
|
||||
</div>
|
||||
<ReactMd
|
||||
className='help-content'
|
||||
escapeHtml={false}
|
||||
source={md}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const Wrapper = styled.div`
|
||||
export default styled(HelpOverlay)`
|
||||
.help-button {
|
||||
cursor: pointer;
|
||||
font-size: 2rem;
|
||||
@ -57,43 +83,3 @@ const Wrapper = styled.div`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default class HelpOverlay extends React.PureComponent<Props, State> {
|
||||
public state: State = { isVisible: false };
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { md } = this.props;
|
||||
const { isVisible } = this.state;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
{this.renderButton('help circle')}
|
||||
<div className={`help-slideout ${isVisible ? 'open' : 'closed'}`}>
|
||||
{this.renderButton('close')}
|
||||
<ReactMd
|
||||
className='help-content'
|
||||
escapeHtml={false}
|
||||
source={md}
|
||||
/>
|
||||
</div>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
private renderButton (name: 'close' | 'help circle'): React.ReactNode {
|
||||
return (
|
||||
<div className='help-button'>
|
||||
<Icon
|
||||
name={name}
|
||||
onClick={this.toggleVisible}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private toggleVisible = (): void => {
|
||||
this.setState(({ isVisible }): State => ({
|
||||
isVisible: !isVisible
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,15 @@ interface Props {
|
||||
type?: 'error' | 'info' | 'warning';
|
||||
}
|
||||
|
||||
const Wrapper = styled.div`
|
||||
function InfoForInput ({ children, className, type = 'info' }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<Labelled>
|
||||
<div className={classes(className, type)}>{children}</div>
|
||||
</Labelled>
|
||||
);
|
||||
}
|
||||
|
||||
export default styled(InfoForInput)`
|
||||
background: white;
|
||||
border-radius: 0 0 0.25rem 0.25rem;
|
||||
margin: -0.5rem 0 0.25rem;
|
||||
@ -34,11 +42,3 @@ const Wrapper = styled.div`
|
||||
padding: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
export default function InfoForInput ({ children, className, type = 'info' }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<Labelled>
|
||||
<Wrapper className={classes(className, type)}>{children}</Wrapper>
|
||||
</Labelled>
|
||||
);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { BareProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import Icon from './Icon';
|
||||
@ -15,51 +15,36 @@ interface Props extends BareProps {
|
||||
help: React.ReactNode;
|
||||
}
|
||||
|
||||
interface State {
|
||||
tooltipOpen: boolean;
|
||||
function LabelHelp ({ className, help, style }: Props): React.ReactElement<Props> {
|
||||
const [isTooltipOpen, setIsTooltipOpen] = useState(false);
|
||||
|
||||
const _toggleTooltip = (): void => setIsTooltipOpen(!isTooltipOpen);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes('ui--LabelHelp', className)}
|
||||
style={style}
|
||||
>
|
||||
<Icon
|
||||
name='help circle'
|
||||
data-tip
|
||||
data-for='controlled-trigger'
|
||||
onMouseOver={_toggleTooltip}
|
||||
onMouseOut={_toggleTooltip}
|
||||
/>
|
||||
{isTooltipOpen && (
|
||||
<Tooltip
|
||||
text={help}
|
||||
trigger='controlled-trigger'
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const Wrapper = styled.div`
|
||||
export default styled(LabelHelp)`
|
||||
cursor: help;
|
||||
display: inline-block;
|
||||
line-height: 1rem;
|
||||
margin: 0 0 0 0.25rem;
|
||||
`;
|
||||
|
||||
export default class LabelHelp extends React.PureComponent<Props, State> {
|
||||
public state: State = {
|
||||
tooltipOpen: false
|
||||
};
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { className, help, style } = this.props;
|
||||
const { tooltipOpen } = this.state;
|
||||
|
||||
return (
|
||||
<Wrapper
|
||||
className={classes('ui--LabelHelp', className)}
|
||||
style={style}
|
||||
>
|
||||
<Icon
|
||||
name='help circle'
|
||||
data-tip
|
||||
data-for='controlled-trigger'
|
||||
onMouseOver={this.toggleTooltip}
|
||||
onMouseOut={this.toggleTooltip}
|
||||
/>
|
||||
{tooltipOpen && (
|
||||
<Tooltip
|
||||
text={help}
|
||||
trigger='controlled-trigger'
|
||||
/>
|
||||
)}
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
private toggleTooltip = (): void => {
|
||||
this.setState(({ tooltipOpen }): Pick<State, never> => ({
|
||||
tooltipOpen: !tooltipOpen
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ export interface Props extends I18nProps {
|
||||
onSelect?: (callAddress?: string, callMethod?: string) => void;
|
||||
}
|
||||
|
||||
const NOOP = (): void => {};
|
||||
|
||||
function onSelect (props: Props, index: number): () => void {
|
||||
return function (): void {
|
||||
const { address: callAddress, contractAbi: { abi: { messages } }, onSelect } = props;
|
||||
@ -61,12 +63,11 @@ function renderMessage (props: Props, index: number): React.ReactNode {
|
||||
}
|
||||
|
||||
function Messages (props: Props): React.ReactElement<Props> {
|
||||
const { className, contractAbi: { abi: { messages } }, isLabelled, isRemovable, onRemove = (): void => { /* . */ }, onSelect, t } = props;
|
||||
const { className, contractAbi: { abi: { messages } }, isLabelled, isRemovable, onRemove = NOOP, onSelect, t } = props;
|
||||
|
||||
return (
|
||||
<div className={classes(className, 'ui--Messages', isLabelled && 'labelled', onSelect && 'select')}>
|
||||
{messages.map((_, index): React.ReactNode => {
|
||||
return renderMessage(props, index);
|
||||
})}
|
||||
{messages.map((_, index): React.ReactNode => renderMessage(props, index))}
|
||||
{isRemovable && (
|
||||
<Button
|
||||
className='iconButton'
|
||||
@ -107,7 +108,6 @@ export default translate(styled(Messages)`
|
||||
margin-right: 0;
|
||||
padding: 0.5rem;
|
||||
margin: 0;
|
||||
/* border-radius: 0.7rem; */
|
||||
|
||||
&.disabled {
|
||||
opacity: 1 !important;
|
||||
|
||||
@ -7,7 +7,7 @@ import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { I18nProps } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
@ -23,153 +23,139 @@ interface Props extends I18nProps {
|
||||
value: DerivedStakingOnlineStatus;
|
||||
}
|
||||
|
||||
interface State {
|
||||
isOpen: boolean;
|
||||
version: 'online' | 'offline' | null;
|
||||
}
|
||||
function OnlineStatus ({ accountId, className, value, tooltip = false, t }: Props): React.ReactElement<Props> | null {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [version, setVersion] = useState<string | null>(null);
|
||||
|
||||
class OnlineStatus extends React.PureComponent<Props, State> {
|
||||
public static getDerivedStateFromProps ({ value = {} }: Props): Pick<State, never> {
|
||||
const _toggleOpen = (): void => setIsOpen(!isOpen);
|
||||
|
||||
useEffect((): void => {
|
||||
const { online, offline } = value;
|
||||
|
||||
if (offline) {
|
||||
return { version: 'offline' };
|
||||
setVersion('offline');
|
||||
} else if (online && online.isOnline) {
|
||||
setVersion('online');
|
||||
} else {
|
||||
setVersion(null);
|
||||
}
|
||||
if (online && online.isOnline) {
|
||||
return { version: 'online' };
|
||||
}
|
||||
return { version: null };
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
public state: State = {
|
||||
isOpen: false,
|
||||
version: null
|
||||
};
|
||||
const key = accountId.toString();
|
||||
const classNames: (string | false | undefined)[] = ['ui--OnlineStatus', isOpen && 'expand', tooltip && 'tooltip', className];
|
||||
let text: string;
|
||||
let contents: React.ReactNode;
|
||||
let offline;
|
||||
let count;
|
||||
let blockNumbers;
|
||||
let blockNumber;
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { accountId, className, value, tooltip = false, t } = this.props;
|
||||
const { isOpen, version } = this.state;
|
||||
switch (version) {
|
||||
case 'offline':
|
||||
offline = value.offline || [];
|
||||
count = offline.reduce((total, { count }): BN => total.add(count), new BN(0));
|
||||
blockNumbers = offline.map(({ blockNumber }): string => `#${formatNumber(blockNumber)}`);
|
||||
|
||||
const key = accountId.toString();
|
||||
const classNames: (string | false | undefined)[] = ['ui--OnlineStatus', isOpen && 'expand', tooltip && 'tooltip', className];
|
||||
let text: string;
|
||||
let contents: React.ReactNode;
|
||||
let offline;
|
||||
let count;
|
||||
let blockNumbers;
|
||||
let blockNumber;
|
||||
classNames.push('offline');
|
||||
contents = count.toString();
|
||||
text = t('Reported offline {{count}} times, last at {{blockNumber}}', {
|
||||
replace: {
|
||||
count,
|
||||
blockNumber: blockNumbers[blockNumbers.length - 1]
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
switch (version) {
|
||||
case 'offline':
|
||||
offline = value.offline || [];
|
||||
count = offline.reduce((total, { count }): BN => total.add(count), new BN(0));
|
||||
blockNumbers = offline.map(({ blockNumber }): string => `#${formatNumber(blockNumber)}`);
|
||||
case 'online':
|
||||
blockNumber = value.online ? value.online.blockNumber : null;
|
||||
|
||||
classNames.push('offline');
|
||||
contents = count.toString();
|
||||
text = t('Reported offline {{count}} times, last at {{blockNumber}}', {
|
||||
classNames.push('online');
|
||||
contents = (
|
||||
<Icon name='check' />
|
||||
);
|
||||
text = blockNumber
|
||||
? t('Reported online at #{{blockNumber}}', {
|
||||
replace: {
|
||||
count,
|
||||
blockNumber: blockNumbers[blockNumbers.length - 1]
|
||||
blockNumber: formatNumber(blockNumber)
|
||||
}
|
||||
});
|
||||
break;
|
||||
})
|
||||
: t('Reported online in the current session');
|
||||
break;
|
||||
|
||||
case 'online':
|
||||
blockNumber = value.online ? value.online.blockNumber : null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
classNames.push('online');
|
||||
contents = (
|
||||
<Icon name='check' />
|
||||
);
|
||||
text = blockNumber
|
||||
? t('Reported online at #{{blockNumber}}', {
|
||||
replace: {
|
||||
blockNumber: formatNumber(blockNumber)
|
||||
}
|
||||
})
|
||||
: t('Reported online in the current session');
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes(...classNames)}
|
||||
{...(!tooltip ? { onClick: this.toggleOpen } : {})}
|
||||
data-for={`online-status-${key}`}
|
||||
data-tip={true}
|
||||
data-tip-disable={!tooltip}
|
||||
>
|
||||
<div className='badge'>
|
||||
{contents}
|
||||
</div>
|
||||
<div className='detail'>
|
||||
{text}
|
||||
</div>
|
||||
<Tooltip
|
||||
trigger={`online-status-${key}`}
|
||||
text={text}
|
||||
/>
|
||||
return (
|
||||
<div
|
||||
className={classes(...classNames)}
|
||||
{...(!tooltip ? { onClick: _toggleOpen } : {})}
|
||||
data-for={`online-status-${key}`}
|
||||
data-tip={true}
|
||||
data-tip-disable={!tooltip}
|
||||
>
|
||||
<div className='badge'>
|
||||
{contents}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private toggleOpen = (): void => {
|
||||
this.setState(({ isOpen }): Pick<State, never> => ({
|
||||
isOpen: !isOpen
|
||||
}));
|
||||
}
|
||||
<div className='detail'>
|
||||
{text}
|
||||
</div>
|
||||
<Tooltip
|
||||
trigger={`online-status-${key}`}
|
||||
text={text}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(styled(OnlineStatus as React.ComponentClass<Props, State>)`
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2);
|
||||
color: #eee;
|
||||
cursor: help;
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
height: 22px;
|
||||
justify-content: center;
|
||||
padding: 0 4px;
|
||||
text-align: center;
|
||||
transition: all ease .2s;
|
||||
width: 22px;
|
||||
export default translate(
|
||||
styled(OnlineStatus)`
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 3px 3px rgba(0, 0, 0, 0.2);
|
||||
color: #eee;
|
||||
cursor: help;
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
height: 22px;
|
||||
justify-content: center;
|
||||
padding: 0 4px;
|
||||
text-align: center;
|
||||
transition: all ease .2s;
|
||||
width: 22px;
|
||||
|
||||
&.offline {
|
||||
background: red;
|
||||
}
|
||||
&.offline {
|
||||
background: red;
|
||||
}
|
||||
|
||||
&.online {
|
||||
background: green;
|
||||
}
|
||||
&.online {
|
||||
background: green;
|
||||
}
|
||||
|
||||
& > * {
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
transition: all ease 0.25;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-weight: bold;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&.expand {
|
||||
width: 300px;
|
||||
& > * {
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
transition: all ease 0.25;
|
||||
}
|
||||
|
||||
.badge {
|
||||
width: 0;
|
||||
font-weight: bold;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: auto;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
&.expand {
|
||||
width: 300px;
|
||||
|
||||
.badge {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.detail {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
`
|
||||
);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { BareProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { MAX_PASS_LEN } from '@polkadot/ui-keyring/defaults';
|
||||
|
||||
import { classes } from './util';
|
||||
@ -27,60 +27,45 @@ interface Props extends BareProps {
|
||||
withLabel?: boolean;
|
||||
}
|
||||
|
||||
interface State {
|
||||
isVisible: boolean;
|
||||
}
|
||||
export default function Password ({ autoFocus, children, className, defaultValue, help, isDisabled, isError, label, name, onChange, onEnter, style, tabIndex, value, withLabel }: Props): React.ReactElement<Props> {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
export default class Password extends React.PureComponent<Props, State> {
|
||||
public state: State = {
|
||||
isVisible: false
|
||||
};
|
||||
const _toggleVisible = (): void => setIsVisible(!isVisible);
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { autoFocus, children, className, defaultValue, help, isDisabled, isError, label, name, onChange, onEnter, style, tabIndex, value, withLabel } = this.props;
|
||||
const { isVisible } = this.state;
|
||||
|
||||
return (
|
||||
<Input
|
||||
autoFocus={autoFocus}
|
||||
className={classes('ui--Password', className)}
|
||||
defaultValue={defaultValue}
|
||||
help={help}
|
||||
isAction
|
||||
isDisabled={isDisabled}
|
||||
isError={isError}
|
||||
label={label}
|
||||
maxLength={MAX_PASS_LEN}
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
onEnter={onEnter}
|
||||
style={style}
|
||||
tabIndex={tabIndex}
|
||||
type={
|
||||
return (
|
||||
<Input
|
||||
autoFocus={autoFocus}
|
||||
className={classes('ui--Password', className)}
|
||||
defaultValue={defaultValue}
|
||||
help={help}
|
||||
isAction
|
||||
isDisabled={isDisabled}
|
||||
isError={isError}
|
||||
label={label}
|
||||
maxLength={MAX_PASS_LEN}
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
onEnter={onEnter}
|
||||
style={style}
|
||||
tabIndex={tabIndex}
|
||||
type={
|
||||
isVisible
|
||||
? 'text'
|
||||
: 'password'
|
||||
}
|
||||
value={value}
|
||||
withLabel={withLabel}
|
||||
>
|
||||
<Button
|
||||
icon={
|
||||
isVisible
|
||||
? 'text'
|
||||
: 'password'
|
||||
? 'hide'
|
||||
: 'unhide'
|
||||
}
|
||||
value={value}
|
||||
withLabel={withLabel}
|
||||
>
|
||||
<Button
|
||||
icon={
|
||||
isVisible
|
||||
? 'hide'
|
||||
: 'unhide'
|
||||
}
|
||||
isPrimary
|
||||
onClick={this.onToggleVisible}
|
||||
/>
|
||||
{children}
|
||||
</Input>
|
||||
);
|
||||
}
|
||||
|
||||
private onToggleVisible = (): void => {
|
||||
this.setState({
|
||||
isVisible: !this.state.isVisible
|
||||
});
|
||||
}
|
||||
isPrimary
|
||||
onClick={_toggleVisible}
|
||||
/>
|
||||
{children}
|
||||
</Input>
|
||||
);
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ export interface RowState {
|
||||
// const DEFAULT_ADDR = '5'.padEnd(16, 'x');
|
||||
// const ICON_SIZE = 48;
|
||||
|
||||
class Row<P extends RowProps, S extends RowState> extends React.PureComponent<P, S> {
|
||||
export default class Row<P extends RowProps, S extends RowState> extends React.PureComponent<P, S> {
|
||||
public state: S = {
|
||||
isEditingName: false,
|
||||
isEditingTags: false
|
||||
@ -373,5 +373,3 @@ class Row<P extends RowProps, S extends RowState> extends React.PureComponent<P,
|
||||
}) as unknown as S);
|
||||
}
|
||||
}
|
||||
|
||||
export default Row;
|
||||
|
||||
@ -63,6 +63,7 @@ function renderItem ({ basePath, isSequence, items }: Props): (tabItem: TabItem,
|
||||
|
||||
export default function Tabs (props: Props): React.ReactElement<Props> {
|
||||
const { className, hidden = [], items, style } = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes('ui--Menu ui menu tabular', className)}
|
||||
|
||||
@ -17,14 +17,10 @@ interface Props extends BareProps {
|
||||
value?: boolean;
|
||||
}
|
||||
|
||||
function onChange ({ onChange }: Props): (_: React.FormEvent<HTMLInputElement>, __: any) => void {
|
||||
return function (_: React.FormEvent<HTMLInputElement>, { checked }: any): void {
|
||||
function Toggle ({ className, asSwitch = true, defaultValue, isDisabled, onChange, value, label }: Props): React.ReactElement<Props> {
|
||||
const _onChange = (_: React.FormEvent<HTMLInputElement>, { checked }: any): void => {
|
||||
onChange && onChange(checked);
|
||||
};
|
||||
}
|
||||
|
||||
function Toggle (props: Props): React.ReactElement<Props> {
|
||||
const { className, asSwitch = true, defaultValue, isDisabled, value, label } = props;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
@ -33,7 +29,7 @@ function Toggle (props: Props): React.ReactElement<Props> {
|
||||
checked={value}
|
||||
disabled={isDisabled}
|
||||
defaultChecked={defaultValue}
|
||||
onChange={onChange(props)}
|
||||
onChange={_onChange}
|
||||
toggle={asSwitch}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { BareProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactTooltip from 'react-tooltip';
|
||||
|
||||
@ -26,42 +26,32 @@ interface Props extends BareProps {
|
||||
trigger: string;
|
||||
}
|
||||
|
||||
export default class Tooltip extends React.PureComponent<Props> {
|
||||
private tooltipContainer: HTMLElement;
|
||||
export default function Tooltip ({ className, effect = 'solid', offset, place = 'bottom', text, trigger }: Props): React.ReactElement<Props> | null {
|
||||
const [tooltipContainer] = useState(document.createElement('div'));
|
||||
|
||||
public constructor (props: Props) {
|
||||
super(props);
|
||||
|
||||
this.tooltipContainer = document.createElement('div');
|
||||
}
|
||||
|
||||
public componentDidMount (): void {
|
||||
useEffect((): () => void => {
|
||||
if (rootElement !== null) {
|
||||
rootElement.appendChild(this.tooltipContainer);
|
||||
rootElement.appendChild(tooltipContainer);
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount (): void {
|
||||
if (rootElement !== null) {
|
||||
rootElement.removeChild(this.tooltipContainer);
|
||||
}
|
||||
}
|
||||
return (): void => {
|
||||
if (rootElement !== null) {
|
||||
rootElement.removeChild(tooltipContainer);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { className, effect = 'solid', offset, place = 'bottom', text, trigger } = this.props;
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<ReactTooltip
|
||||
id={trigger}
|
||||
delayShow={250}
|
||||
effect={effect}
|
||||
offset={offset}
|
||||
place={place}
|
||||
className={classes('ui--Tooltip', className)}
|
||||
>
|
||||
{text}
|
||||
</ReactTooltip>,
|
||||
this.tooltipContainer
|
||||
);
|
||||
}
|
||||
return ReactDOM.createPortal(
|
||||
<ReactTooltip
|
||||
id={trigger}
|
||||
delayShow={250}
|
||||
effect={effect}
|
||||
offset={offset}
|
||||
place={place}
|
||||
className={classes('ui--Tooltip', className)}
|
||||
>
|
||||
{text}
|
||||
</ReactTooltip>,
|
||||
tooltipContainer
|
||||
);
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ export interface TxModalState {
|
||||
isOpen: boolean;
|
||||
}
|
||||
|
||||
class TxModal<P extends TxModalProps, S extends TxModalState> extends TxComponent<P, S> {
|
||||
export default class TxModal<P extends TxModalProps, S extends TxModalState> extends TxComponent<P, S> {
|
||||
protected defaultState: S = {
|
||||
accountId: null,
|
||||
isOpen: false,
|
||||
@ -204,5 +204,3 @@ class TxModal<P extends TxModalProps, S extends TxModalState> extends TxComponen
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TxModal;
|
||||
|
||||
@ -10,22 +10,13 @@ import { InputBalance } from '@polkadot/react-components';
|
||||
|
||||
import Bare from './Bare';
|
||||
|
||||
function onChange ({ isError, onChange }: Props): (_?: BN) => void {
|
||||
return function (value?: BN): void {
|
||||
if (!onChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
onChange({
|
||||
export default function Balance ({ className, defaultValue: { value }, isDisabled, isError, label, onChange, onEnter, style, withLabel }: Props): React.ReactElement<Props> {
|
||||
const defaultValue = new BN((value as BN || '0').toString()).toString(10);
|
||||
const _onChange = (value?: BN): void =>
|
||||
onChange && onChange({
|
||||
isValid: !isError && !!value,
|
||||
value
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function Balance (props: Props): React.ReactElement<Props> {
|
||||
const { className, defaultValue: { value }, isDisabled, isError, label, onEnter, style, withLabel } = props;
|
||||
const defaultValue = new BN((value as BN || '0').toString()).toString(10);
|
||||
|
||||
return (
|
||||
<Bare
|
||||
@ -38,7 +29,7 @@ function Balance (props: Props): React.ReactElement<Props> {
|
||||
isDisabled={isDisabled}
|
||||
isError={isError}
|
||||
label={label}
|
||||
onChange={onChange(props)}
|
||||
onChange={_onChange}
|
||||
withEllipsis
|
||||
onEnter={onEnter}
|
||||
withLabel={withLabel}
|
||||
@ -50,5 +41,3 @@ function Balance (props: Props): React.ReactElement<Props> {
|
||||
export {
|
||||
Balance
|
||||
};
|
||||
|
||||
export default Balance;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user