refactor: sides and bar

This commit is contained in:
cha0s 2020-07-13 20:31:59 -05:00
parent f301a39f84
commit 3f72ba99fa
8 changed files with 125 additions and 136 deletions

View File

@ -2,24 +2,57 @@ import './bar.scss';
import classnames from 'classnames'; import classnames from 'classnames';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React, {useState} from 'react';
export default function Bar(props) { export default function Bar(props) {
const {children, isHorizontal} = props; const {branding, buttons, isHorizontal, onActive} = props;
const [active, setActive] = useState(0);
return ( return (
<div <div
className={classnames(['bar', isHorizontal ? 'bar--horizontal' : 'bar--vertical'])} className={classnames(['bar', isHorizontal ? 'bar--horizontal' : 'bar--vertical'])}
> >
{children} <ul className="bar__buttons">
{branding}
{
buttons.map(({icon, label}, i) => (
<li className="bar__buttonItem">
<button
className={classnames('bar__button', {active: i === active})}
onClick={() => {
onActive(i, active);
setActive(i);
}}
type="button"
>
<span
className="bar__buttonIcon"
role="img"
aria-label={label}
>
{icon}
</span>
<span className="bar__buttonText">{label}</span>
</button>
</li>
))
}
</ul>
</div> </div>
); );
} }
Bar.defaultProps = { Bar.defaultProps = {
branding: null,
isHorizontal: true, isHorizontal: true,
onActive: () => {},
}; };
Bar.propTypes = { Bar.propTypes = {
children: PropTypes.node.isRequired, branding: PropTypes.node,
buttons: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string,
icon: PropTypes.string,
})).isRequired,
isHorizontal: PropTypes.bool, isHorizontal: PropTypes.bool,
onActive: PropTypes.func,
}; };

View File

@ -1,3 +1,5 @@
@import '~/client/scss/colors.scss';
.bar--horizontal { .bar--horizontal {
height: 4em; height: 4em;
width: 100%; width: 100%;
@ -14,3 +16,60 @@
flex-direction: column; flex-direction: column;
} }
} }
.bar__buttons {
display: flex;
.closed & {
flex-direction: column;
}
}
.bar__brandItem {
display: flex;
flex-direction: column;
justify-content: space-around;
font-family: var(--thick-title-font-family);
font-size: 0.95em;
padding: 1em;
user-select: none;
.closed & {
font-size: 0.9em;
text-align: center;
padding: 1em 0 0.5em;
}
}
.bar__buttonItem {
padding: 0.25em;
.closed & {
padding-bottom: 0;
}
.open & {
padding-right: 0;
}
}
.bar__button {
background-color: #2a2a2a;
border: none;
height: 3.5em;
transition: 0.1s background-color;
width: 3.5em;
&:hover {
background-color: #272727;
}
&.active {
background-color: $active-color;
}
.closed &.active {
background-color: #2a2a2a;
}
}
.bar__buttonIcon {
display: flow-root;
}
.bar__buttonText {
font-size: 0.7em;
}

View File

