Kaynağa Gözat

More func. components, Button labelIcon -> icon (req.) (#1649)

Jaco Greeff 5 yıl önce
ebeveyn
işleme
6f8da05805
71 değiştirilmiş dosya ile 408 ekleme ve 520 silme
  1. 1 1
      packages/app-123code/src/Transfer.tsx
  2. 3 2
      packages/app-accounts/src/Account.tsx
  3. 4 4
      packages/app-accounts/src/Overview.tsx
  4. 5 5
      packages/app-accounts/src/Vanity/index.tsx
  5. 2 3
      packages/app-accounts/src/modals/Backup.tsx
  6. 2 2
      packages/app-accounts/src/modals/ChangePass.tsx
  7. 2 2
      packages/app-accounts/src/modals/Create.tsx
  8. 2 2
      packages/app-accounts/src/modals/CreateConfirmation.tsx
  9. 2 2
      packages/app-accounts/src/modals/Import.tsx
  10. 2 2
      packages/app-accounts/src/modals/Qr.tsx
  11. 2 2
      packages/app-accounts/src/modals/Transfer.tsx
  12. 3 2
      packages/app-address-book/src/Address.tsx
  13. 1 1
      packages/app-address-book/src/Overview.tsx
  14. 2 2
      packages/app-address-book/src/modals/Create.tsx
  15. 2 2
      packages/app-claims/src/index.tsx
  16. 1 1
      packages/app-contracts/src/Codes/Add.tsx
  17. 1 1
      packages/app-contracts/src/Codes/Code.tsx
  18. 1 1
      packages/app-contracts/src/Codes/Upload.tsx
  19. 2 2
      packages/app-contracts/src/Codes/index.tsx
  20. 1 1
      packages/app-contracts/src/Contracts/Add.tsx
  21. 2 2
      packages/app-contracts/src/Contracts/Call.tsx
  22. 2 2
      packages/app-contracts/src/Contracts/Contract.tsx
  23. 2 2
      packages/app-contracts/src/Contracts/index.tsx
  24. 8 2
      packages/app-contracts/src/Deploy.tsx
  25. 1 1
      packages/app-contracts/src/Modal.tsx
  26. 2 2
      packages/app-contracts/src/RemoveABI.tsx
  27. 1 1
      packages/app-council/src/Motions/Propose.tsx
  28. 1 1
      packages/app-council/src/Overview/SubmitCandidacy.tsx
  29. 2 2
      packages/app-council/src/Overview/Vote.tsx
  30. 3 3
      packages/app-democracy/src/Overview/Seconding.tsx
  31. 4 4
      packages/app-democracy/src/Overview/Voting.tsx
  32. 1 1
      packages/app-democracy/src/Propose.tsx
  33. 2 2
      packages/app-extrinsics/src/Selection.tsx
  34. 1 1
      packages/app-generic-asset/src/Assets.tsx
  35. 64 80
      packages/app-generic-asset/src/Transfer.tsx
  36. 43 98
      packages/app-generic-asset/src/modals/Create.tsx
  37. 1 0
      packages/app-js/src/ActionButtons.tsx
  38. 2 2
      packages/app-settings/src/Developer.tsx
  39. 2 2
      packages/app-settings/src/General.tsx
  40. 2 2
      packages/app-staking/src/Actions/Account/BondExtra.tsx
  41. 23 38
      packages/app-staking/src/Actions/Account/InputValidationUnstakeThreshold.tsx
  42. 2 2
      packages/app-staking/src/Actions/Account/Nominate.tsx
  43. 2 2
      packages/app-staking/src/Actions/Account/SetControllerAccount.tsx
  44. 2 2
      packages/app-staking/src/Actions/Account/SetRewardDestination.tsx
  45. 2 2
      packages/app-staking/src/Actions/Account/SetSessionAccount.tsx
  46. 2 2
      packages/app-staking/src/Actions/Account/Unbond.tsx
  47. 2 2
      packages/app-staking/src/Actions/Account/Validate.tsx
  48. 4 4
      packages/app-staking/src/Actions/Account/index.tsx
  49. 1 1
      packages/app-staking/src/Actions/Accounts.tsx
  50. 2 2
      packages/app-staking/src/Actions/NewStake.tsx
  51. 1 1
      packages/app-sudo/src/SetKey.tsx
  52. 1 1
      packages/app-sudo/src/Sudo.tsx
  53. 1 1
      packages/app-toolbox/src/Rpc/Selection.tsx
  54. 1 1
      packages/app-toolbox/src/Sign.tsx
  55. 2 2
      packages/app-toolbox/src/Unlock.tsx
  56. 1 1
      packages/app-treasury/src/Overview/Approve.tsx
  57. 1 1
      packages/app-treasury/src/Overview/Propose.tsx
  58. 2 2
      packages/app-treasury/src/Settings.tsx
  59. 10 14
      packages/react-api/src/with/callDiv.tsx
  60. 47 56
      packages/react-components/src/Button/Button.tsx
  61. 16 20
      packages/react-components/src/Button/Group.tsx
  62. 1 2
      packages/react-components/src/Button/types.ts
  63. 2 2
      packages/react-components/src/Forget.tsx
  64. 77 96
      packages/react-components/src/InputFile.tsx
  65. 1 0
      packages/react-components/src/InputNumber.tsx
  66. 1 1
      packages/react-components/src/Messages.tsx
  67. 7 5
      packages/react-components/src/TxButton.tsx
  68. 2 2
      packages/react-components/src/TxModal.tsx
  69. 1 1
      packages/react-components/src/Voting.tsx
  70. 2 2
      packages/react-params/src/Param/Vector.tsx
  71. 2 2
      packages/react-signer/src/Modal.tsx

+ 1 - 1
packages/app-123code/src/Transfer.tsx

@@ -42,8 +42,8 @@ export default class Transfer extends TxComponent<Props, State> {
             <Button.Group>
               <TxButton
                 accountId={accountId}
+                icon='send'
                 label='make transfer'
-                labelIcon='send'
                 params={[recipientId, amount]}
                 tx='balances.transfer'
                 ref={this.button}

+ 3 - 2
packages/app-accounts/src/Account.tsx

@@ -7,7 +7,7 @@ import { I18nProps } from '@polkadot/react-components/types';
 
 import React, { useState, useEffect } from 'react';
 import styled from 'styled-components';
-import { AddressCard, AddressInfo, Button, ChainLock, Forget, Icon } from '@polkadot/react-components';
+import { AddressCard, AddressInfo, Button, ChainLock, Forget } from '@polkadot/react-components';
 import keyring from '@polkadot/ui-keyring';
 
 import Backup from './modals/Backup';
@@ -101,8 +101,9 @@ function Account ({ address, className, t }: Props): React.ReactElement<Props> {
               </>
             )}
             <Button
+              icon='paper plane'
               isPrimary
-              label={<><Icon name='paper plane' /> {t('send')}</>}
+              label={t('send')}
               onClick={_toggleTransfer}
               size='small'
               tooltip={t('Send funds from this account')}

+ 4 - 4
packages/app-accounts/src/Overview.tsx

@@ -52,32 +52,32 @@ function Overview ({ accounts = [], onStatusChange, t }: Props): React.ReactElem
       buttons={
         <Button.Group>
           <Button
+            icon='add'
             isPrimary
             label={t('Add account')}
-            labelIcon='add'
             onClick={_toggleCreate}
           />
           <Button.Or />
           <Button
+            icon='sync'
             isPrimary
             label={t('Restore JSON')}
-            labelIcon='sync'
             onClick={_toggleImport}
           />
           <Button.Or />
           <Button
+            icon='qrcode'
             isPrimary
             label={t('Add via Qr')}
-            labelIcon='qrcode'
             onClick={_toggleQr}
           />
           {isLedger() && (
             <>
               <Button.Or />
               <Button
+                icon='question'
                 isPrimary
                 label={t('Query Ledger')}
-                labelIcon='question'
                 onClick={queryLedger}
               />
             </>

+ 5 - 5
packages/app-accounts/src/Vanity/index.tsx

@@ -95,6 +95,11 @@ class VanityApp extends TxComponent<Props, State> {
     return (
       <Button.Group>
         <Button
+          icon={
+            isRunning
+              ? 'stop'
+              : 'sign-in'
+          }
           isDisabled={!isMatchValid}
           isPrimary={!isRunning}
           onClick={this.toggleStart}
@@ -103,11 +108,6 @@ class VanityApp extends TxComponent<Props, State> {
               ? t('Stop generation')
               : t('Start generation')
           }
-          labelIcon={
-            isRunning
-              ? 'stop'
-              : 'sign-in'
-          }
           ref={this.button}
         />
       </Button.Group>

+ 2 - 3
packages/app-accounts/src/modals/Backup.tsx

@@ -52,17 +52,16 @@ class Backup extends TxComponent<Props, State> {
       <Modal.Actions>
         <Button.Group>
           <Button
+            icon='cancel'
             isNegative
             label={t('Cancel')}
-            labelIcon='cancel'
             onClick={onClose}
           />
           <Button.Or />
           <Button
+            icon='download'
             isDisabled={!isPassValid}
-            isPrimary
             label={t('Download')}
-            labelIcon='download'
             onClick={this.doBackup}
             ref={this.button}
           />

+ 2 - 2
packages/app-accounts/src/modals/ChangePass.tsx

@@ -55,17 +55,17 @@ class ChangePass extends TxComponent<Props, State> {
       <Modal.Actions>
         <Button.Group>
           <Button
+            icon='cancel'
             isNegative
             label={t('Cancel')}
-            labelIcon='cancel'
             onClick={onClose}
           />
           <Button.Or />
           <Button
+            icon='sign-in'
             isDisabled={!isNewValid || !isOldValid}
             isPrimary
             label={t('Change')}
-            labelIcon='sign-in'
             onClick={this.doChange}
             ref={this.button}
           />

+ 2 - 2
packages/app-accounts/src/modals/Create.tsx

@@ -170,17 +170,17 @@ class Create extends React.PureComponent<Props, State> {
         <Modal.Actions>
           <Button.Group>
             <Button
+              icon='cancel'
               isNegative
               label={t('Cancel')}
-              labelIcon='cancel'
               onClick={this.onDiscard}
             />
             <Button.Or />
             <Button
+              icon='plus'
               isDisabled={!isValid}
               isPrimary
               label={t('Save')}
-              labelIcon='plus'
               onClick={this.onShowWarning}
             />
           </Button.Group>

+ 2 - 2
packages/app-accounts/src/modals/CreateConfirmation.tsx

@@ -38,16 +38,16 @@ function CreateConfirmation ({ address, name, onCommit, onHideWarning, t }: Prop
       <Modal.Actions>
         <Button.Group>
           <Button
+            icon='cancel'
             isNegative
             label={t('Cancel')}
-            labelIcon='cancel'
             onClick={onHideWarning}
           />
           <Button.Or />
           <Button
+            icon='plus'
             isPrimary
             label={t('Create and backup account')}
-            labelIcon='plus'
             onClick={onCommit}
           />
         </Button.Group>

+ 2 - 2
packages/app-accounts/src/modals/Import.tsx

@@ -48,18 +48,18 @@ class Import extends TxComponent<Props, State> {
         <Modal.Actions>
           <Button.Group>
             <Button
+              icon='cancel'
               isNegative
               label={t('Cancel')}
-              labelIcon='cancel'
               onClick={onClose}
             />
             <Button.Or />
             <Button
+              icon='sync'
               isDisabled={!isFileValid || !isPassValid}
               isPrimary
               onClick={this.onSave}
               label={t('Restore')}
-              labelIcon='sync'
               ref={this.button}
             />
           </Button.Group>

+ 2 - 2
packages/app-accounts/src/modals/Qr.tsx

@@ -86,18 +86,18 @@ function QrModal ({ className, onClose, onStatusChange, t }: Props): React.React
       <Modal.Actions>
         <Button.Group>
           <Button
+            icon='cancel'
             isNegative
             label={t('Cancel')}
-            labelIcon='cancel'
             onClick={onClose}
           />
           <Button.Or />
           <Button
+            icon='sign-in'
             isDisabled={!scanned || !isNameValid}
             isPrimary
             onClick={_onSave}
             label={t('Create')}
-            labelIcon='sign-in'
           />
         </Button.Group>
       </Modal.Actions>

+ 2 - 2
packages/app-accounts/src/modals/Transfer.tsx

@@ -121,19 +121,19 @@ class Transfer extends React.PureComponent<Props, State> {
         <Modal.Actions>
           <Button.Group>
             <Button
+              icon='cancel'
               isNegative
               label={t('Cancel')}
-              labelIcon='cancel'
               onClick={onClose}
             />
             <Button.Or />
             <TxButton
               accountId={senderId}
               extrinsic={extrinsic}
+              icon='send'
               isDisabled={!hasAvailable}
               isPrimary
               label={t('Make Transfer')}
-              labelIcon='send'
               onStart={onClose}
               withSpinner={false}
             />

+ 3 - 2
packages/app-address-book/src/Address.tsx

@@ -8,7 +8,7 @@ import { I18nProps } from '@polkadot/react-components/types';
 
 import React from 'react';
 import styled from 'styled-components';
-import { AddressCard, AddressInfo, Button, ChainLock, Forget, Icon } from '@polkadot/react-components';
+import { AddressCard, AddressInfo, Button, ChainLock, Forget } from '@polkadot/react-components';
 import keyring from '@polkadot/ui-keyring';
 
 import Transfer from '@polkadot/app-accounts/modals/Transfer';
@@ -69,9 +69,10 @@ class Address extends React.PureComponent<Props, State> {
                 />
               )}
               <Button
+                icon='paper plane'
                 isPrimary
                 key='deposit'
-                label={<><Icon name='paper plane' /> {t('deposit')}</>}
+                label={t('deposit')}
                 onClick={this.toggleTransfer}
                 size='small'
                 tooltip={t('Send funds to this address')}

+ 1 - 1
packages/app-address-book/src/Overview.tsx

@@ -30,9 +30,9 @@ function Overview ({ addresses, onStatusChange, t }: Props): React.ReactElement<
       buttons={
         <Button.Group>
           <Button
+            icon='add'
             isPrimary
             label={t('Add contact')}
-            labelIcon='add'
             onClick={_toggleCreate}
           />
         </Button.Group>

+ 2 - 2
packages/app-address-book/src/modals/Create.tsx

@@ -76,18 +76,18 @@ class Create extends React.PureComponent<Props, State> {
         <Modal.Actions>
           <Button.Group>
             <Button
+              icon='cancel'
               isNegative
               onClick={this.onDiscard}
               label={t('Cancel')}
-              labelIcon='cancel'
             />
             <Button.Or />
             <Button
+              icon='save'
               isDisabled={!isValid}
               isPrimary
               onClick={this.onCommit}
               label={t('Save')}
-              labelIcon='save'
             />
           </Button.Group>
         </Modal.Actions>

+ 2 - 2
packages/app-claims/src/index.tsx

@@ -132,10 +132,10 @@ class App extends TxModal<Props, State> {
               {(step === Step.Account) && (
                 <Button.Group>
                   <Button
+                    icon='sign-in'
                     isPrimary
                     onClick={this.setStep(Step.Sign)}
                     label={t('Continue')}
-                    labelIcon='sign-in'
                   />
                 </Button.Group>
               )}
@@ -171,11 +171,11 @@ class App extends TxModal<Props, State> {
                 {(step === Step.Sign) && (
                   <Button.Group>
                     <Button
+                      icon='sign-in'
                       isDisabled={!accountId || !signature}
                       isPrimary
                       onClick={this.setStep(Step.Claim)}
                       label={t('Confirm claim')}
-                      labelIcon='sign-in'
                     />
                   </Button.Group>
                 )}

+ 1 - 1
packages/app-contracts/src/Codes/Add.tsx

@@ -65,10 +65,10 @@ class Add extends ContractModal<Props, State> {
       <Button.Group>
         {this.renderCancelButton()}
         <Button
+          icon='save'
           isDisabled={!isValid}
           isPrimary
           label={t('Save')}
-          labelIcon='save'
           onClick={this.onSave}
           ref={this.button}
         />

+ 1 - 1
packages/app-contracts/src/Codes/Code.tsx

@@ -74,9 +74,9 @@ class Contract extends React.PureComponent<Props, State> {
           tooltip={t('Forget this code hash')}
         />
         <Button
+          icon='cloud upload'
           isPrimary
           label={t('deploy')}
-          labelIcon='cloud upload'
           onClick={showDeploy(codeHash)}
           size='small'
           tooltip={t('Deploy this code hash as a smart contract')}

+ 1 - 1
packages/app-contracts/src/Codes/Upload.tsx

@@ -73,10 +73,10 @@ class Upload extends ContractModal<Props, State> {
         {this.renderCancelButton()}
         <TxButton
           accountId={accountId}
+          icon='upload'
           isDisabled={!isValid}
           isPrimary
           label={t('Upload')}
-          labelIcon='upload'
           onClick={this.toggleBusy(true)}
           onSuccess={this.onSuccess}
           onFailed={this.toggleBusy(false)}

+ 2 - 2
packages/app-contracts/src/Codes/index.tsx

@@ -39,15 +39,15 @@ class Codes extends React.PureComponent<Props, State> {
           buttons={
             <Button.Group>
               <Button
+                icon='upload'
                 isPrimary
                 label={t('Upload WASM')}
-                labelIcon='upload'
                 onClick={this.showUpload}
               />
               <Button.Or />
               <Button
+                icon='add'
                 label={t('Add an existing code hash')}
-                labelIcon='add'
                 onClick={this.showAdd}
               />
             </Button.Group>

+ 1 - 1
packages/app-contracts/src/Contracts/Add.tsx

@@ -78,10 +78,10 @@ class Add extends ContractModal<Props, State> {
       <Button.Group>
         {this.renderCancelButton()}
         <Button
+          icon='save'
           isDisabled={!isValid}
           isPrimary
           label={t('Save')}
-          labelIcon='save'
           onClick={this.onAdd}
           ref={this.button}
         />

+ 2 - 2
packages/app-contracts/src/Contracts/Call.tsx

@@ -189,18 +189,18 @@ class Call extends TxComponent<Props, State> {
     return (
       <Button.Group>
         <Button
+          icon='cancel'
           isNegative
           onClick={this.onClose}
           label={t('Cancel')}
-          labelIcon='cancel'
         />
         <Button.Or />
         <TxButton
           accountId={accountId}
+          icon='sign-in'
           isDisabled={!isValid}
           isPrimary
           label={t('Call')}
-          labelIcon='sign-in'
           onClick={this.toggleBusy}
           onFailed={this.toggleBusy}
           onSuccess={this.toggleBusy}

+ 2 - 2
packages/app-contracts/src/Contracts/Contract.tsx

@@ -128,16 +128,16 @@ class Contract extends React.PureComponent<Props, State> {
     return (
       <div className='contracts--Contract-buttons'>
         <Button
+          icon='trash'
           isNegative
           onClick={this.toggleForget}
-          icon='trash'
           size='small'
           tooltip={t('Forget this contract')}
         />
         <Button
+          icon='play'
           isPrimary
           label={t('execute')}
-          labelIcon='play'
           onClick={(): void => onCall(address)}
           size='small'
           tooltip={t('Call a method on this contract')}

+ 2 - 2
packages/app-contracts/src/Contracts/index.tsx

@@ -45,18 +45,18 @@ class Contracts extends React.PureComponent<Props, State> {
               {hasCode && (
                 <>
                   <Button
+                    icon='cloud upload'
                     isPrimary
                     label={t('Deploy a code hash')}
-                    labelIcon='cloud upload'
                     onClick={showDeploy()}
                   />
                   <Button.Or />
                 </>
               )}
               <Button
+                icon='add'
                 isPrimary
                 label={t('Add an existing contract')}
-                labelIcon='add'
                 onClick={this.showAdd}
               />
             </Button.Group>

+ 8 - 2
packages/app-contracts/src/Deploy.tsx

@@ -202,15 +202,21 @@ class Deploy extends ContractModal<Props, State> {
         {this.renderCancelButton()}
         <TxButton
           accountId={accountId}
+          icon='cloud upload'
           isDisabled={!isValid}
           isPrimary
           label={t('Deploy')}
-          labelIcon='cloud upload'
           onClick={this.toggleBusy(true)}
           onFailed={this.toggleBusy(false)}
           onSuccess={this.onSuccess}
           params={this.constructCall}
-          tx={api.tx.contracts ? (api.tx.contracts.instantiate ? 'contracts.instantiate' : 'contracts.create') : 'contract.create'}
+          tx={
+            api.tx.contracts
+              ? api.tx.contracts.instantiate
+                ? 'contracts.instantiate' // V2 (new)
+                : 'contracts.create' // V2 (old)
+              : 'contract.create' // V1
+          }
           ref={this.button}
         />
       </Button.Group>

+ 1 - 1
packages/app-contracts/src/Modal.tsx

@@ -169,10 +169,10 @@ class ContractModal<P extends ContractModalProps, S extends ContractModalState>
     return (
       <>
         <Button
+          icon='cancel'
           isNegative
           onClick={this.onClose}
           label={t('Cancel')}
-          labelIcon='cancel'
         />
         <Button.Or />
       </>

+ 2 - 2
packages/app-contracts/src/RemoveABI.tsx

@@ -46,14 +46,14 @@ function RemoveABI ({ code, onClose, onRemove, t }: Props): React.ReactElement<P
             isNegative
             onClick={onClose}
             label={t('Cancel')}
-            labelIcon='cancel'
+            icon='cancel'
           />
           <Button.Or />
           <Button
             isPrimary
             onClick={_onRemove}
             label={t('Remove')}
-            labelIcon='trash'
+            icon='trash'
           />
         </Button.Group>
       </Modal.Actions>

+ 1 - 1
packages/app-council/src/Motions/Propose.tsx

@@ -76,7 +76,7 @@ class Propose extends TxModal<Props, State> {
         <Button
           isPrimary
           label={t('Propose a council motion')}
-          labelIcon='add'
+          icon='add'
           onClick={this.showModal}
         />
       </Button.Group>

+ 1 - 1
packages/app-council/src/Overview/SubmitCandidacy.tsx

@@ -43,7 +43,7 @@ class SubmitCandidacy extends TxModal<Props, State> {
       <Button
         isPrimary
         label={t('Submit candidacy')}
-        labelIcon='add'
+        icon='add'
         onClick={this.showModal}
       />
     );

+ 2 - 2
packages/app-council/src/Overview/Vote.tsx

@@ -161,7 +161,7 @@ class Vote extends TxModal<Props, State> {
         isDisabled={candidates.length === 0}
         isPrimary
         label={t('Vote')}
-        labelIcon='check'
+        icon='check'
         onClick={this.showModal}
       />
     );
@@ -185,7 +185,7 @@ class Vote extends TxModal<Props, State> {
                   accountId={accountId}
                   isNegative
                   label={t('Retract vote')}
-                  labelIcon='delete'
+                  icon='delete'
                   onSuccess={this.onRetractVote}
                   params={[voterPositions[accountId].globalIndex]}
                   tx='elections.retractVoter'

+ 3 - 3
packages/app-democracy/src/Overview/Seconding.tsx

@@ -56,7 +56,7 @@ function Seconding ({ allAccounts, depositors, proposalId, t }: Props): React.Re
                 isNegative
                 onClick={_toggleSeconding}
                 label={t('Cancel')}
-                labelIcon='cancel'
+                icon='cancel'
               />
               <Button.Or />
               <TxButton
@@ -64,7 +64,7 @@ function Seconding ({ allAccounts, depositors, proposalId, t }: Props): React.Re
                 isDisabled={!accountId || isDepositor}
                 isPrimary
                 label={t('Second')}
-                labelIcon='sign-in'
+                icon='sign-in'
                 onClick={_toggleSeconding}
                 params={[proposalId]}
                 tx='democracy.second'
@@ -77,7 +77,7 @@ function Seconding ({ allAccounts, depositors, proposalId, t }: Props): React.Re
         <Button
           isPrimary
           label={t('Second proposal')}
-          labelIcon='toggle off'
+          icon='toggle off'
           onClick={_toggleSeconding}
         />
       </div>

+ 4 - 4
packages/app-democracy/src/Overview/Voting.tsx

@@ -61,18 +61,18 @@ function Voting ({ allAccounts, referendumId, t }: Props): React.ReactElement<Pr
           <Modal.Actions>
             <Button.Group>
               <Button
+                icon='cancel'
                 isNegative
-                onClick={_toggleVoting}
                 label={t('Cancel')}
-                labelIcon='cancel'
+                onClick={_toggleVoting}
               />
               <Button.Or />
               <TxButton
                 accountId={accountId}
+                icon='check'
                 isDisabled={!accountId}
                 isPrimary
                 label={t('Vote')}
-                labelIcon='check'
                 onClick={_toggleVoting}
                 params={[referendumId, voteValue]}
                 tx='democracy.vote'
@@ -83,9 +83,9 @@ function Voting ({ allAccounts, referendumId, t }: Props): React.ReactElement<Pr
       )}
       <div className='ui--Row-buttons'>
         <Button
+          icon='check'
           isPrimary
           label={t('Vote')}
-          labelIcon='check'
           onClick={_toggleVoting}
         />
       </div>

+ 1 - 1
packages/app-democracy/src/Propose.tsx

@@ -66,7 +66,7 @@ class Propose extends TxComponent<Props, State> {
           <TxButton
             accountId={accountId}
             label={t('Submit Proposal')}
-            labelIcon='sign-in'
+            icon='sign-in'
             tx='democracy.propose'
             isDisabled={!isValid}
             params={[

+ 2 - 2
packages/app-extrinsics/src/Selection.tsx

@@ -79,7 +79,7 @@ class Selection extends TxComponent<Props, State> {
             isDisabled={!isValidUnsigned}
             isUnsigned
             label={t('Submit Unsigned')}
-            labelIcon='sign-in'
+            icon='sign-in'
             extrinsic={extrinsic}
           />
           <Button.Or />
@@ -88,7 +88,7 @@ class Selection extends TxComponent<Props, State> {
             isDisabled={!isValid}
             isPrimary
             label={t('Submit Transaction')}
-            labelIcon='sign-in'
+            icon='sign-in'
             extrinsic={extrinsic}
             ref={this.button}
           />

+ 1 - 1
packages/app-generic-asset/src/Assets.tsx

@@ -34,7 +34,7 @@ function Assets ({ assets, t }: Props): React.ReactElement<Props> {
           <Button
             isPrimary
             label={t('Register Asset')}
-            labelIcon='registered'
+            icon='registered'
             onClick={_toggleCreate}
           />
         </Button.Group>

+ 64 - 80
packages/app-generic-asset/src/Transfer.tsx

@@ -53,10 +53,72 @@ class Transfer extends React.PureComponent<Props> {
   }
 
   public render (): React.ReactNode {
+    const { assets, className, onClose, recipientId: propRecipientId, senderId: propSenderId, t } = this.props;
+    const { extrinsic, hasAvailable, recipientId, senderId, assetId } = this.state;
+    const available = <span className='label'>{t('available ')}</span>;
+    const options = assets
+      ? Object.entries(assets)
+        .map(([id, name]): { value: string; text: string } => ({
+          value: id,
+          text: `${name} (${id})`
+        }))
+      : [];
+
     return (
       <div>
-        {this.renderContent()}
-        {this.renderButtons()}
+        <div className={className}>
+          <InputAddress
+            defaultValue={propSenderId}
+            help={t('The account you will send funds from.')}
+            isDisabled={!!propSenderId}
+            label={t('send from account')}
+            labelExtra={<Available label={available} params={senderId} />}
+            onChange={this.onChangeFrom}
+            type='account'
+          />
+          <InputAddress
+            defaultValue={propRecipientId}
+            help={t('Select a contact or paste the address you want to send funds to.')}
+            isDisabled={!!propRecipientId}
+            label={t('send to address')}
+            labelExtra={<Available label={available} params={recipientId} />}
+            onChange={this.onChangeTo}
+            type='allPlus'
+          />
+          <Dropdown
+            allowAdd
+            help={t('Enter the Asset ID of the token you want to transfer.')}
+            label={t('asset id')}
+            onChange={this.onChangeAssetId}
+            options={options}
+            onAdd={this.onAddAssetId}
+            value={assetId}
+          />
+          <InputBalance
+            help={t('Type the amount you want to transfer. Note that you can select the unit on the right e.g sending 1 mili is equivalent to sending 0.001.')}
+            isError={!hasAvailable}
+            label={t('amount')}
+            onChange={this.onChangeAmount}
+          />
+          <Checks
+            accountId={senderId}
+            extrinsic={extrinsic}
+            isSendable
+            onChange={this.onChangeFees}
+          />
+        </div>
+        <Button.Group>
+          <TxButton
+            accountId={senderId}
+            extrinsic={extrinsic}
+            isDisabled={!hasAvailable}
+            isPrimary
+            label={t('Make Transfer')}
+            icon='send'
+            onStart={onClose}
+            withSpinner={false}
+          />
+        </Button.Group>
       </div>
     );
   }
@@ -86,84 +148,6 @@ class Transfer extends React.PureComponent<Props> {
     });
   }
 
-  private renderButtons (): React.ReactNode {
-    const { onClose, t } = this.props;
-    const { extrinsic, hasAvailable, senderId } = this.state;
-
-    return (
-      <Button.Group>
-        <TxButton
-          accountId={senderId}
-          extrinsic={extrinsic}
-          isDisabled={!hasAvailable}
-          isPrimary
-          label={t('Make Transfer')}
-          labelIcon='send'
-          onStart={onClose}
-          withSpinner={false}
-        />
-      </Button.Group>
-    );
-  }
-
-  private renderContent (): React.ReactNode {
-    const { assets, className, recipientId: propRecipientId, senderId: propSenderId, t } = this.props;
-    const { extrinsic, hasAvailable, recipientId, senderId, assetId } = this.state;
-    const available = <span className='label'>{t('available ')}</span>;
-
-    const options = assets
-      ? Object.entries(assets)
-        .map(([id, name]): { value: string; text: string } => ({
-          value: id,
-          text: `${name} (${id})`
-        }))
-      : [];
-
-    return (
-      <div className={className}>
-        <InputAddress
-          defaultValue={propSenderId}
-          help={t('The account you will send funds from.')}
-          isDisabled={!!propSenderId}
-          label={t('send from account')}
-          labelExtra={<Available label={available} params={senderId} />}
-          onChange={this.onChangeFrom}
-          type='account'
-        />
-        <InputAddress
-          defaultValue={propRecipientId}
-          help={t('Select a contact or paste the address you want to send funds to.')}
-          isDisabled={!!propRecipientId}
-          label={t('send to address')}
-          labelExtra={<Available label={available} params={recipientId} />}
-          onChange={this.onChangeTo}
-          type='allPlus'
-        />
-        <Dropdown
-          allowAdd
-          help={t('Enter the Asset ID of the token you want to transfer.')}
-          label={t('asset id')}
-          onChange={this.onChangeAssetId}
-          options={options}
-          onAdd={this.onAddAssetId}
-          value={assetId}
-        />
-        <InputBalance
-          help={t('Type the amount you want to transfer. Note that you can select the unit on the right e.g sending 1 mili is equivalent to sending 0.001.')}
-          isError={!hasAvailable}
-          label={t('amount')}
-          onChange={this.onChangeAmount}
-        />
-        <Checks
-          accountId={senderId}
-          extrinsic={extrinsic}
-          isSendable
-          onChange={this.onChangeFees}
-        />
-      </div>
-    );
-  }
-
   private onChangeAmount = (amount: BN = new BN(0)): void => {
     this.nextState({ amount });
   }

+ 43 - 98
packages/app-generic-asset/src/modals/Create.tsx

@@ -2,10 +2,10 @@
 // This software may be modified and distributed under the terms
 // of the Apache-2.0 license. See the LICENSE file for details.
 
-import BN from 'bn.js';
-import React from 'react';
-
 import { I18nProps } from '@polkadot/react-components/types';
+
+import BN from 'bn.js';
+import React, { useState } from 'react';
 import { InputNumber, Button, Input, Modal } from '@polkadot/react-components';
 
 import translate from '../translate';
@@ -15,74 +15,30 @@ export interface ModalProps {
   onRegister: (id: BN, name: string) => void;
 }
 
-type Props = ModalProps & I18nProps;
-
-interface State {
-  assetId: BN;
-  name: string;
-}
-
-class Create extends React.PureComponent<Props, State> {
-  public state: State;
-
-  public constructor (props: Props) {
-    super(props);
-
-    this.state = this.emptyState();
-  }
-
-  public render (): React.ReactNode {
-    const { t } = this.props;
-
-    return (
-      <Modal
-        dimmer='inverted'
-        open
-      >
-        <Modal.Header>{t('Register an Asset')}</Modal.Header>
-        {this.renderContent()}
-        {this.renderButtons()}
-      </Modal>
-    );
-  }
-
-  private renderButtons (): React.ReactNode {
-    const { t } = this.props;
-    const { name } = this.state;
-
-    return (
-      <Modal.Actions>
-        <Button.Group>
-          <Button
-            isNegative
-            onClick={this.onDiscard}
-            label={t('Cancel')}
-            labelIcon='cancel'
-          />
-          <Button.Or />
-          <Button
-            isDisabled={!name}
-            isPrimary
-            onClick={this.onCommit}
-            label={t('Register')}
-            labelIcon='registered'
-          />
-        </Button.Group>
-      </Modal.Actions>
-    );
-  }
+interface Props extends ModalProps, I18nProps {}
 
-  private renderContent (): React.ReactNode {
-    const { t } = this.props;
-    const { assetId, name } = this.state;
+function Create ({ onClose, onRegister, t }: Props): React.ReactElement<Props> {
+  const [assetId, setAssetId] = useState(new BN(0));
+  const [name, setName] = useState('new asset');
 
-    return (
+  const _onChangeAssetId = (assetId: BN | undefined): void => setAssetId(assetId || new BN(0));
+  const _onCommit = (): void => {
+    onRegister(assetId, name);
+    onClose();
+  };
+
+  return (
+    <Modal
+      dimmer='inverted'
+      open
+    >
+      <Modal.Header>{t('Register an Asset')}</Modal.Header>
       <Modal.Content>
         <InputNumber
           help={t('Enter the Asset ID of the token you want to manage.')}
           label={t('asset id')}
-          onChange={this.onChangeNewAssetId}
-          onEnter={this.onCommit}
+          onChange={_onChangeAssetId}
+          onEnter={_onCommit}
           value={assetId}
         />
         <Input
@@ -90,42 +46,31 @@ class Create extends React.PureComponent<Props, State> {
           help={t('Type the name of this Asset. This name will be used across all the apps. It can be edited later on.')}
           isError={!name}
           label={t('name')}
-          onChange={this.onChangeName}
-          onEnter={this.onCommit}
+          onChange={setName}
+          onEnter={_onCommit}
           value={name}
         />
       </Modal.Content>
-    );
-  }
-
-  private emptyState (): State {
-    return {
-      assetId: new BN(0),
-      name: 'new asset'
-    };
-  }
-
-  private onChangeNewAssetId = (assetId: BN | undefined): void => {
-    this.setState({ assetId: assetId || new BN(0) });
-  }
-
-  private onChangeName = (name: string): void => {
-    this.setState({ name });
-  }
-
-  private onCommit = (): void => {
-    const { onClose, onRegister } = this.props;
-    const { assetId, name } = this.state;
-
-    onRegister(assetId, name);
-    onClose();
-  }
-
-  private onDiscard = (): void => {
-    const { onClose } = this.props;
-
-    onClose();
-  }
+      <Modal.Actions>
+        <Button.Group>
+          <Button
+            isNegative
+            onClick={onClose}
+            label={t('Cancel')}
+            icon='cancel'
+          />
+          <Button.Or />
+          <Button
+            isDisabled={!name}
+            isPrimary
+            onClick={onClose}
+            label={t('Register')}
+            icon='registered'
+          />
+        </Button.Group>
+      </Modal.Actions>
+    </Modal>
+  );
 }
 
 export default translate(Create);

+ 1 - 0
packages/app-js/src/ActionButtons.tsx

@@ -107,6 +107,7 @@ function ActionButtons ({ className, generateLink, isCustomExample, isRunning, r
             withLabel={false}
           />
           <Button
+            icon='save'
             isDisabled={!snippetName.length}
             isPrimary
             label={t('Save snippet to local storage')}

+ 2 - 2
packages/app-settings/src/Developer.tsx

@@ -78,7 +78,7 @@ class Developer extends React.PureComponent<Props, State> {
             isNegative
             onClick={this.clearTypes}
             label={t('Reset')}
-            labelIcon='sync'
+            icon='sync'
           />
           <Button.Or />
           <Button
@@ -86,7 +86,7 @@ class Developer extends React.PureComponent<Props, State> {
             isPrimary
             onClick={this.saveDeveloper}
             label={t('Save')}
-            labelIcon='save'
+            icon='save'
           />
         </Button.Group>
       </div>

+ 2 - 2
packages/app-settings/src/General.tsx

@@ -117,7 +117,7 @@ function General ({ className, isModalContent, onClose, t }: Props): React.React
             <Button
               isNegative
               label={t('Cancel')}
-              labelIcon='cancel'
+              icon='cancel'
               onClick={onClose}
             />
             <Button.Or />
@@ -136,7 +136,7 @@ function General ({ className, isModalContent, onClose, t }: Props): React.React
               ? t('Save & Reload')
               : t('Save')
           }
-          labelIcon='save'
+          icon='save'
         />
       </Button.Group>
     </div>

+ 2 - 2
packages/app-staking/src/Actions/Account/BondExtra.tsx

@@ -75,7 +75,7 @@ class BondExtra extends TxComponent<Props, State> {
               isNegative
               onClick={onClose}
               label={t('Cancel')}
-              labelIcon='cancel'
+              icon='cancel'
             />
             <Button.Or />
             <TxButton
@@ -83,7 +83,7 @@ class BondExtra extends TxComponent<Props, State> {
               isDisabled={!canSubmit}
               isPrimary
               label={t('Bond more')}
-              labelIcon='sign-in'
+              icon='sign-in'
               onClick={onClose}
               extrinsic={extrinsic}
               ref={this.button}

+ 23 - 38
packages/app-staking/src/Actions/Account/InputValidationUnstakeThreshold.tsx

@@ -5,7 +5,7 @@
 import { I18nProps } from '@polkadot/react-components/types';
 
 import BN from 'bn.js';
-import React from 'react';
+import React, { useEffect, useState } from 'react';
 import { Icon } from '@polkadot/react-components';
 
 import translate from '../../translate';
@@ -15,50 +15,35 @@ interface Props extends I18nProps {
   onError: (error: string | null) => void;
 }
 
-interface State {
-  error: string | null;
-}
-
-class InputValidationUnstakeThreshold extends React.PureComponent<Props, State> {
-  public state: State = {
-    error: null
-  };
+function InputValidationUnstakeThreshold ({ onError, t, unstakeThreshold }: Props): React.ReactElement<Props> | null {
+  const [error, setError] = useState<string | null>(null);
 
-  public static getDerivedStateFromProps ({ onError, t, unstakeThreshold }: Props, prevState: State): State | null {
-    let error = null;
+  useEffect((): void => {
+    if (unstakeThreshold) {
+      let newError = null;
 
-    if (!unstakeThreshold) {
-      return null;
-    }
-
-    if (unstakeThreshold.ltn(0)) {
-      error = t('The Threshold must be a positive number');
-    } else if (unstakeThreshold.gtn(10)) {
-      error = t('The Threshold must lower than 11');
-    }
+      if (unstakeThreshold.ltn(0)) {
+        newError = t('The Threshold must be a positive number');
+      } else if (unstakeThreshold.gtn(10)) {
+        newError = t('The Threshold must lower than 11');
+      }
 
-    if (error === prevState.error || !unstakeThreshold) {
-      return null;
+      if (newError !== error) {
+        onError(newError);
+        setError(newError);
+      }
     }
+  }, [unstakeThreshold]);
 
-    onError(error);
-
-    return { error };
+  if (!error) {
+    return null;
   }
 
-  public render (): React.ReactNode {
-    const { error } = this.state;
-
-    if (!error) {
-      return null;
-    }
-
-    return (
-      <article className='warning'>
-        <div><Icon name='warning sign' />{error}</div>
-      </article>
-    );
-  }
+  return (
+    <article className='warning'>
+      <div><Icon name='warning sign' />{error}</div>
+    </article>
+  );
 }
 
 export default translate(InputValidationUnstakeThreshold);

+ 2 - 2
packages/app-staking/src/Actions/Account/Nominate.tsx

@@ -66,7 +66,7 @@ function Nominate ({ controllerId, isOpen, onClose, stashId, stashOptions, t }:
             isNegative
             onClick={onClose}
             label={t('Cancel')}
-            labelIcon='cancel'
+            icon='cancel'
           />
           <Button.Or />
           <TxButton
@@ -76,7 +76,7 @@ function Nominate ({ controllerId, isOpen, onClose, stashId, stashOptions, t }:
             onClick={onClose}
             params={[nominees]}
             label={t('Nominate')}
-            labelIcon='hand paper outline'
+            icon='hand paper outline'
             tx='staking.nominate'
           />
         </Button.Group>

+ 2 - 2
packages/app-staking/src/Actions/Account/SetControllerAccount.tsx

@@ -90,7 +90,7 @@ class SetControllerAccount extends TxComponent<Props, State> {
               isNegative
               onClick={onClose}
               label={t('Cancel')}
-              labelIcon='cancel'
+              icon='cancel'
             />
             <Button.Or />
             <TxButton
@@ -98,7 +98,7 @@ class SetControllerAccount extends TxComponent<Props, State> {
               isDisabled={!canSubmit}
               isPrimary
               label={t('Set controller')}
-              labelIcon='sign-in'
+              icon='sign-in'
               onClick={onClose}
               params={[controllerId]}
               tx='staking.setController'

+ 2 - 2
packages/app-staking/src/Actions/Account/SetRewardDestination.tsx

@@ -49,7 +49,7 @@ class SetRewardDestination extends TxComponent<Props, State> {
               isNegative
               onClick={onClose}
               label={t('Cancel')}
-              labelIcon='cancel'
+              icon='cancel'
             />
             <Button.Or />
             <TxButton
@@ -57,7 +57,7 @@ class SetRewardDestination extends TxComponent<Props, State> {
               isDisabled={!canSubmit}
               isPrimary
               label={t('Set reward destination')}
-              labelIcon='sign-in'
+              icon='sign-in'
               onClick={onClose}
               params={[destination]}
               tx={'staking.setPayee'}

+ 2 - 2
packages/app-staking/src/Actions/Account/SetSessionAccount.tsx

@@ -66,7 +66,7 @@ class SetSessionKey extends React.PureComponent<Props, State> {
               isNegative
               onClick={onClose}
               label={t('Cancel')}
-              labelIcon='cancel'
+              icon='cancel'
             />
             <Button.Or />
             <TxButton
@@ -74,7 +74,7 @@ class SetSessionKey extends React.PureComponent<Props, State> {
               isDisabled={hasError}
               isPrimary
               label={t('Set Session Key')}
-              labelIcon='sign-in'
+              icon='sign-in'
               onClick={onClose}
               params={
                 isSubstrateV2

+ 2 - 2
packages/app-staking/src/Actions/Account/Unbond.tsx

@@ -73,7 +73,7 @@ class Unbond extends TxComponent<Props, State> {
               isNegative
               onClick={onClose}
               label={t('Cancel')}
-              labelIcon='cancel'
+              icon='cancel'
             />
             <Button.Or />
             <TxButton
@@ -81,7 +81,7 @@ class Unbond extends TxComponent<Props, State> {
               isDisabled={!canSubmit}
               isPrimary
               label={t('Unbond')}
-              labelIcon='sign-out'
+              icon='sign-out'
               onClick={onClose}
               params={[maxUnbond]}
               tx='staking.unbond'

+ 2 - 2
packages/app-staking/src/Actions/Account/Validate.tsx

@@ -94,7 +94,7 @@ class Validate extends TxComponent<Props, State> {
           <Button
             isNegative
             label={t('Cancel')}
-            labelIcon='cancel'
+            icon='cancel'
             onClick={onClose}
           />
           <Button.Or />
@@ -103,7 +103,7 @@ class Validate extends TxComponent<Props, State> {
             isDisabled={!!unstakeThresholdError}
             isPrimary
             label={t('Validate')}
-            labelIcon='check circle outline'
+            icon='check circle outline'
             onClick={onClose}
             params={[
               isSubstrateV2

+ 4 - 4
packages/app-staking/src/Actions/Account/index.tsx

@@ -365,7 +365,7 @@ class Account extends React.PureComponent<Props, State> {
               ? t('Stop Nominating')
               : t('Stop Validating')
           }
-          labelIcon='stop'
+          icon='stop'
           key='stop'
           tx='staking.chill'
         />
@@ -378,7 +378,7 @@ class Account extends React.PureComponent<Props, State> {
             key='set'
             onClick={this.toggleSetSessionAccount}
             label={t('Set Session Key')}
-            labelIcon='sign-in'
+            icon='sign-in'
           />
         );
       } else {
@@ -388,7 +388,7 @@ class Account extends React.PureComponent<Props, State> {
             key='validate'
             onClick={this.toggleValidate}
             label={t('Validate')}
-            labelIcon='check circle outline'
+            icon='check circle outline'
           />
         );
       }
@@ -400,7 +400,7 @@ class Account extends React.PureComponent<Props, State> {
           key='nominate'
           onClick={this.toggleNominate}
           label={t('Nominate')}
-          labelIcon='hand paper outline'
+          icon='hand paper outline'
         />
       );
     }

+ 1 - 1
packages/app-staking/src/Actions/Accounts.tsx

@@ -56,7 +56,7 @@ function Accounts ({ allAccounts, allStashes, className, myControllers, recently
           isPrimary
           key='new-stake'
           label={t('New stake')}
-          labelIcon='add'
+          icon='add'
           onClick={_toggleNewStake}
         />
       }

+ 2 - 2
packages/app-staking/src/Actions/NewStake.tsx

@@ -115,7 +115,7 @@ class NewStake extends TxComponent<Props, State> {
               isNegative
               onClick={onClose}
               label={t('Cancel')}
-              labelIcon='cancel'
+              icon='cancel'
             />
             <Button.Or />
             <TxButton
@@ -123,7 +123,7 @@ class NewStake extends TxComponent<Props, State> {
               isDisabled={!canSubmit}
               isPrimary
               label={t('Bond')}
-              labelIcon='sign-in'
+              icon='sign-in'
               onClick={onClose}
               extrinsic={extrinsic}
               ref={this.button}

+ 1 - 1
packages/app-sudo/src/SetKey.tsx

@@ -65,7 +65,7 @@ class SetKey extends React.PureComponent<Props, State> {
                   isDisabled={!isMine || sudoKey === selected}
                   isPrimary
                   label={t('Reassign')}
-                  labelIcon='sign-in'
+                  icon='sign-in'
                   params={[selected]}
                   tx='sudo.setKey'
                 />

+ 1 - 1
packages/app-sudo/src/Sudo.tsx

@@ -47,7 +47,7 @@ class Propose extends TxComponent<Props, State> {
             <TxButton
               accountId={sudoKey}
               label={t('Submit Sudo')}
-              labelIcon='sign-in'
+              icon='sign-in'
               tx='sudo.sudo'
               isDisabled={!method || !isValid}
               params={method ? [createType('Proposal', method)] : []}

+ 1 - 1
packages/app-toolbox/src/Rpc/Selection.tsx

@@ -66,7 +66,7 @@ class Selection extends TxComponent<Props, State> {
             onClick={this.onSubmit}
 
             label={t('Submit RPC call')}
-            labelIcon='sign-in'
+            icon='sign-in'
             ref={this.button}
           />
         </Button.Group>

+ 1 - 1
packages/app-toolbox/src/Sign.tsx

@@ -102,7 +102,7 @@ class Sign extends React.PureComponent<Props, State> {
               isPrimary
               onClick={this.toggleUnlock}
               label={t('Unlock account')}
-              labelIcon='unlock'
+              icon='unlock'
             />
           </Button.Group>
         </div>

+ 2 - 2
packages/app-toolbox/src/Unlock.tsx

@@ -66,14 +66,14 @@ class Unlock extends TxComponent<Props, State> {
             isNegative
             onClick={this.onCancel}
             label={t('Cancel')}
-            labelIcon='cancel'
+            icon='cancel'
           />
           <Button.Or />
           <Button
             isPrimary
             onClick={this.onUnlock}
             label={t('Unlock')}
-            labelIcon='unlock'
+            icon='unlock'
             ref={this.button}
           />
         </Button.Group>

+ 1 - 1
packages/app-treasury/src/Overview/Approve.tsx

@@ -63,7 +63,7 @@ class Approve extends TxModal<Props, State> {
           <Button
             isPrimary
             label={t('Respond')}
-            labelIcon='reply'
+            icon='reply'
             onClick={this.showModal}
           />
         </Button.Group>

+ 1 - 1
packages/app-treasury/src/Overview/Propose.tsx

@@ -49,7 +49,7 @@ class Propose extends TxModal<Props, State> {
         <Button
           isPrimary
           label={t('Submit a spend proposal')}
-          labelIcon='add'
+          icon='add'
           onClick={this.showModal}
         />
       </Button.Group>

+ 2 - 2
packages/app-treasury/src/Settings.tsx

@@ -117,7 +117,7 @@ class Settings extends TxComponent<Props, State> {
               <TxButton
                 accountId={accountId}
                 label={t('Submit')}
-                labelIcon='sign-in'
+                icon='sign-in'
                 tx='treasury.configure'
                 params={[
                   proposalBond.toString(),
@@ -145,7 +145,7 @@ class Settings extends TxComponent<Props, State> {
               <TxButton
                 accountId={accountId}
                 label={t('Submit')}
-                labelIcon='sign-in'
+                icon='sign-in'
                 tx='treasury.setPot'
                 params={[pot]}
               />

+ 10 - 14
packages/react-api/src/with/callDiv.tsx

@@ -16,20 +16,16 @@ interface Props<T> extends BaseProps<T> {
 // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
 export default function withCallDiv<T> (endpoint: string, options: Options = {}) {
   return (render: (value?: T) => React.ReactNode, defaultProps: DefaultProps = {}): React.ComponentType<any> => {
-    class Inner extends React.PureComponent<Props<T>> {
-      public render (): React.ReactNode {
-        const { callResult, callUpdated, children, className = defaultProps.className, label = '', style } = this.props;
-
-        return (
-          <div
-            {...defaultProps}
-            className={[className, callUpdated ? 'rx--updated' : undefined].join(' ')}
-            style={style}
-          >
-            {label}{render(callResult)}{children}
-          </div>
-        );
-      }
+    function Inner ({ callResult, callUpdated, children, className = defaultProps.className, label = '', style }: any): React.ReactElement<Props<T>> {
+      return (
+        <div
+          {...defaultProps}
+          className={[className, callUpdated ? 'rx--updated' : undefined].join(' ')}
+          style={style}
+        >
+          {label}{render(callResult)}{children}
+        </div>
+      );
     }
 
     return withCall(endpoint, { ...options, propName: 'callResult' })(Inner);

+ 47 - 56
packages/react-components/src/Button/Button.tsx

@@ -4,7 +4,7 @@
 
 import { ButtonProps } from './types';
 
-import React from 'react';
+import React, { useState } from 'react';
 import SUIButton from 'semantic-ui-react/dist/commonjs/elements/Button/Button';
 import { isUndefined } from '@polkadot/util';
 
@@ -13,59 +13,50 @@ import Tooltip from '../Tooltip';
 
 let idCounter = 0;
 
-export default class Button extends React.PureComponent<ButtonProps> {
-  private id = `button-${++idCounter}`;
-
-  public render (): React.ReactNode {
-    const { children, className, floated, icon, isBasic = false, isCircular = false, isDisabled = false, isLoading = false, isNegative = false, isPositive = false, isPrimary = false, label, labelIcon, labelPosition, onClick, size, style, tabIndex, tooltip } = this.props;
-
-    const props = {
-      basic: isBasic,
-      circular: isCircular,
-      className,
-      'data-tip': !!tooltip,
-      'data-for': this.id,
-      disabled: isDisabled,
-      floated,
-      icon,
-      labelPosition,
-      loading: isLoading,
-      negative: isNegative,
-      onClick,
-      positive: isPositive,
-      primary: isPrimary,
-      size,
-      secondary: !isBasic && !(isPositive || isPrimary || isNegative),
-      style,
-      tabIndex
-    };
-
-    return (
-      <>
-        {
-          isUndefined(label) && isUndefined(children)
-            ? <SUIButton {...props} />
-            : (
-              <SUIButton {...props}>
-                {!!labelIcon && (
-                  <>
-                    <Icon className={labelIcon} />
-                    {'  '}
-                  </>
-                )}
-                {label}
-                {children}
-              </SUIButton>
-            )
-        }
-        {tooltip && (
-          <Tooltip
-            place='top'
-            text={tooltip}
-            trigger={this.id}
-          />
-        )}
-      </>
-    );
-  }
+export default function Button ({ children, className, floated, icon, isBasic = false, isCircular = false, isDisabled = false, isLoading = false, isNegative = false, isPositive = false, isPrimary = false, label, labelPosition, onClick, size, style, tabIndex, tooltip }: ButtonProps): React.ReactElement<ButtonProps> {
+  const [triggerId] = useState(`button-${++idCounter}`);
+  const props = {
+    basic: isBasic,
+    circular: isCircular,
+    className,
+    'data-tip': !!tooltip,
+    'data-for': triggerId,
+    disabled: isDisabled,
+    floated,
+    labelPosition,
+    loading: isLoading,
+    negative: isNegative,
+    onClick,
+    positive: isPositive,
+    primary: isPrimary,
+    size,
+    secondary: !isBasic && !(isPositive || isPrimary || isNegative),
+    style,
+    tabIndex
+  };
+
+  return (
+    <>
+      {
+        isUndefined(label) && isUndefined(children)
+          ? <SUIButton {...props} icon={icon} />
+          : (
+            <SUIButton {...props}>
+              {icon && (
+                <><Icon className={icon} />{'  '}</>
+              )}
+              {label}
+              {children}
+            </SUIButton>
+          )
+      }
+      {tooltip && (
+        <Tooltip
+          place='top'
+          text={tooltip}
+          trigger={triggerId}
+        />
+      )}
+    </>
+  );
 }

+ 16 - 20
packages/react-components/src/Button/Group.tsx

@@ -11,26 +11,22 @@ import styled from 'styled-components';
 import { classes } from '../util';
 import Divider from './Divider';
 
-class ButtonGroup extends React.PureComponent<GroupProps> {
-  public render (): React.ReactNode {
-    const { children, className, isBasic = false, isCentered = false, style } = this.props;
-
-    return (
-      <div
-        className={classes('ui--Button-Group', isCentered ? 'centered' : '', className)}
-        style={style}
-      >
-        <SUIButton.Group basic={isBasic}>
-          {
-            isBasic
-              ? null
-              : <Divider style={{ padding: '0em' }} />
-          }
-          {children}
-        </SUIButton.Group>
-      </div>
-    );
-  }
+function ButtonGroup ({ children, className, isBasic = false, isCentered = false, style }: GroupProps): React.ReactElement<GroupProps> {
+  return (
+    <div
+      className={classes('ui--Button-Group', isCentered ? 'centered' : '', className)}
+      style={style}
+    >
+      <SUIButton.Group basic={isBasic}>
+        {
+          isBasic
+            ? null
+            : <Divider style={{ padding: '0em' }} />
+        }
+        {children}
+      </SUIButton.Group>
+    </div>
+  );
 }
 
 (ButtonGroup as GroupType).Divider = Divider;

+ 1 - 2
packages/react-components/src/Button/types.ts

@@ -9,7 +9,7 @@ export type Button$Sizes = 'mini' | 'tiny' | 'small' | 'medium' | 'large' | 'big
 export interface ButtonProps extends BareProps {
   children?: React.ReactNode;
   floated?: 'left' | 'right';
-  icon?: string;
+  icon: string;
   isBasic?: boolean;
   isCircular?: boolean;
   isDisabled?: boolean;
@@ -18,7 +18,6 @@ export interface ButtonProps extends BareProps {
   isPositive?: boolean;
   isPrimary?: boolean;
   label?: React.ReactNode;
-  labelIcon?: string;
   labelPosition?: 'left' | 'right';
   onClick?: () => void | Promise<void>;
   ref?: any;

+ 2 - 2
packages/react-components/src/Forget.tsx

@@ -114,14 +114,14 @@ function Forget (props: Props): React.ReactElement<Props> {
             isNegative
             onClick={onClose}
             label={t('Cancel')}
-            labelIcon='cancel'
+            icon='cancel'
           />
           <Button.Or />
           <Button
             isPrimary
             onClick={onForget}
             label={t('Forget')}
-            labelIcon='trash'
+            icon='trash'
           />
         </Button.Group>
       </Modal.Actions>

+ 77 - 96
packages/react-components/src/InputFile.tsx

@@ -5,7 +5,7 @@
 import { WithTranslation } from 'react-i18next';
 import { BareProps } from './types';
 
-import React from 'react';
+import React, { useRef, useState } from 'react';
 import Dropzone from 'react-dropzone';
 import styled from 'styled-components';
 import { formatNumber } from '@polkadot/util';
@@ -29,11 +29,9 @@ interface Props extends BareProps, WithTranslation {
   withLabel?: boolean;
 }
 
-interface State {
-  file?: {
-    name: string;
-    size: number;
-  };
+interface FileState {
+  name: string;
+  size: number;
 }
 
 interface LoadEvent {
@@ -42,70 +40,16 @@ interface LoadEvent {
   };
 }
 
-class InputFile extends React.PureComponent<Props, State> {
-  private dropZone: any;
-
-  public state: State = {};
-
-  public constructor (props: Props) {
-    super(props);
-
-    this.dropZone = React.createRef();
-  }
-
-  public render (): React.ReactNode {
-    const { accept, className, clearContent, help, isDisabled, isError = false, label, placeholder, t, withEllipsis, withLabel } = this.props;
-    const { file } = this.state;
-
-    const dropZone = (
-      <Dropzone
-        accept={accept}
-        className={classes('ui--InputFile', isError ? 'error' : '', className)}
-        disabled={isDisabled}
-        multiple={false}
-        ref={this.dropZone}
-        onDrop={this.onDrop}
-      >
-        <em className='label'>
-          {
-            !file || clearContent
-              ? placeholder || t('click to select or drag and drop the file here')
-              : placeholder || t('{{name}} ({{size}} bytes)', {
-                replace: {
-                  name: file.name,
-                  size: formatNumber(file.size)
-                }
-              })
-          }
-        </em>
-      </Dropzone>
-    );
-
-    return label ? (
-      <Labelled
-        help={help}
-        label={label}
-        withEllipsis={withEllipsis}
-        withLabel={withLabel}
-      >
-        {dropZone}
-      </Labelled>
-    ) : dropZone;
-  }
-
-  private onDrop = (files: File[]): void => {
-    const { onChange } = this.props;
+function InputFile ({ accept, className, clearContent, help, isDisabled, isError = false, label, onChange, placeholder, t, withEllipsis, withLabel }: Props): React.ReactElement<Props> {
+  const dropRef = useRef<Dropzone | null>(null);
+  const [file, setFile] = useState<FileState | undefined>();
 
+  const _onDrop = (files: File[]): void => {
     files.forEach((file): void => {
       const reader = new FileReader();
 
-      reader.onabort = (): void => {
-        // ignore
-      };
-
-      reader.onerror = (): void => {
-        // ignore
-      };
+      reader.onabort = (): void => {};
+      reader.onerror = (): void => {};
 
       // ummm... events are not properly specified here?
       (reader as any).onload = ({ target: { result } }: LoadEvent): void => {
@@ -114,41 +58,78 @@ class InputFile extends React.PureComponent<Props, State> {
 
         onChange && onChange(data, name);
 
-        if (this.dropZone && this.dropZone.current) {
-          this.setState({
-            file: {
-              name,
-              size: data.length
-            }
+        if (dropRef && dropRef.current) {
+          setFile({
+            name,
+            size: data.length
           });
         }
       };
 
       reader.readAsArrayBuffer(file);
     });
-  }
+  };
+
+  const dropZone = (
+    <Dropzone
+      accept={accept}
+      className={classes('ui--InputFile', isError ? 'error' : '', className)}
+      disabled={isDisabled}
+      multiple={false}
+      ref={dropRef}
+      onDrop={_onDrop}
+    >
+      <em className='label'>
+        {
+          !file || clearContent
+            ? placeholder || t('click to select or drag and drop the file here')
+            : placeholder || t('{{name}} ({{size}} bytes)', {
+              replace: {
+                name: file.name,
+                size: formatNumber(file.size)
+              }
+            })
+        }
+      </em>
+    </Dropzone>
+  );
+
+  return label
+    ? (
+      <Labelled
+        help={help}
+        label={label}
+        withEllipsis={withEllipsis}
+        withLabel={withLabel}
+      >
+        {dropZone}
+      </Labelled>
+    )
+    : dropZone;
 }
 
-export default translate(styled(InputFile)`
-  background: #fff;
-  border: 1px solid rgba(34, 36, 38, 0.15);
-  border-radius: 0.28571429rem;
-  font-size: 1rem;
-  margin: 0.25rem 0;
-  padding: 1rem;
-  width: 100% !important;
-
-  &.error {
-    background: #fff6f6;
-    border-color: #e0b4b4;
-  }
-
-  &:hover {
-    background: #fefefe;
-    cursor: pointer;
-  }
-
-  .label {
-    color: rgba(0, 0, 0, .6);
-  }
-`);
+export default translate(
+  styled(InputFile)`
+    background: #fff;
+    border: 1px solid rgba(34, 36, 38, 0.15);
+    border-radius: 0.28571429rem;
+    font-size: 1rem;
+    margin: 0.25rem 0;
+    padding: 1rem;
+    width: 100% !important;
+
+    &.error {
+      background: #fff6f6;
+      border-color: #e0b4b4;
+    }
+
+    &:hover {
+      background: #fefefe;
+      cursor: pointer;
+    }
+
+    .label {
+      color: rgba(0, 0, 0, .6);
+    }
+  `
+);

+ 1 - 0
packages/react-components/src/InputNumber.tsx

@@ -148,6 +148,7 @@ class InputNumber extends React.PureComponent<Props, State> {
     return (
       <Button
         className='ui--MaxButton'
+        icon=''
         onClick={this.setToMaxValue}
       >
         Max

+ 1 - 1
packages/react-components/src/Messages.tsx

@@ -52,7 +52,7 @@ function renderMessage (props: Props, index: number): React.ReactNode {
       isDisabled={!onSelectProp}
       onClick={onSelect(props, index)}
       isPrimary={!!onSelectProp}
-      labelIcon='info'
+      icon='info'
     >
       {name}
       (

+ 7 - 5
packages/react-components/src/TxButton.tsx

@@ -29,7 +29,7 @@ interface Props extends ApiProps {
   accountNonce?: Index;
   className?: string;
   extrinsic?: IExtrinsic | SubmittableExtrinsic;
-  icon?: string;
+  icon: string;
   iconSize?: Button$Sizes;
   isBasic?: boolean;
   isDisabled?: boolean;
@@ -37,7 +37,6 @@ interface Props extends ApiProps {
   isPrimary?: boolean;
   isUnsigned?: boolean;
   label: React.ReactNode;
-  labelIcon?: string;
   onClick?: () => any;
   onFailed?: TxFailedCallback;
   onStart?: () => void;
@@ -62,7 +61,7 @@ class TxButtonInner extends React.PureComponent<InnerProps> {
   };
 
   public render (): React.ReactNode {
-    const { accountId, className, icon, iconSize, isBasic, isDisabled, isNegative, isPrimary, isUnsigned, label, labelIcon, tooltip } = this.props;
+    const { accountId, className, icon, iconSize, isBasic, isDisabled, isNegative, isPrimary, isUnsigned, label, tooltip } = this.props;
     const { isSending } = this.state;
     const needsAccount = isUnsigned
       ? false
@@ -77,9 +76,12 @@ class TxButtonInner extends React.PureComponent<InnerProps> {
         isDisabled={isSending || isDisabled || needsAccount}
         isLoading={isSending}
         isNegative={isNegative}
-        isPrimary={isUndefined(isPrimary) ? (!isNegative && !isBasic) : isPrimary}
+        isPrimary={
+          isUndefined(isPrimary)
+            ? (!isNegative && !isBasic)
+            : isPrimary
+        }
         label={label}
-        labelIcon={labelIcon}
         onClick={this.send}
         size={iconSize}
       />

+ 2 - 2
packages/react-components/src/TxModal.tsx

@@ -157,7 +157,7 @@ export default class TxModal<P extends TxModalProps, S extends TxModalState> ext
         isDisabled={this.isDisabled()}
         isPrimary
         label={this.submitLabel()}
-        labelIcon='sign-in'
+        icon='sign-in'
         onClick={this.onSubmit}
         onFailed={this.onFailed}
         onSuccess={this.onSuccess}
@@ -177,7 +177,7 @@ export default class TxModal<P extends TxModalProps, S extends TxModalState> ext
           isNegative
           onClick={this.hideModal}
           label={t('Cancel')}
-          labelIcon='cancel'
+          icon='cancel'
         />
         <Button.Or />
       </>

+ 1 - 1
packages/react-components/src/Voting.tsx

@@ -115,7 +115,7 @@ class Voting extends TxModal<Props, State> {
         <Button
           isPrimary
           label={t('Vote')}
-          labelIcon='check'
+          icon='check'
           onClick={this.showModal}
         />
       </div>

+ 2 - 2
packages/react-params/src/Param/Vector.tsx

@@ -102,14 +102,14 @@ class Vector extends React.PureComponent<Props, State> {
           isPrimary
           onClick={this.rowAdd}
           label={t('Add item')}
-          labelIcon='add'
+          icon='add'
         />
         <Button
           isDisabled={values.length === 1}
           isNegative
           onClick={this.rowRemove}
           label={t('Remove item')}
-          labelIcon='minus'
+          icon='minus'
         />
       </div>
     );

+ 2 - 2
packages/react-signer/src/Modal.tsx

@@ -156,7 +156,7 @@ class Signer extends React.PureComponent<Props, State> {
             }
             tabIndex={3}
             label={t('Cancel')}
-            labelIcon='cancel'
+            icon='cancel'
           />
           {(!isQrVisible || !isQrScanning) && (
             <>
@@ -182,7 +182,7 @@ class Signer extends React.PureComponent<Props, State> {
                           ? t('Sign via Qr')
                           : t('Sign and Submit')
                 }
-                labelIcon={
+                icon={
                   isQrVisible
                     ? 'qrcode'
                     : currentItem.isUnsigned