rework navmenu to use header

This commit is contained in:
SrGooglo 2023-08-17 17:53:20 +00:00
parent 846114cbbf
commit 874a755dc3
7 changed files with 128 additions and 229 deletions

View File

@ -1,27 +1,52 @@
import React from "react"
import classnames from "classnames"
import { Motion, spring } from "react-motion"
import useLayoutInterface from "hooks/useLayoutInterface"
import "./index.less"
export default (props) => {
const [visible, setVisible] = React.useState(false)
const [render, setRender] = React.useState(null)
const headerInterface = {
toggle: (to) => setVisible((prevValue) => to ?? !prevValue),
}
React.useEffect(() => {
app.layout.header = headerInterface
}, [])
return <div
className={classnames(
"page_header",
{
["visible"]: visible,
useLayoutInterface("header", {
render: (component, options) => {
if (component === null) {
return setRender(null)
}
)}
return setRender({
component,
options
})
}
})
return <Motion
style={{
y: spring(render ? 0 : 100,),
}}
>
{String(window.location.pathname).toTitleCase()}
</div>
{({ y, height }) => {
return <div
className={classnames(
"page_header_wrapper",
{
["hidden"]: !render,
}
)}
style={{
WebkitTransform: `translateY(-${y}px)`,
transform: `translateY(-${y}px)`,
}}
>
{
render?.component && React.cloneElement(
render?.component,
render?.options?.props ?? {}
)
}
</div>
}}
</Motion>
}

View File

@ -1,4 +1,4 @@
.page_header {
.page_header_wrapper {
position: sticky;
z-index: 100;
@ -6,26 +6,24 @@
top: 0;
left: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
overflow: hidden;
// hidden values
padding: 0;
opacity: 0;
height: 0px;
width: 100%;
transition: all 150ms ease-in-out;
margin-bottom: 20px;
padding: 5px;
backdrop-filter: blur(10px);
&.visible {
opacity: 1;
height: 50px;
padding: 20px;
background-color: rgba(var(--background-color-accent-values), 0.8);
border-radius: 12px;
border: 1px solid var(--border-color);
overflow: hidden;
&.hidden {
opacity: 0;
height: 0;
padding: 0;
margin: 0;
}
}

View File

@ -4,30 +4,8 @@ import * as antd from "antd"
import "./index.less"
const NavMenu = (props) => {
const handleOnClickItem = (event) => {
return props.onClickItem(event.key)
}
return <div className="navmenu_wrapper">
<div className="card">
{
props.header && <div className="card_header">
{props.header}
</div>
}
<antd.Menu
mode="inline"
selectedKeys={[props.activeKey]}
onClick={handleOnClickItem}
items={props.items}
/>
</div>
</div>
}
const NavMenuMobile = (props) => {
export default (props) => {
function handleClickItem(item) {
if (item.children && Array.isArray(item.children)) {
return false
@ -38,7 +16,7 @@ const NavMenuMobile = (props) => {
return <div
className={classnames(
"__mobile__navmenu_wrapper",
"navmenu_wrapper",
)}
>
{
@ -56,7 +34,7 @@ const NavMenuMobile = (props) => {
<antd.Button
key={item.key}
className={classnames(
"__mobile__navmenu_item",
"navmenu_item",
item.key === props.activeKey && "active",
)}
type="ghost"
@ -65,6 +43,14 @@ const NavMenuMobile = (props) => {
<div className="icon">
{item.icon}
</div>
{
props.renderNames && <div className="label">
<p>
{item.label ?? item.id}
</p>
</div>
}
</antd.Button>
</antd.Dropdown>
}
@ -72,7 +58,7 @@ const NavMenuMobile = (props) => {
return <antd.Button
key={item.key}
className={classnames(
"__mobile__navmenu_item",
"navmenu_item",
item.key === props.activeKey && "active",
)}
onClick={() => handleClickItem(item)}
@ -82,10 +68,16 @@ const NavMenuMobile = (props) => {
<div className="icon">
{item.icon}
</div>
{
props.renderNames && <div className="label">
<p>
{item.label ?? item.id}
</p>
</div>
}
</antd.Button>
})
}
</div>
}
export default app.isMobile ? NavMenuMobile : NavMenu
}

View File

@ -1,64 +1,6 @@
@import "theme/vars.less";
.navmenu_wrapper {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
width: 100%;
.card {
display: flex;
flex-direction: column;
background-color: var(--background-color-accent);
border-radius: 12px;
padding: 20px;
width: 100%;
h1,
h2 {
width: fit-content;
margin: 0;
}
.card_header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
view-transition-name: main-header;
h1 {
view-transition-name: main-header-text;
}
}
&.content {
position: relative;
transform: translateY(-30px);
padding-top: 35px;
z-index: 45;
}
}
&.card:last-child {
margin-bottom: 0;
}
}
.__mobile__navmenu_wrapper {
display: flex;
flex-direction: row;
@ -66,9 +8,10 @@
width: 100%;
.__mobile__navmenu_item {
.navmenu_item {
font-size: 0.7rem;
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
@ -82,10 +25,16 @@
color: var(--colorPrimary);
}
p {
margin: 0;
}
.icon {
margin: 0;
line-height: 1rem;
font-size: 1.5rem;
font-size: 1rem;
}
.label {

View File

@ -72,6 +72,8 @@ export class PagePanelWithNavMenu extends React.Component {
if (app.isMobile) {
app.layout.top_bar.shouldUseTopBarSpacer(true)
} else {
app.layout.header.render(null)
}
}
@ -119,7 +121,10 @@ export class PagePanelWithNavMenu extends React.Component {
const componentProps = tab.props ?? this.props.tabProps
return React.createElement(tab.component, componentProps)
return React.createElement(tab.component, {
...componentProps,
ref: this.primaryPanelRef,
})
}
replaceQueryTypeToCurrentTab = () => {
@ -186,16 +191,23 @@ export class PagePanelWithNavMenu extends React.Component {
}
render() {
const panels = [
return <>
{
children: <>
<NavMenu
header={this.props.navMenuHeader}
activeKey={this.state.activeTab}
items={this.getItems(this.props.tabs)}
onClickItem={(key) => this.handleTabChange(key)}
/>
app.isMobile && app.layout.top_bar.render(<NavMenu
activeKey={this.state.activeTab}
items={this.getItems(this.props.tabs)}
onClickItem={(key) => this.handleTabChange(key)}
/>)
}
{
!app.isMobile && app.layout.header.render(<NavMenu
header={this.props.navMenuHeader}
activeKey={this.state.activeTab}
items={this.getItems(this.props.tabs)}
onClickItem={(key) => this.handleTabChange(key)}
renderNames
>
{
Array.isArray(this.state.renders) && [
this.state.renders.map((render, index) => {
@ -206,98 +218,14 @@ export class PagePanelWithNavMenu extends React.Component {
})
]
}
</>
},
{
props: {
ref: this.primaryPanelRef,
className: this.props.transition ? "fade-opacity-enter" : undefined,
},
children: this.renderActiveTab()
},
]
if (app.isMobile) {
delete panels[0]
}
if (this.props.extraPanel) {
panels.push(this.props.extraPanel)
}
return <>
{
app.isMobile && app.layout.top_bar.render(<NavMenu
activeKey={this.state.activeTab}
items={this.getItems(this.props.tabs)}
onClickItem={(key) => this.handleTabChange(key)}
/>)
</NavMenu>)
}
{
this.renderActiveTab()
}
<PagePanels
primaryPanelClassName={this.props.primaryPanelClassName}
panels={panels}
masked={this.props.masked}
no_top_padding={this.props.no_top_padding}
/>
</>
}
}
export default class PagePanels extends React.Component {
generateGridStyle = () => {
switch (this.props.panels.length) {
case 1: {
return {
gridTemplateColumns: "1fr",
}
}
case 2: {
return {
gridTemplateColumns: "1fr 3fr",
}
}
case 3: {
return {
gridTemplateColumns: "0.5fr 1fr 0.5fr",
}
}
}
}
render() {
if (!this.props.panels) {
return null
}
return <div
className={classnames(
"pagePanels",
{
["masked"]: this.props.masked,
["withTopPadding"]: !!!this.props.no_top_padding
}
)}
style={this.generateGridStyle()}
>
{
this.props.panels[0] && <Panel
{...this.props.panels[0]}
align="left"
/>
}
{
this.props.panels[1] && <Panel
{...this.props.panels[1]}
className={this.props.primaryPanelClassName}
align="center"
/>
}
{
this.props.panels[2] && <Panel
{...this.props.panels[2]}
align="right"
/>
}
</div>
}
}
export default PagePanelWithNavMenu

View File

@ -53,12 +53,8 @@ html {
}
.pagePanels {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 1fr;
grid-column-gap: 20px;
grid-row-gap: 0px;
display: flex;
flex-direction: column;
width: 100%;

View File

@ -2,7 +2,15 @@ import React from "react"
import classnames from "classnames"
import { Layout } from "antd"
import { Sidebar, Drawer, Sidedrawer, BottomBar, TopBar, ToolsBar } from "components/Layout"
import {
Sidebar,
Drawer,
Sidedrawer,
BottomBar,
TopBar,
ToolsBar,
Header,
} from "components/Layout"
import BackgroundDecorator from "components/BackgroundDecorator"
@ -27,6 +35,7 @@ const DesktopLayout = (props) => {
<Drawer />
<Sidebar />
<Sidedrawer />
<Layout.Content
id="content_layout"
className={classnames(
@ -35,6 +44,8 @@ const DesktopLayout = (props) => {
"fade-transverse-active",
)}
>
<Header />
{
props.children && React.cloneElement(props.children, props)
}