Fixed sidebar w. scrollable icons (#796)
* enhanced sidebar * ts * tidyup * bump * fix * yarn lock * package json * package json * fixed sidebar * lodash throttle * tslint * yarn lock * universal height * logo width * post conflicts * toggle bar * tidyup * tidyup, remove flex on sidebar wrap * conflict * yarn lock * ts * yarn lock * sticky sidebar * wrapper classes * cleanup * polkadot pink dial down * revert pink remove, consistent collapse pos * eagle-eyed jaco * collapsed icon margin 0
This commit is contained in:
parent
7ff2aff2b3
commit
9dc5f50f73
@ -5,6 +5,7 @@
|
||||
import { BareProps } from '@polkadot/ui-app/types';
|
||||
|
||||
import React from 'react';
|
||||
import store from 'store';
|
||||
import styled from 'styled-components';
|
||||
import { classes } from '@polkadot/ui-app/util';
|
||||
import Signer from '@polkadot/ui-signer/index';
|
||||
@ -18,6 +19,10 @@ import SideBar from './SideBar';
|
||||
|
||||
type Props = BareProps & {};
|
||||
|
||||
type State = {
|
||||
isCollapsed: boolean
|
||||
};
|
||||
|
||||
const Wrapper = styled.div`
|
||||
align-items: stretch;
|
||||
box-sizing: border-box;
|
||||
@ -25,16 +30,43 @@ const Wrapper = styled.div`
|
||||
min-height: 100vh;
|
||||
`;
|
||||
|
||||
function Apps (props: Props) {
|
||||
return (
|
||||
<Wrapper className={classes(`theme--${settings.uiTheme}`)}>
|
||||
<SideBar />
|
||||
<Signer>
|
||||
<Content />
|
||||
</Signer>
|
||||
<Connecting />
|
||||
</Wrapper>
|
||||
);
|
||||
class Apps extends React.Component<Props, State> {
|
||||
state: State;
|
||||
|
||||
constructor (props: Props) {
|
||||
super(props);
|
||||
|
||||
const state = store.get('sidebar') || {};
|
||||
this.state = {
|
||||
isCollapsed: false,
|
||||
...state
|
||||
};
|
||||
}
|
||||
|
||||
render () {
|
||||
const { isCollapsed } = this.state;
|
||||
|
||||
return (
|
||||
<Wrapper className={classes('apps-Wrapper', `${isCollapsed ? 'collapsed' : 'expanded'}`, `theme--${settings.uiTheme}`)}>
|
||||
<SideBar
|
||||
collapse={this.collapse}
|
||||
isCollapsed={isCollapsed}
|
||||
/>
|
||||
<Signer>
|
||||
<Content />
|
||||
</Signer>
|
||||
<Connecting />
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
private collapse = (): void => {
|
||||
this.setState(({ isCollapsed }: State) => ({
|
||||
isCollapsed: !isCollapsed
|
||||
}), () => {
|
||||
store.set('sidebar', this.state);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default hot(Apps);
|
||||
|
||||
@ -5,81 +5,113 @@
|
||||
@import '../../../ui-app/src/styles/theme/_colors-polkadot.css';
|
||||
@import '../../../ui-app/src/styles/theme/_colors-substrate.css';
|
||||
|
||||
.apps--SideBar {
|
||||
background: #4e4e4e;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
padding: 0.75em 0 0 0.75em;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
transition: width 0.3s;
|
||||
.apps-Wrapper {
|
||||
transition: padding-left 0.3s;
|
||||
|
||||
&.collapsed {
|
||||
width: 4.2rem;
|
||||
.apps--SideBar {
|
||||
align-items: center;
|
||||
background: #3f3f3f;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
transition: width 0.3s;
|
||||
z-index: 100;
|
||||
|
||||
.ui.vertical.menu {
|
||||
align-items: flex-end;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
position: sticky;
|
||||
overflow-y: auto;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.apps--SideBar-Item {
|
||||
align-self: flex-end;
|
||||
flex-grow: 0;
|
||||
overflow-x: visible;
|
||||
width: inherit;
|
||||
|
||||
padding: 0 !important;
|
||||
.text {
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.apps--SideBar-logo {
|
||||
margin: 0.5rem 1.5rem 1rem 0.75rem;
|
||||
padding-top: 0.75em;
|
||||
width: 9rem;
|
||||
}
|
||||
|
||||
.apps--SideBar-collapse {
|
||||
align-items: flex-end;
|
||||
background: #3f3f3f;
|
||||
bottom: 0px;
|
||||
display: flex;
|
||||
flex-direction: row wrap;
|
||||
flex-grow: 1;
|
||||
justify-content: flex-start;
|
||||
padding: 3.5rem 0 1rem 0;
|
||||
position: sticky;
|
||||
width: 100%;
|
||||
|
||||
.ui.basic.secondary.button {
|
||||
bottom: 0.75rem;
|
||||
box-shadow: 0 0 0 1px #eee inset !important;
|
||||
color: #eee !important;
|
||||
left: -0.06rem;
|
||||
position: absolute;
|
||||
transition: transform 0.15s;
|
||||
|
||||
&.rotated {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.apps--SideBar-toggle {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
transition: all 0.2s;
|
||||
width: 6px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255,255,255,0.15);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.expanded {
|
||||
&.expanded .apps--SideBar {
|
||||
padding-left: 0.74rem;
|
||||
text-align: left;
|
||||
width: 12rem;
|
||||
}
|
||||
|
||||
.ui.vertical.menu {
|
||||
margin: 0;
|
||||
width: auto;
|
||||
}
|
||||
&.collapsed .apps--SideBar {
|
||||
text-align: center;
|
||||
width: 4.2rem;
|
||||
|
||||
.apps--SideBar-Item {
|
||||
overflow-x: visible;
|
||||
padding: 0 !important;
|
||||
text-align: left;
|
||||
|
||||
.text {
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.apps--SideBar-logo {
|
||||
width: 100%;
|
||||
margin: 0.5rem 1.5rem 1rem 0.75rem;
|
||||
width: 9rem;
|
||||
}
|
||||
|
||||
.apps--SideBar-collapse {
|
||||
bottom: 0.75em;
|
||||
position: fixed;
|
||||
left: 0.75rem;
|
||||
|
||||
.ui.basic.secondary.button {
|
||||
box-shadow: 0 0 0 1px #eee inset !important;
|
||||
color: #eee !important;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.apps--SideBar-toggle {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: -2px;
|
||||
height: 100%;
|
||||
width: 7px;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255,255,255,0.15);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
.divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.apps--SideBar-Item {
|
||||
margin-left: 5px;
|
||||
.icon {
|
||||
font-size: 1.38rem;
|
||||
font-size: 1.28rem;
|
||||
}
|
||||
.text {
|
||||
display: none;
|
||||
@ -87,13 +119,21 @@
|
||||
}
|
||||
|
||||
.apps--SideBar-logo {
|
||||
margin: 0.125rem 0.75rem 0.625rem 0;
|
||||
margin: 0.125rem auto 0.625rem auto;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
a.apps--SideBar-Item-NavLink {
|
||||
padding-top: 0.9em;
|
||||
padding-bottom: 0.9em;
|
||||
padding-bottom: 0.92em;
|
||||
padding-top: 0.92em;
|
||||
|
||||
> i {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.apps--SideBar-collapse .ui.basic.secondary.button {
|
||||
left: 0.66rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,11 +142,17 @@ a.apps--SideBar-Item-NavLink {
|
||||
color: #eee;
|
||||
display: block;
|
||||
padding: 0.75em 0.75em;
|
||||
transition: background 0.15s;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0,0,0,0.15);
|
||||
border-radius: 0.28571429rem 0 0 0.28571429rem;
|
||||
}
|
||||
}
|
||||
|
||||
a.apps--SideBar-Item-NavLink-active {
|
||||
background: #fafafa;
|
||||
background: #fafafa !important;
|
||||
border-radius: 0.28571429rem 0 0 0.28571429rem;
|
||||
color: inherit;
|
||||
|
||||
@ -115,15 +161,18 @@ a.apps--SideBar-Item-NavLink-active {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.theme--polkadot {
|
||||
a.apps--SideBar-Item-NavLink:hover {
|
||||
color: $nav-link;
|
||||
transition: 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0,0,0,0.05);
|
||||
}
|
||||
}
|
||||
|
||||
a.apps--SideBar-Item-NavLink-active {
|
||||
color: $nav-link;
|
||||
|
||||
&:hover {
|
||||
color: $nav-link;
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import './SideBar.css';
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
import store from 'store';
|
||||
import { withMulti } from '@polkadot/ui-api/index';
|
||||
import { Button, Icon, Menu } from '@polkadot/ui-app/index';
|
||||
|
||||
@ -19,30 +18,18 @@ import Item from './Item';
|
||||
import NodeInfo from './NodeInfo';
|
||||
import getLogo from './logos';
|
||||
|
||||
type Props = I18nProps;
|
||||
|
||||
type State = {
|
||||
isCollapsed: boolean
|
||||
type Props = I18nProps & {
|
||||
isCollapsed: boolean,
|
||||
collapse: () => void
|
||||
};
|
||||
|
||||
class SideBar extends React.PureComponent<Props, State> {
|
||||
state: State;
|
||||
|
||||
constructor (props: Props) {
|
||||
super(props);
|
||||
|
||||
const state = store.get('sidebar') || {};
|
||||
this.state = {
|
||||
isCollapsed: false,
|
||||
...state
|
||||
};
|
||||
}
|
||||
class SideBar extends React.PureComponent<Props> {
|
||||
|
||||
render () {
|
||||
const { isCollapsed } = this.state;
|
||||
const { isCollapsed } = this.props;
|
||||
|
||||
return (
|
||||
<div className={`apps--SideBar ${isCollapsed ? 'collapsed' : 'expanded'}`}>
|
||||
<div className='apps--SideBar'>
|
||||
<Menu
|
||||
secondary
|
||||
vertical
|
||||
@ -65,31 +52,24 @@ class SideBar extends React.PureComponent<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
private collapse = (): void => {
|
||||
this.setState(({ isCollapsed }: State) => ({
|
||||
isCollapsed: !isCollapsed
|
||||
}), () => {
|
||||
store.set('sidebar', this.state);
|
||||
});
|
||||
}
|
||||
|
||||
private renderCollapse () {
|
||||
const { isCollapsed } = this.state;
|
||||
const { isCollapsed } = this.props;
|
||||
|
||||
return (
|
||||
<div className='apps--SideBar-collapse'>
|
||||
<Button
|
||||
icon={`angle double ${isCollapsed ? 'right' : 'left'}`}
|
||||
icon='angle double right'
|
||||
isBasic
|
||||
isCircular
|
||||
onClick={this.collapse}
|
||||
onClick={this.props.collapse}
|
||||
className={`${isCollapsed ? `` : `rotated`}`}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private renderLogo () {
|
||||
const { isCollapsed } = this.state;
|
||||
const { isCollapsed } = this.props;
|
||||
const logo = getLogo(isCollapsed);
|
||||
|
||||
return (
|
||||
@ -102,7 +82,7 @@ class SideBar extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
private renderRoutes () {
|
||||
const { isCollapsed } = this.state;
|
||||
const { isCollapsed } = this.props;
|
||||
const { t } = this.props;
|
||||
|
||||
return routing.routes.map((route, index) => (
|
||||
@ -141,7 +121,7 @@ class SideBar extends React.PureComponent<Props, State> {
|
||||
return (
|
||||
<div
|
||||
className='apps--SideBar-toggle'
|
||||
onClick={this.collapse}
|
||||
onClick={this.props.collapse}
|
||||
>
|
||||
</div>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user