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/Skeleton.css | 14 +++++++++ FrontEnd/src/views/common/Skeleton.tsx | 4 ++- FrontEnd/src/views/common/index.css | 23 ++++++--------- FrontEnd/src/views/common/tab/TabPages.tsx | 33 ++++++++++++++------- FrontEnd/src/views/common/tab/Tabs.css | 31 ++++++++++++++++++++ FrontEnd/src/views/common/tab/Tabs.tsx | 47 ++++++++++++++++++++++++++++-- 6 files changed, 125 insertions(+), 27 deletions(-) create mode 100644 FrontEnd/src/views/common/Skeleton.css create mode 100644 FrontEnd/src/views/common/tab/Tabs.css (limited to 'FrontEnd/src/views/common') diff --git a/FrontEnd/src/views/common/Skeleton.css b/FrontEnd/src/views/common/Skeleton.css new file mode 100644 index 00000000..db1a1c34 --- /dev/null +++ b/FrontEnd/src/views/common/Skeleton.css @@ -0,0 +1,14 @@ +.cru-skeleton { + padding: 0 1em; +} + +.cru-skeleton-line { + height: 1em; + background-color: #e6e6e6; + margin: 0.7em 0; + border-radius: 0.2em; +} + +.cru-skeleton-line.last { + width: 50%; +} diff --git a/FrontEnd/src/views/common/Skeleton.tsx b/FrontEnd/src/views/common/Skeleton.tsx index 14886c71..58d34215 100644 --- a/FrontEnd/src/views/common/Skeleton.tsx +++ b/FrontEnd/src/views/common/Skeleton.tsx @@ -1,6 +1,8 @@ import React from "react"; import classnames from "classnames"; -import { range } from "lodash"; +import range from "lodash/range"; + +import "./Skeleton.css"; export interface SkeletonProps { lineNumber?: number; diff --git a/FrontEnd/src/views/common/index.css b/FrontEnd/src/views/common/index.css index 62167cfc..529e0e51 100644 --- a/FrontEnd/src/views/common/index.css +++ b/FrontEnd/src/views/common/index.css @@ -108,6 +108,10 @@ color: var(--cru-danger-color); } +.cru-text-center { + text-align: center; +} + .cru-text-end { text-align: end; } @@ -128,6 +132,11 @@ clear: both; } +.cru-fill-parent { + width: 100%; + height: 100%; +} + .icon-button { font-size: 1.4rem; cursor: pointer; @@ -160,20 +169,6 @@ border-radius: 50%; } -.cru-skeleton { - padding: 0 1em; -} - -.cru-skeleton-line { - height: 1em; - background-color: #e6e6e6; - margin: 0.7em 0; - border-radius: 0.2em; -} -.cru-skeleton-line.last { - width: 50%; -} - .cru-tab-pages-action-area { display: flex; align-items: center; 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