From 88851e84f070207581f5dfa78a94e52194a2281b Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 1 Jul 2021 17:54:04 +0800 Subject: ... --- FrontEnd/src/views/common/tab/TabPages.tsx | 33 ++++++++++++++------- FrontEnd/src/views/common/tab/Tabs.css | 31 ++++++++++++++++++++ FrontEnd/src/views/common/tab/Tabs.tsx | 47 ++++++++++++++++++++++++++++-- 3 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 FrontEnd/src/views/common/tab/Tabs.css (limited to 'FrontEnd/src/views/common/tab') diff --git a/FrontEnd/src/views/common/tab/TabPages.tsx b/FrontEnd/src/views/common/tab/TabPages.tsx index b7a9fb36..677f558a 100644 --- a/FrontEnd/src/views/common/tab/TabPages.tsx +++ b/FrontEnd/src/views/common/tab/TabPages.tsx @@ -1,17 +1,19 @@ import React from "react"; -import { useTranslation } from "react-i18next"; -import { convertI18nText, I18nText, UiLogicError } from "@/common"; +import { I18nText, UiLogicError } from "@/common"; + +import Tabs from "./Tabs"; export interface TabPage { - id: string; - tabText: I18nText; + name: string; + text: I18nText; page: React.ReactNode; } export interface TabPagesProps { pages: TabPage[]; actions?: React.ReactNode; + dense?: boolean; className?: string; style?: React.CSSProperties; navClassName?: string; @@ -23,6 +25,7 @@ export interface TabPagesProps { const TabPages: React.FC = ({ pages, actions, + dense, className, style, navClassName, @@ -30,17 +33,13 @@ const TabPages: React.FC = ({ pageContainerClassName, pageContainerStyle, }) => { - // TODO: - if (pages.length === 0) { throw new UiLogicError("Page list can't be empty."); } - const { t } = useTranslation(); - - const [tab, setTab] = React.useState(pages[0].id); + const [tab, setTab] = React.useState(pages[0].name); - const currentPage = pages.find((p) => p.id === tab); + const currentPage = pages.find((p) => p.name === tab); if (currentPage == null) { throw new UiLogicError("Current tab value is bad."); @@ -48,6 +47,20 @@ const TabPages: React.FC = ({ return (
+ ({ + name: page.name, + text: page.text, + onClick: () => { + setTab(page.name); + }, + }))} + dense={dense} + activeTabName={tab} + className={navClassName} + style={navStyle} + actions={actions} + />
{currentPage.page}
diff --git a/FrontEnd/src/views/common/tab/Tabs.css b/FrontEnd/src/views/common/tab/Tabs.css new file mode 100644 index 00000000..53505a3c --- /dev/null +++ b/FrontEnd/src/views/common/tab/Tabs.css @@ -0,0 +1,31 @@ +.cru-nav { + border-bottom: var(--cru-background-2-color) 1px solid; + display: flex; +} + +.cru-nav-item { + color: var(--cru-primary-color); + border: var(--cru-background-2-color) 0.5px solid; + border-bottom: none; + padding: 0.5em 1.5em; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + transition: all 0.5s; + cursor: pointer; +} + +.cru-nav.dense .cru-nav-item { + padding: 0.2em 1em; +} + +.cru-nav-item:hover { + background-color: var(--cru-background-1-color); +} + +.cru-nav-item:not(.active) { + color: var(--cru-primary-r2-color); +} + +.cru-nav-action-area { + margin-left: auto; +} diff --git a/FrontEnd/src/views/common/tab/Tabs.tsx b/FrontEnd/src/views/common/tab/Tabs.tsx index 29ebcbd8..701b4073 100644 --- a/FrontEnd/src/views/common/tab/Tabs.tsx +++ b/FrontEnd/src/views/common/tab/Tabs.tsx @@ -1,6 +1,11 @@ import React from "react"; +import { Link } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import classnames from "classnames"; -import { I18nText } from "@/common"; +import { convertI18nText, I18nText } from "@/common"; + +import "./Tabs.css"; export interface Tab { name: string; @@ -11,9 +16,47 @@ export interface Tab { export interface TabsProps { activeTabName?: string; + actions?: React.ReactNode; + dense?: boolean; tabs: Tab[]; + className?: string; + style?: React.CSSProperties; } export default function Tabs(props: TabsProps): React.ReactElement | null { - return
; + const { tabs, activeTabName, className, style, dense, actions } = props; + + const { t } = useTranslation(); + + return ( +
+ {tabs.map((tab) => { + const active = activeTabName === tab.name; + const className = classnames("cru-nav-item", active && "active"); + + if (tab.link != null) { + return ( + + {convertI18nText(tab.text, t)} + + ); + } else { + return ( + + {convertI18nText(tab.text, t)} + + ); + } + })} +
{actions}
+
+ ); } -- cgit v1.2.3