Browse Source

Convert tabs to non sui styles (#3168)

* Convert tabs to non sui styles

* inactive hover

* Adjust sequence display

* Update
Jaco Greeff 4 years ago
parent
commit
fffa535d11

+ 6 - 4
packages/page-contracts/src/index.tsx

@@ -3,7 +3,7 @@
 // of the Apache-2.0 license. See the LICENSE file for details.
 
 import { AppProps as Props } from '@polkadot/react-components/types';
-import { TabItem } from '@polkadot/react-components/Tabs';
+import { TabItem } from '@polkadot/react-components/Tabs/types';
 import { ComponentProps } from './types';
 
 import React, { useCallback, useEffect, useMemo, useState } from 'react';
@@ -26,7 +26,6 @@ function ContractsApp ({ basePath, onStatusChange }: Props): React.ReactElement<
   const [constructorIndex, setConstructorIndex] = useState(0);
   const [isDeployOpen, toggleIsDeployOpen, setIsDeployOpen] = useToggle();
   const [updated, setUpdated] = useState(0);
-
   const [allCodes, setAllCodes] = useState(store.getAllCode());
 
   const _triggerUpdate = useCallback(
@@ -47,6 +46,11 @@ function ContractsApp ({ basePath, onStatusChange }: Props): React.ReactElement<
     [allCodes, toggleIsDeployOpen]
   );
 
+  const _onCloseDeploy = useCallback(
+    () => setIsDeployOpen(false),
+    [setIsDeployOpen]
+  );
+
   const componentProps = useMemo(
     (): ComponentProps => ({
       accounts: allAccounts,
@@ -76,8 +80,6 @@ function ContractsApp ({ basePath, onStatusChange }: Props): React.ReactElement<
 
   const hidden: string[] = [];
 
-  const _onCloseDeploy = (): void => setIsDeployOpen(false);
-
   return (
     <main className='contracts--App'>
       <HelpOverlay md={introMd as string} />

+ 0 - 95
packages/react-components/src/Tabs.tsx

@@ -1,95 +0,0 @@
-// Copyright 2017-2020 @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 React, { useEffect } from 'react';
-import { NavLink, useLocation } from 'react-router-dom';
-import styled from 'styled-components';
-
-import { classes } from './util';
-import Icon from './Icon';
-
-const MyIcon = styled(Icon)`
-  &&& {
-    width: 1rem;
-    margin: 0.7rem 0;
-  }
-`;
-
-export interface TabItem {
-  alias?: string;
-  hasParams?: boolean;
-  isExact?: boolean;
-  isRoot?: boolean;
-  name: string;
-  text: React.ReactNode;
-}
-
-interface Props {
-  className?: string;
-  basePath: string;
-  hidden?: (string | boolean | undefined)[];
-  items: TabItem[];
-  isSequence?: boolean;
-}
-
-function renderItem ({ basePath, isSequence, items }: Props): (tabItem: TabItem, index: number) => React.ReactNode {
-  return function Tab ({ hasParams, isRoot, name, text, ...tab }: TabItem, index: number): React.ReactNode {
-    const to = isRoot
-      ? basePath
-      : `${basePath}/${name}`;
-    // only do exact matching when not the fallback (first position tab),
-    // params are problematic for dynamic hidden such as app-accounts
-    const isExact = tab.isExact || !hasParams || (!isSequence && index === 0);
-
-    return (
-      <React.Fragment key={to}>
-        <NavLink
-          activeClassName='active'
-          className='item'
-          exact={isExact}
-          strict={isExact}
-          to={to}
-        >
-          {text}
-        </NavLink>
-        {(isSequence && index < items.length - 1) && (
-          <MyIcon icon='arrow-right' />
-        )}
-      </React.Fragment>
-    );
-  };
-}
-
-function Tabs (props: Props): React.ReactElement<Props> {
-  const location = useLocation();
-  const { className = '', basePath, hidden = [], items } = props;
-
-  // redirect on invalid tabs
-  useEffect((): void => {
-    if (location.pathname !== basePath) {
-      // Has the form /staking/query/<something>
-      const [,, section] = location.pathname.split('/');
-      const alias = items.find(({ alias }) => alias === section);
-
-      if (alias) {
-        window.location.hash = alias.isRoot
-          ? basePath
-          : `${basePath}/${alias.name}`;
-      } else if (hidden.includes(section) || !items.some(({ isRoot, name }) => !isRoot && name === section)) {
-        window.location.hash = basePath;
-      }
-    }
-  }, [basePath, hidden, items, location]);
-
-  return (
-    <div className={classes('ui--Menu ui menu tabular', className)}>
-      {items
-        .filter(({ name }): boolean => !hidden.includes(name))
-        .map(renderItem(props))
-      }
-    </div>
-  );
-}
-
-export default React.memo(Tabs);

+ 70 - 0
packages/react-components/src/Tabs/Tab.tsx

@@ -0,0 +1,70 @@
+// Copyright 2017-2020 @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 { TabItem } from './types';
+
+import React from 'react';
+import { NavLink } from 'react-router-dom';
+import styled from 'styled-components';
+
+import Icon from '../Icon';
+
+interface Props extends TabItem {
+  basePath: string;
+  className?: string;
+  index: number;
+  isSequence?: boolean;
+  num: number;
+}
+
+function Tab ({ basePath, className = '', hasParams, index, isExact, isRoot, isSequence, name, num, text }: Props): React.ReactElement<Props> {
+  const to = isRoot
+    ? basePath
+    : `${basePath}/${name}`;
+
+  // only do exact matching when not the fallback (first position tab),
+  // params are problematic for dynamic hidden such as app-accounts
+  const tabIsExact = isExact || !hasParams || (!isSequence && index === 0);
+
+  return (
+    <NavLink
+      activeClassName='tabLinkActive'
+      className={`ui--Tabs-Tab ${className}`}
+      exact={tabIsExact}
+      strict={tabIsExact}
+      to={to}
+    >
+      {text}{(isSequence && index < (num - 1)) && (
+        <Icon
+          className='tabIcon'
+          icon='arrow-right'
+        />
+      )}
+    </NavLink>
+  );
+}
+
+export default React.memo(styled(Tab)`
+  border-bottom: 2px solid transparent;
+  color: rgba(0, 0, 0, 0.87) !important;
+  padding: 0.75rem 1.5rem;
+
+  &.tabLinkActive {
+    border-bottom-color: #e6e6e6;
+    color: rgba(0, 0, 0, 0.95);
+    font-weight: 700;
+  }
+
+  &:hover {
+    color: inherit !important;
+
+    &:not(.tabLinkActive) {
+      border-bottom-color: #e6e6e6;
+    }
+  }
+
+  .tabIcon {
+    margin-left: 0.75rem;
+  }
+`);

+ 72 - 0
packages/react-components/src/Tabs/index.tsx

@@ -0,0 +1,72 @@
+// Copyright 2017-2020 @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 { TabItem } from './types';
+
+import React, { useEffect } from 'react';
+import { useLocation } from 'react-router-dom';
+import styled from 'styled-components';
+
+import Tab from './Tab';
+
+interface Props {
+  className?: string;
+  basePath: string;
+  hidden?: (string | boolean | undefined)[];
+  items: TabItem[];
+  isSequence?: boolean;
+}
+
+function Tabs ({ basePath, className = '', hidden, isSequence, items }: Props): React.ReactElement<Props> {
+  const location = useLocation();
+
+  // redirect on invalid tabs
+  useEffect((): void => {
+    if (location.pathname !== basePath) {
+      // Has the form /staking/query/<something>
+      const [,, section] = location.pathname.split('/');
+      const alias = items.find(({ alias }) => alias === section);
+
+      if (alias) {
+        window.location.hash = alias.isRoot
+          ? basePath
+          : `${basePath}/${alias.name}`;
+      } else if (hidden && (hidden.includes(section) || !items.some(({ isRoot, name }) => !isRoot && name === section))) {
+        window.location.hash = basePath;
+      }
+    }
+  }, [basePath, hidden, items, location]);
+
+  const filtered = hidden
+    ? items.filter(({ name }) => !hidden.includes(name))
+    : items;
+
+  return (
+    <div className={`ui--Tabs ${className}`}>
+      {filtered.map((tab, index) => (
+        <Tab
+          {...tab}
+          basePath={basePath}
+          index={index}
+          isSequence={isSequence}
+          key={tab.name}
+          num={filtered.length}
+        />
+      ))}
+    </div>
+  );
+}
+
+export default React.memo(styled(Tabs)`
+  border-bottom: 1px solid #e6e6e6;
+  margin: 0 -2em;
+  overflow-x: scroll;
+  padding: 2em 2em 0.75rem;
+  text-align: left;
+
+  &::-webkit-scrollbar {
+    display: none;
+    width: 0px;
+  }
+`);

+ 14 - 0
packages/react-components/src/Tabs/types.ts

@@ -0,0 +1,14 @@
+// Copyright 2017-2020 @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 React from 'react';
+
+export interface TabItem {
+  alias?: string;
+  hasParams?: boolean;
+  isExact?: boolean;
+  isRoot?: boolean;
+  name: string;
+  text: React.ReactNode;
+}

+ 2 - 2
packages/react-components/src/styles/index.ts

@@ -58,8 +58,8 @@ export default createGlobalStyle<Props>`
   }
 
   .theme--default {
-    .ui.menu.tabular .item.active {
-      border-color: ${getHighlight} !important;
+    .ui--Tabs-Tab.tabLinkActive {
+      border-bottom-color: ${getHighlight};
     }
 
     .ui.blue.progress > .bar {

+ 2 - 2
packages/react-components/src/styles/media.ts

@@ -189,8 +189,8 @@ export default css`
 
   /* tabs */
   @media (max-width: 991px) {
-    .ui.menu.tabular {
-      padding-left: 5.2rem !important;
+    .ui--Tabs {
+      padding-left: 5.2rem;
     }
   }
 `;

+ 0 - 25
packages/react-components/src/styles/semantic.ts

@@ -177,31 +177,6 @@ export default css`
     justify-content: flex-start;
   }
 
-  .ui.menu.tabular {
-    border-color: #e6e6e6;
-    /* break out of the wrapping main padding */
-    margin: -1em -2em 0;
-    overflow-x: scroll;
-    padding: 2em 2em 0 2em;
-    transition: padding-left 0.2s linear 0.4s;
-
-    &::-webkit-scrollbar {
-      display: none;
-      width: 0px;
-    }
-
-    .item {
-      border-bottom: 2px solid rgba(0, 0, 0, 0);
-      border: none;
-      top: -1px;
-
-      &.active {
-        background: none;;
-        border-bottom: 2px solid #db2828;
-      }
-    }
-  }
-
   /* remove the default white background, settings app has it as part of Tab */
   .ui.segment {
     background: transparent;

+ 0 - 4
packages/react-components/src/styles/theme.ts

@@ -61,10 +61,6 @@ export default css`
       border-bottom-color: ${colorBtnHighlight};
     }
 
-    .ui.menu.tabular .item.active {
-      border-bottom-color: ${colorBtnHighlight};
-    }
-
     /* this is for dropdown buttons */
     .ui.buttons .ui.button.selection.visible.dropdown {
       &:hover {