From e37bac07a0db9ec1e8fd68dff3b891af5691f9d6 Mon Sep 17 00:00:00 2001 From: Yury Molodov Date: Fri, 13 Jan 2023 09:45:07 +0100 Subject: [PATCH] feat: make nav menu as links (#3646) --- .../src/components/Layout/Header/Header.tsx | 9 +-- .../src/components/Layout/Header/style.scss | 25 +++++++- .../vmui/src/components/Main/Tabs/TabItem.tsx | 57 +++++++++++++++++ .../components/Main/Tabs/TabItemWrapper.tsx | 29 +++++++++ .../vmui/src/components/Main/Tabs/Tabs.tsx | 61 ++++++++----------- .../vmui/src/components/Main/Tabs/style.scss | 4 ++ 6 files changed, 141 insertions(+), 44 deletions(-) create mode 100644 app/vmui/packages/vmui/src/components/Main/Tabs/TabItem.tsx create mode 100644 app/vmui/packages/vmui/src/components/Main/Tabs/TabItemWrapper.tsx diff --git a/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx b/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx index 9166d8171..d202043c6 100644 --- a/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx +++ b/app/vmui/packages/vmui/src/components/Layout/Header/Header.tsx @@ -58,11 +58,6 @@ const Header: FC = () => { const [activeMenu, setActiveMenu] = useState(pathname); - const handleChangeTab = (value: string) => { - setActiveMenu(value); - navigate(value); - }; - const headerSetup = useMemo(() => { return ((routerOptions[pathname] || {}) as RouterOptions).header || {}; }, [pathname]); @@ -90,7 +85,7 @@ const Header: FC = () => { > {!appModeEnable && (
@@ -99,10 +94,10 @@ const Header: FC = () => { )}
!r.hide)} color={color} - onChange={handleChangeTab} />
diff --git a/app/vmui/packages/vmui/src/components/Layout/Header/style.scss b/app/vmui/packages/vmui/src/components/Layout/Header/style.scss index 8f46382ac..e31343087 100644 --- a/app/vmui/packages/vmui/src/components/Layout/Header/style.scss +++ b/app/vmui/packages/vmui/src/components/Layout/Header/style.scss @@ -2,6 +2,7 @@ .vm-header { display: flex; + flex-wrap: wrap; align-items: center; justify-content: flex-start; padding: $padding-small $padding-medium; @@ -11,15 +12,35 @@ padding: $padding-small 0; } - &__logo { + @media (max-width: 1200px) { + gap: $padding-global; + + .vm-tabs { + gap: 0; + } + } + + &-logo { position: relative; display: flex; align-items: center; - justify-content: center; + justify-content: flex-start; cursor: pointer; width: 100%; max-width: 65px; + min-width: 65px; margin-bottom: 2px; + overflow: hidden; + + @media (max-width: 1200px) { + min-width: 14px; + max-width: 14px; + } + + svg { + max-width: 65px; + min-width: 65px; + } } &-nav { diff --git a/app/vmui/packages/vmui/src/components/Main/Tabs/TabItem.tsx b/app/vmui/packages/vmui/src/components/Main/Tabs/TabItem.tsx new file mode 100644 index 000000000..65f27c286 --- /dev/null +++ b/app/vmui/packages/vmui/src/components/Main/Tabs/TabItem.tsx @@ -0,0 +1,57 @@ +import React, { Component, FC, Ref } from "preact/compat"; +import classNames from "classnames"; +import { getCssVariable } from "../../../utils/theme"; +import { TabItemType } from "./Tabs"; +import TabItemWrapper from "./TabItemWrapper"; +import "./style.scss"; + +interface TabItemProps { + activeItem: string + item: TabItemType + color?: string + onChange?: (value: string) => void + activeNavRef: Ref + isNavLink?: boolean +} + +const TabItem: FC = ({ + activeItem, + item, + color = getCssVariable("color-primary"), + activeNavRef, + onChange, + isNavLink +}) => { + const createHandlerClickTab = (value: string) => () => { + onChange && onChange(value); + }; + + return ( + + {item.icon && ( +
+ {item.icon} +
+ )} + {item.label} +
+ ); +}; + +export default TabItem; diff --git a/app/vmui/packages/vmui/src/components/Main/Tabs/TabItemWrapper.tsx b/app/vmui/packages/vmui/src/components/Main/Tabs/TabItemWrapper.tsx new file mode 100644 index 000000000..4fa35cf4b --- /dev/null +++ b/app/vmui/packages/vmui/src/components/Main/Tabs/TabItemWrapper.tsx @@ -0,0 +1,29 @@ +import { ReactNode } from "react"; +import React, { FC } from "preact/compat"; +import { NavLink } from "react-router-dom"; + +interface TabItemWrapperProps { + to: string + isNavLink?: boolean + className: string + style: { color: string } + children: ReactNode + onClick: () => void +} + +const TabItemWrapper: FC = ({ to, isNavLink, children, ...props }) => { + if (isNavLink) { + return ( + + {children} + + ); + } + + return
{children}
; +}; + +export default TabItemWrapper; diff --git a/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx b/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx index 02181129e..ea8bf7455 100644 --- a/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx +++ b/app/vmui/packages/vmui/src/components/Main/Tabs/Tabs.tsx @@ -1,16 +1,24 @@ -import React, { FC, useRef, useState } from "preact/compat"; +import React, { Component, FC, useRef, useState } from "preact/compat"; import { ReactNode, useEffect } from "react"; -import "./style.scss"; -import classNames from "classnames"; import { getCssVariable } from "../../../utils/theme"; import useResize from "../../../hooks/useResize"; +import TabItem from "./TabItem"; +import "./style.scss"; + +export interface TabItemType { + value: string + label?: string + icon?: ReactNode + className?: string +} interface TabsProps { activeItem: string - items: {value: string, label?: string, icon?: ReactNode, className?: string}[] + items: TabItemType[] color?: string - onChange: (value: string) => void + onChange?: (value: string) => void indicatorPlacement?: "bottom" | "top" + isNavLink?: boolean } const Tabs: FC = ({ @@ -18,19 +26,16 @@ const Tabs: FC = ({ items, color = getCssVariable("color-primary"), onChange, - indicatorPlacement = "bottom" + indicatorPlacement = "bottom", + isNavLink, }) => { const windowSize = useResize(document.body); - const activeNavRef = useRef(null); + const activeNavRef = useRef(null); const [indicatorPosition, setIndicatorPosition] = useState({ left: 0, width: 0, bottom: 0 }); - const createHandlerClickTab = (value: string) => () => { - onChange(value); - }; - useEffect(() => { - if(activeNavRef.current) { - const { offsetLeft: left, offsetWidth: width, offsetHeight: height } = activeNavRef.current; + if(activeNavRef.current?.base instanceof HTMLElement) { + const { offsetLeft: left, offsetWidth: width, offsetHeight: height } = activeNavRef.current.base; const positionTop = indicatorPlacement === "top"; setIndicatorPosition({ left, width, bottom: positionTop ? height - 2 : 0 }); } @@ -38,29 +43,15 @@ const Tabs: FC = ({ return
{items.map(item => ( -
- {item.icon && ( -
- {item.icon} -
- )} - {item.label} -
+ activeItem={activeItem} + item={item} + onChange={onChange} + color={color} + activeNavRef={activeNavRef} + isNavLink={isNavLink} + /> ))}