From d3de5b99e13d966c9cc66b9d52aca3982b8b4aa1 Mon Sep 17 00:00:00 2001 From: cyrbuzz Date: Wed, 13 Dec 2023 10:43:52 +0800 Subject: [PATCH] feat: changes --- components/app/header/Header.less | 1 - components/app/header/Header.tsx | 215 ++++++++++--------- components/common/dropdown/Dropdown.tsx | 25 ++- components/common/markdown/Markdown.tsx | 16 +- components/common/markdown/markdown.less | 1 + components/common/typography/Typography.less | 1 + components/common/typography/Typography.tsx | 10 +- components/utilities/useBem.ts | 10 + 8 files changed, 163 insertions(+), 116 deletions(-) create mode 100644 components/utilities/useBem.ts diff --git a/components/app/header/Header.less b/components/app/header/Header.less index 4d8d12f..787a91e 100644 --- a/components/app/header/Header.less +++ b/components/app/header/Header.less @@ -109,7 +109,6 @@ .subql-header-navlink { text-decoration: none; - margin-right: 24px; display: flex; color: var(--sq-gray700); width: fit-content; diff --git a/components/app/header/Header.tsx b/components/app/header/Header.tsx index 831c675..504a361 100644 --- a/components/app/header/Header.tsx +++ b/components/app/header/Header.tsx @@ -10,8 +10,10 @@ import { AiOutlineMenu } from 'react-icons/ai'; import { IoCloseSharp } from 'react-icons/io5'; import { Dropdown, MenuWithDesc, Typography } from '../../common'; import { Context } from 'components/common/provider'; -import { createBEM } from 'components/utilities/createBem'; +import { useBem } from 'components/utilities/useBem'; import './Header.less'; +import { useMemo } from 'react'; +import { createBEM } from 'components/utilities/createBem'; const logo = 'https://static.subquery.network/design/images/logo.svg'; const logoDark = 'https://static.subquery.network/design/images/logo-light.svg'; @@ -65,7 +67,7 @@ export interface LeftHeaderProps { isMobile?: boolean; } const LeftHeader = ({ leftElement, dropdownLinks, isMobile }: LeftHeaderProps) => { - const bem = createBEM('subql-left-header'); + const bem = useBem('subql-left-header'); const { theme } = React.useContext(Context); const sortedDropdownLinks = !leftElement && dropdownLinks && (
@@ -120,63 +122,66 @@ const MiddleHeader = ({ ), }: MiddleHeaderProps) => { const { theme } = React.useContext(Context); - const bem = createBEM('subql-middle-header'); - const sortedAppNavigation = !middleElement && appNavigation && ( - - {appNavigation.map((nav, index) => { - if (nav.dropdown) { - const dropdownMenu = nav.dropdown.map((menu) => ({ - key: menu.link, - label: {menu.label}, - className: clsx(bem('menu-item'), theme === 'dark' && bem('menu-item', { dark: 'dark' })), // should refoctor - })); - return ( -
- { - if (nav.onClick) { - nav.onClick(key); - } else if (isExternalLink(key)) { - window.open(key, '_blank'); - } else { - navigate(key); - } - }} - getPopupContainer={() => { - return document.querySelector(`.middle-item-${index}`) as HTMLElement; - }} - /> -
- ); - } - return ( -
{ - if (!isExternalLink(nav.link ?? '/')) { - navigate(nav.link ?? '/'); - e.stopPropagation(); - e.preventDefault(); - } - }} - > - {renderLink(nav.link ?? '/', nav.label, nav.active || active)} -
- ); - })} -
- ); + const bem = useBem('subql-middle-header'); return ( <> <>{middleElement} - <>{sortedAppNavigation} + {!middleElement && appNavigation && ( + + {appNavigation.map((nav, index) => { + if (nav.dropdown) { + return ( +
+ ({ + key: menu.link, + label: {menu.label}, + className: clsx(bem('menu-item'), theme === 'dark' && bem('menu-item', { dark: 'dark' })), // should refoctor + }))} + label={nav.label} + trigger={[isMobile ? 'click' : 'hover']} + onMenuItemClick={({ key }) => { + if (nav.onClick) { + nav.onClick(key); + } else if (isExternalLink(key)) { + window.open(key, '_blank'); + } else { + navigate(key); + } + }} + onLableClick={() => { + if (nav.link) { + navigate(nav.link); + } + }} + getPopupContainer={() => { + return document.querySelector(`.middle-item-${index}`) as HTMLElement; + }} + /> +
+ ); + } + return ( +
{ + if (!isExternalLink(nav.link ?? '/')) { + navigate(nav.link ?? '/'); + e.stopPropagation(); + e.preventDefault(); + } + }} + > + {renderLink(nav.link ?? '/', nav.label, nav.active || active)} +
+ ); + })} +
+ )} ); }; @@ -201,68 +206,70 @@ export const Header: React.FC> = ({ navigate, active, }) => { - const { screenWidth } = useScreen(); - const isMobile = screenWidth < 768; const { theme } = React.useContext(Context); - const bem = createBEM('subql-header'); - const FullHeader = () => ( -
-
-
- - SubQuery Logo - -
- - - -
- - <>{rightElement} -
- ); - - const MenuHeader = () => { - const [showMenu, setShowMenu] = React.useState(false); - const bem = createBEM('subql-mobile-header'); - const { theme } = React.useContext(Context); - const handleMenuClick = () => { - setShowMenu(!showMenu); - }; + const bem = useBem('subql-header'); + const mobileHeaderBem = useBem('subql-mobile-header'); + const { screenWidth } = useScreen(); + const [showMenu, setShowMenu] = React.useState(false); + const MenuIcon = useMemo(() => (showMenu ? IoCloseSharp : AiOutlineMenu), [showMenu]); + const isMobile = useMemo(() => screenWidth < 768, [screenWidth]); - const MenuIcon = showMenu ? IoCloseSharp : AiOutlineMenu; + return ( + <> + {isMobile ? ( +
+
+
+ + SubQuery Logo + +
- return ( -
-
-
- - SubQuery Logo - + { + setShowMenu(!showMenu); + }} + size={20} + style={{ cursor: 'pointer' }} + />
- - + {showMenu && ( +
+ + + <>{rightElement} +
+ )}
- {showMenu && ( -
- + ) : ( +
+
+
+ + SubQuery Logo + +
+ + - <>{rightElement}
- )} -
- ); - }; - return ( - <> - {isMobile ? : } + <>{rightElement} +
+ )} {children} ); diff --git a/components/common/dropdown/Dropdown.tsx b/components/common/dropdown/Dropdown.tsx index b1d21f8..336171d 100644 --- a/components/common/dropdown/Dropdown.tsx +++ b/components/common/dropdown/Dropdown.tsx @@ -8,12 +8,14 @@ import DownOutlined from '@ant-design/icons/DownOutlined'; import { ItemType, MenuClickEventHandler } from 'rc-menu/lib/interface'; import styles from './Dropdown.module.css'; import { Typography } from '../typography'; +import { Context } from '../provider'; export interface DropdownProps extends Partial { label?: string; menuitem: ItemType[]; menuClassName?: string; onMenuItemClick?: MenuClickEventHandler; + onLableClick?: () => void; LeftLabelIcon?: React.ReactElement; RightLabelIcon?: React.ReactElement; active?: boolean; @@ -27,14 +29,33 @@ export const Dropdown: React.FC = ({ menuClassName, active, onMenuItemClick, + onLableClick, ...props }) => { + const { theme } = React.useContext(Context); const [isOpen, setIsOpen] = React.useState(false); const sortedLabel = ( {LeftLabelIcon} - {label ?? 'Dropdown'} - {LeftLabelIcon ? undefined : RightLabelIcon ? RightLabelIcon : } + { + onLableClick?.(); + }} + > + {label ?? 'Dropdown'} + + + {LeftLabelIcon ? undefined : RightLabelIcon ? ( + RightLabelIcon + ) : ( + + )} + ); diff --git a/components/common/markdown/Markdown.tsx b/components/common/markdown/Markdown.tsx index 5e0d805..93f9aaa 100644 --- a/components/common/markdown/Markdown.tsx +++ b/components/common/markdown/Markdown.tsx @@ -19,8 +19,8 @@ const previewBem = createBEM('subql-markdown-preview'); export interface SubqlMarkdown { value?: string | undefined; onChange?: (val: string | undefined) => void; - inputProps: TextAreaProps; - previewProps: Options; + inputProps?: TextAreaProps; + previewProps?: Options; } const MarkdownPreview: FC = (props) => { @@ -52,9 +52,9 @@ const Markdown: FC = (props) => { Preview - + This entry supports{' '} - + basic markdown @@ -64,6 +64,14 @@ const Markdown: FC = (props) => { {tabVal === 'edit' && ( { diff --git a/components/common/markdown/markdown.less b/components/common/markdown/markdown.less index ec11f81..efc9806 100644 --- a/components/common/markdown/markdown.less +++ b/components/common/markdown/markdown.less @@ -58,6 +58,7 @@ } &-preview { + color: var(--sq-gray700); p { margin: 1em 0; } diff --git a/components/common/typography/Typography.less b/components/common/typography/Typography.less index 96d1153..6f38e44 100644 --- a/components/common/typography/Typography.less +++ b/components/common/typography/Typography.less @@ -141,6 +141,7 @@ } &-link { + cursor: pointer; .subql-typography { transition: .1s all linear; color: var(--sq-gray600); diff --git a/components/common/typography/Typography.tsx b/components/common/typography/Typography.tsx index be1ac1e..eee99e9 100644 --- a/components/common/typography/Typography.tsx +++ b/components/common/typography/Typography.tsx @@ -18,8 +18,8 @@ type Props = { tooltipIcon?: React.ReactNode; } & React.HTMLProps; -export interface LinkProps { - href: string; +export interface LinkProps extends Props { + href?: string; children?: React.ReactNode; active?: boolean; } @@ -68,12 +68,12 @@ const TypographyInner: React.FC = ({ ); }; -const Link: React.FC = (props) => { - const { href, children, active = false } = props; +const Link: React.FC> = (props) => { + const { href, children, active = false, ...rest } = props; return ( - {children} + {children} ); }; diff --git a/components/utilities/useBem.ts b/components/utilities/useBem.ts new file mode 100644 index 0000000..1168de7 --- /dev/null +++ b/components/utilities/useBem.ts @@ -0,0 +1,10 @@ +// Copyright 2020-2022 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import { useMemo } from 'react'; +import { createBEM } from './createBem'; + +export const useBem = (bemName: string) => { + const bem = useMemo(() => createBEM(bemName), [bemName]); + return bem; +};