From 7ceaa68ca30f09b8a7a1afc81f6e102275edccb5 Mon Sep 17 00:00:00 2001 From: ukorvl Date: Thu, 3 Aug 2023 20:24:21 +0400 Subject: [PATCH] add UniservsalLink component #44 --- app/not-found.tsx | 4 +- app/page.tsx | 6 +-- components/Footer/Location.tsx | 6 +-- components/Footer/Mail.tsx | 5 +- components/Menu/SocialLinksList.tsx | 6 +-- components/SocialIcons/SocialIcons.tsx | 6 +-- components/TopMenu/TopMenu.tsx | 14 +++--- components/UniservsalLink/UniservsalLink.tsx | 51 ++++++++++++++++++++ 8 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 components/UniservsalLink/UniservsalLink.tsx diff --git a/app/not-found.tsx b/app/not-found.tsx index dc1e16c..d48c597 100644 --- a/app/not-found.tsx +++ b/app/not-found.tsx @@ -1,4 +1,4 @@ -import Link from 'next/link'; +import UniservsalLink from '@/components/UniservsalLink/UniservsalLink'; /** * @returns React component. @@ -9,7 +9,7 @@ export default function NotFound() {

Not Found

Could not find requested resource

- View all posts + View all posts

); diff --git a/app/page.tsx b/app/page.tsx index 8411a35..f2433ff 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx'; -import Link from 'next/link'; import AppearInViewport from '@/components/AppearInViewport/AppearInViewport'; import MainPageVideoPlayer from '@/components/MainPageVideoPlayer/MainPageVideoPlayer'; +import UniservsalLink from '@/components/UniservsalLink/UniservsalLink'; const containerCn = clsx('relative', 'z-10', 'flex', 'flex-col', 'items-center', 'grow'); const titleCn = clsx('font-light', 'text-8xl'); @@ -33,12 +33,12 @@ export default function Home() { className={exploreCn} variants={exploreLinkVariants} > - EXPLORE - + diff --git a/components/Footer/Location.tsx b/components/Footer/Location.tsx index 32c587d..a661574 100644 --- a/components/Footer/Location.tsx +++ b/components/Footer/Location.tsx @@ -1,6 +1,6 @@ import clsx from 'clsx'; -import Link from 'next/link'; import {memo} from 'react'; +import UniservsalLink from '../UniservsalLink/UniservsalLink'; const {NEXT_PUBLIC_LOCATION_ADDRESS_TEXT, NEXT_PUBLIC_LOCATION_GOOGLE_MAPS_LINK} = process.env; @@ -14,13 +14,13 @@ const linkCn = clsx('animated-link'); function Location() { return (
-
{NEXT_PUBLIC_LOCATION_ADDRESS_TEXT}
- +
); } diff --git a/components/Footer/Mail.tsx b/components/Footer/Mail.tsx index 50c6956..4a30641 100644 --- a/components/Footer/Mail.tsx +++ b/components/Footer/Mail.tsx @@ -1,5 +1,6 @@ import clsx from 'clsx'; import {memo} from 'react'; +import UniservsalLink from '../UniservsalLink/UniservsalLink'; const {NEXT_PUBLIC_CONTACT_EMAIL} = process.env; @@ -12,12 +13,12 @@ const anchorCn = clsx('animated-link'); function Mail() { return (
- {NEXT_PUBLIC_CONTACT_EMAIL} - +
); } diff --git a/components/Menu/SocialLinksList.tsx b/components/Menu/SocialLinksList.tsx index 7a0a3ca..919fb6b 100644 --- a/components/Menu/SocialLinksList.tsx +++ b/components/Menu/SocialLinksList.tsx @@ -1,6 +1,6 @@ -import Link from 'next/link'; import {memo} from 'react'; import clsx from 'clsx'; +import UniservsalLink from '../UniservsalLink/UniservsalLink'; const {NEXT_PUBLIC_FACEBOOK_ADDRESS, NEXT_PUBLIC_INSTAGRAM_ADDRESS, NEXT_PUBLIC_TELEGRAM_ADDRESS} = process.env; @@ -30,14 +30,14 @@ function SocialLinksList() { return (
{linksConfig.map(({title, href}) => ( - {title.toUpperCase()} - + ))}
); diff --git a/components/SocialIcons/SocialIcons.tsx b/components/SocialIcons/SocialIcons.tsx index 79457ff..b6a4439 100644 --- a/components/SocialIcons/SocialIcons.tsx +++ b/components/SocialIcons/SocialIcons.tsx @@ -2,12 +2,12 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import clsx from 'clsx'; -import Link from 'next/link'; import {twMerge} from 'tailwind-merge'; import {memo} from 'react'; import {m} from 'framer-motion'; import iconsConfig from './iconsConfig'; import AppearInViewport from '../AppearInViewport/AppearInViewport'; +import UniservsalLink from '../UniservsalLink/UniservsalLink'; const iconsCn = clsx( 'flex', @@ -54,7 +54,7 @@ function SocialIcons() { key={href} variants={variants} > - @@ -62,7 +62,7 @@ function SocialIcons() { className={twMerge(iconCn, className)} {...rest} /> - + ))} diff --git a/components/TopMenu/TopMenu.tsx b/components/TopMenu/TopMenu.tsx index 4f3bec0..af4e75f 100644 --- a/components/TopMenu/TopMenu.tsx +++ b/components/TopMenu/TopMenu.tsx @@ -1,10 +1,10 @@ 'use client'; -import Link from 'next/link'; import clsx from 'clsx'; import {m} from 'framer-motion'; import {menuItemsConfig, socialLinksConfig} from './topMenuCongif'; import Menu from '../Menu/Menu'; +import UniservsalLink from '../UniservsalLink/UniservsalLink'; const variants = { open: { @@ -37,24 +37,24 @@ export default function TopMenu() { className={itemsListCn} > - SALSAVIVA - + {menuItemsConfig.map(({href, text, bgImgPath}, idx) => ( - {text} - + ))} @@ -67,13 +67,13 @@ export default function TopMenu() { key={idx} className={socialLinkMenuItem} > - {text.toUpperCase()} - + ))} diff --git a/components/UniservsalLink/UniservsalLink.tsx b/components/UniservsalLink/UniservsalLink.tsx new file mode 100644 index 0000000..e801fda --- /dev/null +++ b/components/UniservsalLink/UniservsalLink.tsx @@ -0,0 +1,51 @@ +import Link, {LinkProps} from 'next/link'; +import {AnchorHTMLAttributes, forwardRef} from 'react'; + +/** + * Props. + */ +type UniservsalLinkProps = Omit, keyof LinkProps> & + LinkProps; + +const externalLinkOpenings = ['https://', 'http://', 'mailto:', 'tel:']; + +/** + * @param href Href. + * @returns True if link is external. + */ +function isLinkExternal(href: string) { + return externalLinkOpenings.some(opening => href.startsWith(opening)); +} + +/** + * @returns React component. + */ +const UniservsalLink = forwardRef(function UniservsalLink( + {children, href, ...props}, + ref, +) { + if (typeof href === 'object' || !isLinkExternal(href)) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +}); + +export default UniservsalLink;