@ -7,56 +7,32 @@ import Bar from './bar';
export default function ChatLeft() { export default function ChatLeft() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [active, setActive] = useState(0); // const [active, setActive] = useState(0);
const toggleOpen = () => setIsOpen(!isOpen); const toggleOpen = () => setIsOpen(!isOpen);
const buttons = [ const buttons = [
{ {
emoji: '📜', icon: '📜',
label: 'chat', label: 'chat',
}, },
{ {
emoji: '😁', icon: '😁',
label: 'friends', label: 'friends',
}, },
]; ];
return ( return (
<div <div
className={classnames( className={classnames('left', 'flexed', isOpen ? 'open' : 'closed')}
'left',
'chat--flexed',
isOpen ? 'left--open' : 'left--closed',
)}
> >
<Bar isHorizontal={isOpen}> <Bar
<ul className="left__buttons"> branding={<li className="bar__brandItem">reddichat</li>}
<li className="left__brandItem">reddichat</li> buttons={buttons}
{ isHorizontal={isOpen}
buttons.map(({emoji, label}, i) => ( onActive={(active, i) => {
<li className="left__buttonItem"> if (i === active || !isOpen) {
<button toggleOpen();
className={classnames('left__button', {active: isOpen && i === active})}
onClick={() => {
if (i === active || !isOpen) {
toggleOpen();
}
setActive(i);
}}
type="button"
>
<span
className="left__buttonIcon"
role="img"
aria-label={label}
>
{emoji}
</span>
<span className="left__buttonText">{label}</span>
</button>
</li>
))
} }
</ul> }}
</Bar> />
<label className="channel__join"> <label className="channel__join">
Join Join
<span className="channel__joinTextWrapper"> <span className="channel__joinTextWrapper">

View File

@ -3,64 +3,10 @@
transition: 0.2s width; transition: 0.2s width;
} }
.left--open { .left.open {
width: 18em; width: 18em;
} }
.left__buttons {
display: flex;
.left--closed & {
flex-direction: column;
}
}
.left__brandItem {
display: flex;
flex-direction: column;
justify-content: space-around;
font-family: var(--thick-title-font-family);
font-size: 0.95em;
padding: 1em;
user-select: none;
.left--closed & {
font-size: 0.9em;
text-align: center;
padding: 1em 0 0.5em;
}
}
.left__buttonItem {
padding: 0.25em;
.left--closed & {
padding-bottom: 0;
}
.left--open & {
padding-right: 0;
}
}
.left__button {
background-color: #2a2a2a;
border: none;
height: 3.5em;
transition: 0.1s background-color;
width: 3.5em;
&:hover {
background-color: #272727;
}
&.active {
background-color: #555555;
}
}
.left__buttonIcon {
display: flow-root;
}
.left__buttonText {
font-size: 0.7em;
}
.channel__join[class] { .channel__join[class] {
background-color: #272727; background-color: #272727;
flex-wrap: nowrap; flex-wrap: nowrap;

View File

@ -7,51 +7,26 @@ import Bar from './bar';
export default function ChatRight() { export default function ChatRight() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [active, setActive] = useState(0);
const toggleOpen = () => setIsOpen(!isOpen); const toggleOpen = () => setIsOpen(!isOpen);
const buttons = [ const buttons = [
{ {
emoji: '🙃', icon: '🙃',
label: 'present', label: 'present',
}, },
]; ];
return ( return (
<div <div
className={classnames( className={classnames('right', 'flexed', isOpen ? 'open' : 'closed')}
'right',
'chat--flexed',
isOpen ? 'right--open' : 'right--closed',
)}
> >
<Bar isHorizontal={isOpen}> <Bar
<ul className="right__buttons"> buttons={buttons}
{ isHorizontal={isOpen}
buttons.map(({emoji, label}, i) => ( onActive={(active, i) => {
<li className="right__buttonItem"> if (i === active || !isOpen) {
<button toggleOpen();
className={classnames('right__button', {active: isOpen && i === active})}
onClick={() => {
if (i === active || !isOpen) {
toggleOpen();
}
setActive(i);
}}
type="button"
>
<span
className="right__buttonIcon"
role="img"
aria-label={label}
>
{emoji}
</span>
<span className="right__buttonText">{label}</span>
</button>
</li>
))
} }
</ul> }}
</Bar> />
</div> </div>
); );
} }

View File

@ -7,7 +7,7 @@
float: right; float: right;
} }
.right--open { .right.open {
width: 18em; width: 18em;
} }
@ -21,10 +21,10 @@
.right__buttonItem { .right__buttonItem {
padding: 0.25em; padding: 0.25em;
.right--closed & { .right.closed & {
padding-bottom: 0; padding-bottom: 0;
} }
.right--open & { .right.open & {
padding-left: 0; padding-left: 0;
} }
} }

View File

@ -9,7 +9,7 @@ export default function Chat() {
return ( return (
<div className="chat"> <div className="chat">
<ChatLeft /> <ChatLeft />
<div className="chat__messages chat--flexed"></div> <div className="chat__messages flexed"></div>
<ChatRight /> <ChatRight />
</div> </div>
); );

View File

@ -4,7 +4,7 @@
width: 100%; width: 100%;
} }
.chat--flexed { .flexed {
height: 100%; height: 100%;
width: 4em; width: 4em;
overflow: hidden; overflow: hidden;