Convert tabs to non sui styles (#3168)
* Convert tabs to non sui styles * inactive hover * Adjust sequence display * Update
This commit is contained in:
parent
0b7d306251
commit
fffa535d11
@ -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} />
|
||||
|
||||
@ -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
packages/react-components/src/Tabs/Tab.tsx
Normal file
70
packages/react-components/src/Tabs/Tab.tsx
Normal file
@ -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
packages/react-components/src/Tabs/index.tsx
Normal file
72
packages/react-components/src/Tabs/index.tsx
Normal file
@ -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
packages/react-components/src/Tabs/types.ts
Normal file
14
packages/react-components/src/Tabs/types.ts
Normal file
@ -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;
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user