From 25a73dafe0ab1ca8be9fdbd87f21792d1593df9b Mon Sep 17 00:00:00 2001 From: Nik Tverd Date: Mon, 29 May 2023 14:46:10 +0600 Subject: [PATCH] feat: use RouterLink --- src/blocks/Header/Header.tsx | 16 +++---- src/blocks/Icons/Icons.tsx | 6 +-- src/components/Button/Button.tsx | 3 ++ src/components/CardBase/CardBase.tsx | 14 +----- src/components/FileLink/FileLink.tsx | 10 ++++- .../HeaderBreadcrumbs/HeaderBreadcrumbs.tsx | 5 ++- src/components/Link/Link.tsx | 5 ++- src/components/RouterLink/RouterLink.tsx | 44 +++++++++++++++++-- src/components/Title/Title.tsx | 11 +++-- .../NavigationButton/NavigationButton.tsx | 12 ++--- .../NavigationLink/NavigationLink.tsx | 22 +++------- .../components/SocialIcon/SocialIcon.tsx | 6 +-- src/sub-blocks/BannerCard/BannerCard.tsx | 20 ++++----- 13 files changed, 98 insertions(+), 76 deletions(-) diff --git a/src/blocks/Header/Header.tsx b/src/blocks/Header/Header.tsx index 166a3fa80..ca2c89b99 100644 --- a/src/blocks/Header/Header.tsx +++ b/src/blocks/Header/Header.tsx @@ -1,6 +1,6 @@ import React, {useContext} from 'react'; -import {Button, HTML, Media, RouterLink} from '../../components'; +import {Button, HTML, Media} from '../../components'; import HeaderBreadcrumbs from '../../components/HeaderBreadcrumbs/HeaderBreadcrumbs'; import {getMediaImage} from '../../components/Media/Image/utils'; import YFMWrapper from '../../components/YFMWrapper/YFMWrapper'; @@ -141,14 +141,12 @@ export const HeaderBlock = (props: WithChildren) => {
{buttons && buttons.map((button, index) => ( - -
)} diff --git a/src/blocks/Icons/Icons.tsx b/src/blocks/Icons/Icons.tsx index d2bf3b679..33fb08cab 100644 --- a/src/blocks/Icons/Icons.tsx +++ b/src/blocks/Icons/Icons.tsx @@ -1,6 +1,6 @@ import React, {useContext} from 'react'; -import {BlockHeader, Image} from '../../components'; +import {BlockHeader, Image, RouterLink} from '../../components'; import {LocationContext} from '../../context/locationContext'; import {IconsBlockProps} from '../../models'; import {block, getLinkProps} from '../../utils'; @@ -16,7 +16,7 @@ const Icons = ({title, size = 's', items}: IconsBlockProps) => {
{title && } {items.map((item) => ( - { >

{item.text}

-
+ ))}
); diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index 559ab1adf..7ceb00dbe 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -3,6 +3,7 @@ import React, {useCallback, useContext} from 'react'; import {Button as CommonButton, Icon, Platform, StoreBadge} from '@gravity-ui/uikit'; import {LocaleContext} from '../../context/localeContext/localeContext'; +import {LocationContext} from '../../context/locationContext'; import {useAnalytics} from '../../hooks'; import {useMetrika} from '../../hooks/useMetrika'; import {Github} from '../../icons'; @@ -25,6 +26,7 @@ const b = block('button-block'); const Button = (props: ButtonProps) => { const handleMetrika = useMetrika(); + const {Link} = useContext(LocationContext); const {lang, tld} = useContext(LocaleContext); const { className, @@ -95,6 +97,7 @@ const Button = (props: ButtonProps) => { size={toCommonSize(size as OldButtonSize)} href={url ? setUrlTld(url, tld) : undefined} width={width} + component={Link} {...buttonProps} > {icon && buttonImg.position === 'left' ? icon : null} diff --git a/src/components/CardBase/CardBase.tsx b/src/components/CardBase/CardBase.tsx index 52d3b0e7e..ac972053e 100644 --- a/src/components/CardBase/CardBase.tsx +++ b/src/components/CardBase/CardBase.tsx @@ -107,18 +107,8 @@ export const Layout = (props: CardBaseProps) => { }; return url ? ( - - e.preventDefault()} - onClick={onClick} - > - {cardContent} - + + {cardContent} ) : (
{cardContent}
diff --git a/src/components/FileLink/FileLink.tsx b/src/components/FileLink/FileLink.tsx index 9e4e0a48b..fa2df4b03 100644 --- a/src/components/FileLink/FileLink.tsx +++ b/src/components/FileLink/FileLink.tsx @@ -3,6 +3,7 @@ import React, {useContext} from 'react'; import {LocationContext} from '../../context/locationContext'; import {FileLinkProps, WithChildren} from '../../models'; import {block, getLinkProps} from '../../utils'; +import RouterLink from '../RouterLink/RouterLink'; import './FileLink.scss'; @@ -46,9 +47,14 @@ const FileLink = (props: WithChildren) => {
{fileExt}
)}
- + {text} - +
); diff --git a/src/components/HeaderBreadcrumbs/HeaderBreadcrumbs.tsx b/src/components/HeaderBreadcrumbs/HeaderBreadcrumbs.tsx index c1e2a4bcc..f6c721ba7 100644 --- a/src/components/HeaderBreadcrumbs/HeaderBreadcrumbs.tsx +++ b/src/components/HeaderBreadcrumbs/HeaderBreadcrumbs.tsx @@ -4,6 +4,7 @@ import {useAnalytics} from '../../hooks'; import {useMetrika} from '../../hooks/useMetrika'; import {DefaultEventNames, HeaderBreadCrumbsProps} from '../../models'; import {block} from '../../utils'; +import RouterLink from '../RouterLink/RouterLink'; import './HeaderBreadcrumbs.scss'; @@ -23,9 +24,9 @@ export default function HeaderBreadcrumbs(props: HeaderBreadCrumbsProps) {
{items.map((item) => ( ))}
diff --git a/src/components/Link/Link.tsx b/src/components/Link/Link.tsx index a5dfb81c1..94a6bdece 100644 --- a/src/components/Link/Link.tsx +++ b/src/components/Link/Link.tsx @@ -11,6 +11,7 @@ import {ClassNameProps, DefaultEventNames, LinkProps, TextSize, WithChildren} fr import {block, getLinkProps, setUrlTld} from '../../utils'; import BackLink from '../BackLink/BackLink'; import FileLink from '../FileLink/FileLink'; +import RouterLink from '../RouterLink/RouterLink'; import './Link.scss'; @@ -80,7 +81,7 @@ const LinkBlock = (props: WithChildren) => { const content = children || text; return ( - ) => { ) : ( content )} - +
); } default: diff --git a/src/components/RouterLink/RouterLink.tsx b/src/components/RouterLink/RouterLink.tsx index 09bea0907..60b866b01 100644 --- a/src/components/RouterLink/RouterLink.tsx +++ b/src/components/RouterLink/RouterLink.tsx @@ -1,17 +1,53 @@ -import React, {Fragment, useContext} from 'react'; +import React, {useContext} from 'react'; import {LocationContext} from '../../context/locationContext'; import {WithChildren} from '../../models'; +import {EXTERNAL_LINK_PROPS, isLinkExternal} from '../../utils'; export interface RouterLinkProps { href: string; + forceAnchor?: boolean; + target?: string; + rel?: string; + className?: string; [key: string]: unknown; } -const RouterLink = ({href, children}: WithChildren) => { - const {Link} = useContext(LocationContext); +const RouterLink = ({ + href, + rel, + children, + target, + forceAnchor = false, + ...commonProps +}: WithChildren) => { + const {Link, hostname} = useContext(LocationContext); - return Link ? {children} : {children}; + const isExternal = isLinkExternal(href, hostname); + const shouldAnchorTag = + typeof href === 'string' && + (!Link || isExternal || forceAnchor || target === EXTERNAL_LINK_PROPS.target); + const component = shouldAnchorTag ? 'a' : Link; + + if (!component) { + return
{JSON.stringify({isExternal, shouldAnchorTag, component})}
; + } + + const linkProps = { + href, + target, + rel: target === EXTERNAL_LINK_PROPS.target && !rel ? EXTERNAL_LINK_PROPS.rel : rel, + }; + + return React.createElement( + component, + { + href, + ...(shouldAnchorTag ? linkProps : {}), + ...commonProps, + }, + children, + ); }; export default RouterLink; diff --git a/src/components/Title/Title.tsx b/src/components/Title/Title.tsx index ac9a0e0f1..59dea1f95 100644 --- a/src/components/Title/Title.tsx +++ b/src/components/Title/Title.tsx @@ -1,6 +1,6 @@ import React, {Fragment, ReactNode, useContext} from 'react'; -import {HTML, ToggleArrow} from '../'; +import {HTML, RouterLink, ToggleArrow} from '../'; import {LocationContext} from '../../context/locationContext'; import {MobileContext} from '../../context/mobileContext'; import {TextSize, TitleProps} from '../../models'; @@ -81,9 +81,14 @@ const Title = (props: TitleFullProps) => { content = textMarkup; } else if (url) { content = ( - + {insideClickableContent} - + ); } else if (onClick) { content = ( diff --git a/src/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.tsx b/src/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.tsx index e5ec3f9b5..5a500e41c 100644 --- a/src/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.tsx +++ b/src/navigation/components/NavigationItem/components/NavigationButton/NavigationButton.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {Button, RouterLink} from '../../../../../components'; +import {Button} from '../../../../../components'; import {BlockIdContext} from '../../../../../context/blockIdContext'; import {ButtonProps} from '../../../../../models'; import {block} from '../../../../../utils'; @@ -15,17 +15,11 @@ const ANALYTICS_ID = 'navigation'; type NavigationButtonProps = Pick & ButtonProps; export const NavigationButton: React.FC = (props) => { - const {url, target, className} = props; + const {url, className} = props; const classes = b(null, className); return ( - {target ? ( -