refactor: sides and bar
This commit is contained in:
parent
f301a39f84
commit
3f72ba99fa
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat--flexed {
|
.flexed {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 4em;
|
width: 4em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user