From 06238c57a6ebf354e32937108e0ecc34e04eb902 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Wed, 4 Aug 2021 22:41:58 +0800 Subject: [PATCH] feat: SidebarView --- web/src/components/DevContainer.tsx | 9 + web/src/components/SidebarView.tsx | 167 ++++++++++++++++++ .../components/modals/SettingsView/About.tsx | 6 + .../components/modals/SettingsView/index.tsx | 43 +++++ web/src/routes/Main/Navbar/SettingBtn.tsx | 8 +- web/tailwind.config.js | 1 + 6 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 web/src/components/DevContainer.tsx create mode 100644 web/src/components/SidebarView.tsx create mode 100644 web/src/components/modals/SettingsView/About.tsx create mode 100644 web/src/components/modals/SettingsView/index.tsx diff --git a/web/src/components/DevContainer.tsx b/web/src/components/DevContainer.tsx new file mode 100644 index 00000000..8259e1cf --- /dev/null +++ b/web/src/components/DevContainer.tsx @@ -0,0 +1,9 @@ +import React, { Fragment } from 'react'; +import { isDevelopment } from 'tailchat-shared'; + +export const DevContainer: React.FC = React.memo((props) => { + return isDevelopment ? {props.children} : null; +}); +DevContainer.displayName = 'DevContainer'; + +export default DevContainer; diff --git a/web/src/components/SidebarView.tsx b/web/src/components/SidebarView.tsx new file mode 100644 index 00000000..903643f0 --- /dev/null +++ b/web/src/components/SidebarView.tsx @@ -0,0 +1,167 @@ +import React, { useState, useContext } from 'react'; +import _get from 'lodash/get'; +import { DevContainer } from './DevContainer'; +import clsx from 'clsx'; + +export interface SidebarViewMenuItemType { + type: 'item'; + title: string; + content: React.ReactNode; + + /** + * 是否是仅开发者可见 + */ + isDev?: boolean; + + /** + * 隐藏这个项 + */ + hidden?: boolean; +} + +interface SidebarViewLinkType { + type: 'link'; + title: string; + onClick: () => void; + isDanger?: boolean; +} + +const SidebarViewMenuItemTitle: React.FC<{ + active?: boolean; + isDanger?: boolean; + onClick: () => void; +}> = (props) => ( +
+ {props.children} +
+); + +interface SidebarViewContextProps { + content: React.ReactNode; + setContent: (content: React.ReactNode) => void; +} +export const SidebarViewContext = + React.createContext(null); +SidebarViewContext.displayName = 'SidebarViewContext'; + +export type SidebarViewMenuItem = SidebarViewMenuItemType | SidebarViewLinkType; +export type SidebarViewMenuType = + | { + type: 'group'; + title: string; + children: SidebarViewMenuItem[]; + } + | SidebarViewMenuItem; + +interface SidebarViewMenuProps { + menu: SidebarViewMenuType; +} +const SidebarViewMenuItem: React.FC = React.memo( + (props) => { + const { menu } = props; + const context = useContext(SidebarViewContext); + + if (!context) { + return null; + } + + const { content, setContent } = context; + + if (menu.type === 'group') { + return ( +
+
+ {menu.title} +
+
+ {menu.children.map((sub, i) => ( + + ))} +
+
+ ); + } else if (menu.type === 'item') { + if (menu.hidden === true) { + return null; + } + + const component = ( + setContent(menu.content)} + > + {menu.title} + + ); + + if (menu.isDev === true) { + return {component}; + } else { + return
{component}
; + } + } else if (menu.type === 'link') { + return ( +
+ + {menu.title} + +
+ ); + } + + return null; + } +); +SidebarViewMenuItem.displayName = 'SidebarViewMenuItem'; + +interface SidebarViewProps { + menu: SidebarViewMenuType[]; + + /** + * 默认内容路径 + * @default "0.children.0.content" + */ + defaultContentPath: string; +} +export const SidebarView: React.FC = React.memo((props) => { + const { menu, defaultContentPath = '0.children.0.content' } = props; + const [content, setContent] = useState( + _get(menu, defaultContentPath, null) + ); + + return ( + +
+
+ {menu.map((item, i) => ( + + ))} +
+ +
+ {content} +
+
+
+ ); +}); +SidebarView.displayName = 'SidebarView'; diff --git a/web/src/components/modals/SettingsView/About.tsx b/web/src/components/modals/SettingsView/About.tsx new file mode 100644 index 00000000..43c9eec6 --- /dev/null +++ b/web/src/components/modals/SettingsView/About.tsx @@ -0,0 +1,6 @@ +import React from 'react'; + +export const SettingsAbout: React.FC = React.memo(() => { + return
关于
; +}); +SettingsAbout.displayName = 'SettingsAbout'; diff --git a/web/src/components/modals/SettingsView/index.tsx b/web/src/components/modals/SettingsView/index.tsx new file mode 100644 index 00000000..c87b8b25 --- /dev/null +++ b/web/src/components/modals/SettingsView/index.tsx @@ -0,0 +1,43 @@ +import { FullModal } from '@/components/FullModal'; +import { SidebarView, SidebarViewMenuType } from '@/components/SidebarView'; +import React, { useCallback, useMemo } from 'react'; +import { t } from 'tailchat-shared'; +import { SettingsAbout } from './About'; + +interface SettingsViewProps { + onClose: () => void; +} +export const SettingsView: React.FC = React.memo((props) => { + const handleChangeVisible = useCallback( + (visible) => { + if (visible === false && typeof props.onClose === 'function') { + props.onClose(); + } + }, + [props.onClose] + ); + + const menu: SidebarViewMenuType[] = useMemo( + () => [ + { + type: 'group', + title: t('通用'), + children: [ + { + type: 'item', + title: t('关于'), + content: , + }, + ], + }, + ], + [] + ); + + return ( + + + + ); +}); +SettingsView.displayName = 'SettingsView'; diff --git a/web/src/routes/Main/Navbar/SettingBtn.tsx b/web/src/routes/Main/Navbar/SettingBtn.tsx index 900e41b6..a84c77ae 100644 --- a/web/src/routes/Main/Navbar/SettingBtn.tsx +++ b/web/src/routes/Main/Navbar/SettingBtn.tsx @@ -1,15 +1,11 @@ -import { FullModal } from '@/components/FullModal'; import { closeModal, openModal } from '@/components/Modal'; +import { SettingsView } from '@/components/modals/SettingsView'; import { Icon } from '@iconify/react'; import React, { useCallback } from 'react'; export const SettingBtn: React.FC = React.memo(() => { const handleClick = useCallback(() => { - const key = openModal( - closeModal(key)}> - Setting View - - ); + const key = openModal( closeModal(key)} />); }, []); return ( diff --git a/web/tailwind.config.js b/web/tailwind.config.js index c091789e..c49c0599 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -74,6 +74,7 @@ module.exports = { opacity: ['disabled'], display: ['group-hover'], borderRadius: ['hover'], + borderWidth: ['last'], }, }, plugins: [tailchat],