Browse Source

Add Expanded component (#1834)

Jaco Greeff 5 years ago
parent
commit
d05eb94052

+ 10 - 19
packages/app-staking/src/Overview/Address.tsx

@@ -11,7 +11,7 @@ import BN from 'bn.js';
 import React, { useContext, useEffect, useState } from 'react';
 import styled from 'styled-components';
 import { ApiContext, withCalls, withMulti } from '@polkadot/react-api';
-import { AddressCard, AddressMini, Badge, Icon } from '@polkadot/react-components';
+import { AddressCard, AddressMini, Badge, Expander, Icon } from '@polkadot/react-components';
 import { classes } from '@polkadot/react-components/util';
 import keyring from '@polkadot/ui-keyring';
 import { formatNumber } from '@polkadot/util';
@@ -48,7 +48,6 @@ const WITH_VALIDATOR_PREFS = { validatorPayment: true };
 function Address ({ address, authorsMap, className, currentElected, defaultName, filter, lastAuthors, points, recentlyOnline, stakingInfo, t, withNominations = true }: Props): React.ReactElement<Props> | null {
   const { isSubstrateV2 } = useContext(ApiContext);
   const [extraInfo, setExtraInfo] = useState<[React.ReactNode, React.ReactNode][] | undefined>();
-  const [isNominationsOpen, setIsNominationsOpen] = useState(false);
   const [{ balanceOpts, controllerId, hasNominators, isNominatorMe, isSelected, nominators, sessionId, stashId }, setStakingState] = useState<StakingState>({
     balanceOpts: { bonded: true },
     hasNominators: false,
@@ -118,13 +117,6 @@ function Address ({ address, authorsMap, className, currentElected, defaultName,
     );
   }
 
-  const _toggleNominations = (event: React.SyntheticEvent): void => {
-    event.preventDefault();
-    event.stopPropagation();
-
-    setIsNominationsOpen(!isNominationsOpen);
-  };
-
   const lastBlockNumber = authorsMap[stashId];
   const isAuthor = lastAuthors && lastAuthors.includes(stashId);
 
@@ -184,15 +176,14 @@ function Address ({ address, authorsMap, className, currentElected, defaultName,
       withValidatorPrefs={WITH_VALIDATOR_PREFS}
     >
       {withNominations && hasNominators && (
-        <details open={isNominationsOpen}>
-          <summary onClick={_toggleNominations}>
-            {t('Nominators ({{count}})', {
-              replace: {
-                count: nominators.length
-              }
-            })}
-          </summary>
-          {isNominationsOpen && nominators.map(([who, bonded]): React.ReactNode =>
+        <Expander
+          summary={t('Nominators ({{count}})', {
+            replace: {
+              count: nominators.length
+            }
+          })}
+        >
+          {nominators.map(([who, bonded]): React.ReactNode =>
             <AddressMini
               bonded={bonded}
               key={who.toString()}
@@ -200,7 +191,7 @@ function Address ({ address, authorsMap, className, currentElected, defaultName,
               withBonded
             />
           )}
-        </details>
+        </Expander>
       )}
     </AddressCard>
   );

+ 4 - 1
packages/app-staking/src/Overview/CurrentList.tsx

@@ -10,6 +10,7 @@ import { ValidatorFilter } from '../types';
 import React, { useContext, useEffect, useState } from 'react';
 import { ApiContext } from '@polkadot/react-api';
 import { Columar, Column, Dropdown, FilterOverlay } from '@polkadot/react-components';
+import { createType } from '@polkadot/types';
 
 import translate from '../translate';
 import Address from './Address';
@@ -22,6 +23,8 @@ interface Props extends I18nProps {
   stakingOverview?: DerivedStakingOverview;
 }
 
+const EMPTY_POINTS = createType('Points');
+
 function renderColumn (addresses: AccountId[] | string[], defaultName: string, withOnline: boolean, withPoints: boolean, filter: string, { authorsMap, lastAuthors, recentlyOnline, stakingOverview }: Props): React.ReactNode {
   return (addresses as AccountId[]).map((address, index): React.ReactNode => (
     <Address
@@ -34,7 +37,7 @@ function renderColumn (addresses: AccountId[] | string[], defaultName: string, w
       key={address.toString()}
       points={
         withPoints && stakingOverview
-          ? stakingOverview.eraPoints.individual[index]
+          ? stakingOverview.eraPoints.individual[index] || EMPTY_POINTS
           : undefined
       }
       recentlyOnline={

+ 0 - 1
packages/app-staking/src/Overview/Summary.tsx

@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 // Copyright 2017-2019 @polkadot/app-staking authors & contributors
 // This software may be modified and distributed under the terms
 // of the Apache-2.0 license. See the LICENSE file for details.

+ 0 - 1
packages/app-staking/src/Overview/index.tsx

@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/camelcase */
 // Copyright 2017-2019 @polkadot/app-staking authors & contributors
 // This software may be modified and distributed under the terms
 // of the Apache-2.0 license. See the LICENSE file for details.

+ 33 - 0
packages/react-components/src/Expander.tsx

@@ -0,0 +1,33 @@
+// Copyright 2017-2019 @polkadot/react-components authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { BareProps } from './types';
+
+import React, { useState } from 'react';
+
+export interface Props extends BareProps {
+  children: React.ReactNode;
+  summary: React.ReactNode;
+}
+
+export default function Expanded ({ children, className, style, summary }: Props): React.ReactElement<Props> {
+  const [isExpanded, setIsExpanded] = useState(false);
+
+  const _toggle = (event: React.SyntheticEvent): void => {
+    event.preventDefault();
+    event.stopPropagation();
+
+    setIsExpanded(!isExpanded);
+  };
+
+  return (
+    <details
+      className={`ui--Expander ${className}`}
+      open={isExpanded}
+    >
+      <summary onClick={_toggle}>{summary}</summary>
+      {isExpanded && children}
+    </details>
+  );
+}

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

@@ -28,6 +28,7 @@ export { default as CryptoType } from './CryptoType';
 export { default as Dropdown } from './Dropdown';
 export { default as Editor } from './Editor';
 export { default as Event } from './Event';
+export { default as Expander } from './Expander';
 export { default as Extrinsic } from './Extrinsic';
 export { default as FilterOverlay } from './FilterOverlay';
 export { default as Forget } from './Forget';