Fix last Sidebar bugs

Signed-off-by: Avior <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2021-12-12 14:53:11 +01:00
parent c35084fb9d
commit d5b438cd45
Signed by: Florian Bouillon
GPG Key ID: 50BD648F12C86AB6
4 changed files with 48 additions and 25 deletions

View File

@ -7,5 +7,6 @@ Router.router = {
replace: async () => {}, replace: async () => {},
prefetch: () => {}, prefetch: () => {},
route: '/mock-route', route: '/mock-route',
asPath: '/mock-route',
pathname: 'mock-path', pathname: 'mock-path',
} }

View File

@ -143,10 +143,10 @@
@media (prefers-color-scheme dark) @media (prefers-color-scheme dark)
color white color white
background $darkGrayDark background $darkGrayDark
&.active
&:active &:active
color $textOnMain color $textOnMain
background $main background $main
padding 8px padding 8px
display flex display flex
align-items center align-items center
@ -166,6 +166,10 @@
width 100% width 100%
display flex display flex
//max-height 24px //max-height 24px
&.active > div
color $textOnMain
background $main
ul ul
list-style none list-style none
margin 0 margin 0

View File

@ -2,7 +2,6 @@ import React from 'react'
import { Meta, Story } from '@storybook/react/types-6-0' import { Meta, Story } from '@storybook/react/types-6-0'
import { Zap, ZapOff } from 'lucide-react' import { Zap, ZapOff } from 'lucide-react'
import Component from '.' import Component from '.'
export default { export default {
title: 'DZEIO/Sidebar', title: 'DZEIO/Sidebar',
component: Component, component: Component,
@ -19,10 +18,10 @@ Sidebar.args = {
name: 'Username', name: 'Username',
menu: [{ menu: [{
path: '/logout', path: '/logout',
value: 'Logout' name: 'Logout'
}, { }, {
path: '/logout', path: '/mock-route',
value: 'Logout' name: 'Mock Route'
}] }]
}, },
menu: [{ menu: [{
@ -31,11 +30,20 @@ Sidebar.args = {
}, { }, {
name: 'With Childs', name: 'With Childs',
icon: Zap, icon: Zap,
subMenu: [{
name: 'Child 1'
}, {
name: 'Mock Route',
path: '/mock-route'
}]
}, {
name: 'With Childs2',
icon: Zap,
subMenu: [{ subMenu: [{
name: 'Child 1' name: 'Child 1'
}, { }, {
name: 'Child with link', name: 'Child with link',
path: '/dashboard' path: '/mock-route2'
}] }]
}, { }, {
path: '/dashboard', path: '/dashboard',

View File

@ -1,7 +1,7 @@
import React, { MouseEvent } from 'react' import React, { MouseEvent } from 'react'
import Router from 'next/router' import Router from 'next/router'
import { ChevronDown, Minus, MoreHorizontal, Plus } from 'lucide-react' import { ChevronDown, MoreHorizontal, Plus } from 'lucide-react'
import Text from '../Text' import Text from '../Text'
import Col from '../Col' import Col from '../Col'
import Row from '../Row' import Row from '../Row'
@ -71,7 +71,7 @@ interface State {
* Sidebar Component * Sidebar Component
* @version 1.0.0 * @version 1.0.0
*/ */
export default class Navbar extends React.Component<Props, State> { export default class Sidebar extends React.Component<Props, State> {
public state: State = { public state: State = {
open: true, open: true,
@ -79,14 +79,12 @@ export default class Navbar extends React.Component<Props, State> {
} }
public componentDidMount() { public componentDidMount() {
this.setState({ this.onRouteChange(Router.asPath)
path: Router.asPath
})
Router.events.on('routeChangeComplete', () => { Router.events.on('routeChangeComplete', () => {
this.setState({path: Router.asPath, open: false}) this.onRouteChange(Router.asPath)
}) })
Router.events.on('routeChangeError', () => { Router.events.on('routeChangeError', () => {
this.setState({path: Router.asPath, open: false}) this.onRouteChange(Router.asPath)
}) })
if (!this.props.fullWidth) { if (!this.props.fullWidth) {
document.body.classList.add(css.sidebarBody) document.body.classList.add(css.sidebarBody)
@ -94,7 +92,18 @@ export default class Navbar extends React.Component<Props, State> {
document.body.addEventListener('click', this.onBodyClick) document.body.addEventListener('click', this.onBodyClick)
} }
private onRouteChange(newRoute: string) {
let activeMenu = undefined
for (const menu of this.props.menu) {
if (newRoute === menu.path || menu.subMenu?.find((it) => newRoute === it.path)) {
activeMenu = menu.name + (menu.path ?? '')
}
}
this.setState({path: newRoute, subMenu: undefined, userMenu: false, activeMenu})
}
public componentDidUpdate() { public componentDidUpdate() {
//console.log(this.state.path)
if (this.state.open) { if (this.state.open) {
document.body.classList.remove(css.short) document.body.classList.remove(css.short)
} else { } else {
@ -114,14 +123,15 @@ export default class Navbar extends React.Component<Props, State> {
public onClick = (id: string, subMenu?: Array<MenuItem>) => (ev: MouseEvent) => { public onClick = (id: string, subMenu?: Array<MenuItem>) => (ev: MouseEvent) => {
ev.stopPropagation() ev.stopPropagation()
if (!this.state.open && subMenu) { if (!this.state.open && subMenu) {
console.log(ev) //console.log(ev)
this.setState({ this.setState({
subMenu: { subMenu: {
y: (ev.currentTarget as HTMLElement).offsetTop, y: (ev.currentTarget as HTMLElement).offsetTop,
menu: subMenu.map((v) => ({ menu: subMenu.map((v) => ({
display: v.name, display: v.name,
value: v.path, value: v.path,
href: v.path href: v.path,
selected: this.state.path === v.path
})) }))
} }
}) })
@ -167,10 +177,11 @@ export default class Navbar extends React.Component<Props, State> {
{this.props.user?.menu && this.state.userMenu && ( {this.props.user?.menu && this.state.userMenu && (
<div className={buildClassName(css.userMenu, [css.fullWidth, this.props.fullWidth], [css.short, !this.state.open])}> <div className={buildClassName(css.userMenu, [css.fullWidth, this.props.fullWidth], [css.short, !this.state.open])}>
<Menu onClick={this.onMenuClick} outline items={this.props.user.menu.map((v) => ({ <Menu onClick={this.onMenuClick} outline items={this.props.user.menu.map((v) => ({
display: v.name, display: v.name,
value: v.path, value: v.path,
href: v.path href: v.path,
}))} /> selected: this.state.path === v.path
}))} />
</div> </div>
)} )}
{this.state.subMenu && ( {this.state.subMenu && (
@ -197,7 +208,7 @@ export default class Navbar extends React.Component<Props, State> {
} }
private makeMenuItem(obj: MenuItem & {subMenu?: Array<MenuItem>}, isSub = false) { private makeMenuItem(obj: MenuItem & {subMenu?: Array<MenuItem>}, isSub = false) {
const id = obj.name + obj.path const id = obj.name + (obj.path ?? '')
const content = ( const content = (
<> <>
{obj.icon && ( {obj.icon && (
@ -211,9 +222,10 @@ export default class Navbar extends React.Component<Props, State> {
)} )}
</> </>
) )
const isActive = this.state.path === obj.path || obj.subMenu?.find((it) => this.state.path === it.path)
return <li key={id} className={buildClassName( return <li key={id} className={buildClassName(
[css.active, obj?.path && this.state.path?.startsWith(obj.path)], [css.active, isActive],
[css.activeMenu, id === this.state.activeMenu] [css.activeMenu, id === this.state.activeMenu && this.state.open]
)}> )}>
<div onClick={isSub ? undefined : this.onClick(id, obj.subMenu)}> <div onClick={isSub ? undefined : this.onClick(id, obj.subMenu)}>
{obj.path ? ( {obj.path ? (
@ -224,9 +236,7 @@ export default class Navbar extends React.Component<Props, State> {
</div> </div>
{obj.subMenu && ( {obj.subMenu && (
<ul> <ul>
{obj.subMenu.map((it, key) => ( {obj.subMenu.map((it) => this.makeMenuItem(it, true))}
<li key={it.name + key}>{this.makeMenuItem(it, true)}</li>
))}
</ul> </ul>
)} )}
</li> </li>