diff --git a/apps/charterafrica/src/components/CommunityPlatforms/CommunityPlatforms.snap.js b/apps/charterafrica/src/components/CommunityPlatforms/CommunityPlatforms.snap.js index 452a917f4..5d17634ac 100644 --- a/apps/charterafrica/src/components/CommunityPlatforms/CommunityPlatforms.snap.js +++ b/apps/charterafrica/src/components/CommunityPlatforms/CommunityPlatforms.snap.js @@ -65,7 +65,7 @@ exports[` renders unchanged 1`] = ` renders unchanged 1`] = ` class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root" > renders unchanged 1`] = ` class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root" > renders unchanged 1`] = ` class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root" > renders unchanged 1`] = ` class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12 css-18qart5-MuiGrid-root" > renders unchanged 1`] = ` class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12 css-18qart5-MuiGrid-root" > renders unchanged 1`] = ` class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12 css-18qart5-MuiGrid-root" > renders unchanged 1`] = `
renders unchanged 1`] = `
renders unchanged 1`] = `
renders unchanged 1`] = ` > CfA builds digital democracy solutions that give citizens unfettered access to actionable information that empowers them to make informed decisions, which strengthens civic engagement for improved public governance and accountability. This includes building infrastructures like the continent’s largest open data portals at  renders unchanged 1`] = `  and  renders unchanged 1`] = ` . CfA incubates initiatives as diverse as the  renders unchanged 1`] = `  network, the  renders unchanged 1`] = `  fact-checking initiative and the  renders unchanged 1`] = ` > CfA manages the  renders unchanged 1`] = `  (ANCIR), which gives the continent’s top muckraking newsrooms the best possible  renders unchanged 1`] = ` renders unchanged 1`] = `  and  renders unchanged 1`] = `  to help improve their ability to tackle crooked politicians, organised crime and predatory big business. CfA runs  renders unchanged 1`] = ` , one of the continent’s largest  renders unchanged 1`] = `  initiatives for digital journalists, and seed funds cross-border collaboration. CfA’s research and analysis programme  renders unchanged 1`] = ` > CfA shares a covenant with the rest of the  renders unchanged 1`] = ` class="MuiCardActions-root MuiCardActions-spacing css-1to78gr-MuiCardActions-root" > renders unchanged 1`] = ` class="MuiCardActions-root MuiCardActions-spacing css-1to78gr-MuiCardActions-root" > renders unchanged 1`] = `
({ + sx={(theme: Theme) => ({ "&>svg,&>img": { transition: theme.transitions.create(["opacity", "transform"]), }, @@ -56,14 +57,14 @@ const Logo = React.forwardRef(function Logo( > {title?.length ? ( ({ + sx={{ fill: { xs: "none" }, fontSize: 32, left: -24, opacity: 0, position: "absolute", right: 0, - })} + }} > @@ -86,7 +87,7 @@ const Logo = React.forwardRef(function Logo( textTransform="uppercase" typography="h4" underline="none" - sx={({ transitions, typography }) => ({ + sx={({ transitions, typography }: Theme) => ({ display: "flex", fontFamily: typography.fontFamilyMono, transition: transitions.create(["opacity", "transform"]), diff --git a/packages/commons-ui-next/src/Link/PagesRouterLink.js b/packages/commons-ui-next/src/Link/PagesRouterLink.js new file mode 100644 index 000000000..c1fc57fac --- /dev/null +++ b/packages/commons-ui-next/src/Link/PagesRouterLink.js @@ -0,0 +1,89 @@ +/* eslint-env browser */ +import clsx from "clsx"; +import { useRouter } from "next/router"; +import PropTypes from "prop-types"; +import React, { useEffect, useState } from "react"; + +import StyledLink from "./StyledLink"; + +import isExternalUrl from "@/commons-ui/next/utils/isExternalUrl"; + +function checkIfPathsMatch(linkPath, currentPath) { + return linkPath === currentPath; +} + +const PagesRouterLink = React.forwardRef( + function PagesRouterLinkLink(props, ref) { + const { + activeClassName = "active", + as, + className: classNameProp, + href, + isActive: isActiveProp, + linkAs: linkAsProp, + ...other + } = props; + + const { asPath, isReady } = useRouter(); + const [className, setClassName] = useState(classNameProp); + const isActive = isActiveProp || checkIfPathsMatch; + const isInternalLink = !isExternalUrl( + typeof href === "string" ? href : href.pathname, + ); + const linkAs = linkAsProp || as; + + useEffect(() => { + if (isReady && isInternalLink) { + const linkPathname = new URL(linkAs || href, window.location.href) + .pathname; + const currentPathname = new URL(asPath, window.location.href).pathname; + const newClassName = clsx(classNameProp, { + [activeClassName]: isActive(linkPathname, currentPathname), + }); + if (newClassName !== className) { + setClassName(newClassName); + } + } + }, [ + activeClassName, + asPath, + className, + classNameProp, + href, + isActive, + isInternalLink, + isReady, + linkAs, + ]); + + return ( + + ); + }, +); + +PagesRouterLink.propTypes = { + activeClassName: PropTypes.string, + as: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), + className: PropTypes.string, + href: PropTypes.string, + isActive: PropTypes.func, + legacyBehavior: PropTypes.bool, + linkAs: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), + locale: PropTypes.string, + noLinkStyle: PropTypes.bool, + prefetch: PropTypes.bool, + replace: PropTypes.bool, + role: PropTypes.string, + scroll: PropTypes.bool, + shallow: PropTypes.bool, +}; + +export default PagesRouterLink; diff --git a/packages/commons-ui-next/src/Link/Link.snap.js b/packages/commons-ui-next/src/Link/PagesRouterLink.snap.js similarity index 81% rename from packages/commons-ui-next/src/Link/Link.snap.js rename to packages/commons-ui-next/src/Link/PagesRouterLink.snap.js index 87676a140..b793a3a41 100644 --- a/packages/commons-ui-next/src/Link/Link.snap.js +++ b/packages/commons-ui-next/src/Link/PagesRouterLink.snap.js @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` renders unchanged 1`] = ` +exports[` renders unchanged 1`] = `
", () => { + it("renders unchanged", () => { + const { container } = render( + Home, + ); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/commons-ui-next/src/Link/Link.js b/packages/commons-ui-next/src/Link/StyledLink.js similarity index 59% rename from packages/commons-ui-next/src/Link/Link.js rename to packages/commons-ui-next/src/Link/StyledLink.js index 5356e339e..956af28ea 100644 --- a/packages/commons-ui-next/src/Link/Link.js +++ b/packages/commons-ui-next/src/Link/StyledLink.js @@ -1,18 +1,15 @@ -/* eslint-env browser */ import MuiLink from "@mui/material/Link"; import { styled } from "@mui/material/styles"; -import clsx from "clsx"; import NextLink from "next/link"; -import { useRouter } from "next/router"; import PropTypes from "prop-types"; -import React, { useEffect, useState } from "react"; +import React from "react"; import isExternalUrl from "@/commons-ui/next/utils/isExternalUrl"; // Add support for the sx prop for consistency with the other branches. const Anchor = styled("a")({}); -export const NextLinkComposed = React.forwardRef( +const NextLinkComposed = React.forwardRef( function NextLinkComposed(props, ref) { const { linkAs, @@ -57,19 +54,13 @@ NextLinkComposed.propTypes = { to: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired, }; -function checkIfPathsMatch(linkPath, currentPath) { - return linkPath === currentPath; -} - // A styled version of the Next.js Link component: // https://nextjs.org/docs/api-reference/next/link -const Link = React.forwardRef(function Link(props, ref) { +const StyledLink = React.forwardRef(function Link(props, ref) { const { - activeClassName = "active", as, - className: classNameProp, + className, href, - isActive: isActiveProp, legacyBehavior, linkAs: linkAsProp, locale, @@ -82,37 +73,9 @@ const Link = React.forwardRef(function Link(props, ref) { ...other } = props; - const { asPath, isReady } = useRouter(); - const [className, setClassName] = useState(classNameProp); - const linkAs = linkAsProp || as; - const isActive = isActiveProp || checkIfPathsMatch; - - useEffect(() => { - if (isReady) { - const linkPathname = new URL(linkAs || href, window.location.href) - .pathname; - const activePathname = new URL(asPath, window.location.href).pathname; - const newClassName = clsx(classNameProp, { - [activeClassName]: isActive(linkPathname, activePathname), - }); - - if (newClassName !== className) { - setClassName(newClassName); - } - } - }, [ - activeClassName, - asPath, - className, - classNameProp, - href, - isActive, - isReady, - linkAs, - ]); - - const isExternal = isExternalUrl(href); - + // https://nextjs.org/docs/app/api-reference/components/link#href-required + const url = typeof href === "string" ? href : href.pathname; + const isExternal = isExternalUrl(url); if (isExternal) { const externalLinkProps = { href, @@ -120,12 +83,13 @@ const Link = React.forwardRef(function Link(props, ref) { target: "_blank", ...other, }; - if (noLinkStyle) { - return ; - } - return ; + const LinkComponent = noLinkStyle ? Anchor : MuiLink; + return ( + + ); } + const linkAs = linkAsProp || as; const nextjsProps = { to: href, linkAs, @@ -137,33 +101,23 @@ const Link = React.forwardRef(function Link(props, ref) { locale, }; - if (noLinkStyle) { - return ( - - ); - } + const LinkComponent = noLinkStyle ? NextLinkComposed : MuiLink; + const component = noLinkStyle ? undefined : NextLinkComposed; return ( - ); }); -Link.propTypes = { - activeClassName: PropTypes.string, +StyledLink.propTypes = { as: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), className: PropTypes.string, href: PropTypes.string, - isActive: PropTypes.func, legacyBehavior: PropTypes.bool, linkAs: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), locale: PropTypes.string, @@ -175,4 +129,4 @@ Link.propTypes = { shallow: PropTypes.bool, }; -export default Link; +export default StyledLink; diff --git a/packages/commons-ui-next/src/Link/StyledLink.snap.js b/packages/commons-ui-next/src/Link/StyledLink.snap.js new file mode 100644 index 000000000..db0e8ddea --- /dev/null +++ b/packages/commons-ui-next/src/Link/StyledLink.snap.js @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders unchanged 1`] = ` + +`; diff --git a/packages/commons-ui-next/src/Link/Link.test.js b/packages/commons-ui-next/src/Link/StyledLink.test.js similarity index 53% rename from packages/commons-ui-next/src/Link/Link.test.js rename to packages/commons-ui-next/src/Link/StyledLink.test.js index 4ef10c59d..0d9c03e0a 100644 --- a/packages/commons-ui-next/src/Link/Link.test.js +++ b/packages/commons-ui-next/src/Link/StyledLink.test.js @@ -1,11 +1,11 @@ import { render } from "@commons-ui/testing-library"; import React from "react"; -import Link from "./Link"; +import StyledLink from "./StyledLink"; -describe("", () => { +describe("", () => { it("renders unchanged", () => { - const { container } = render(Home); + const { container } = render(Home); expect(container).toMatchSnapshot(); }); }); diff --git a/packages/commons-ui-next/src/Link/index.js b/packages/commons-ui-next/src/Link/index.js index 6d59fd0b2..f0bdce76f 100644 --- a/packages/commons-ui-next/src/Link/index.js +++ b/packages/commons-ui-next/src/Link/index.js @@ -1,3 +1,7 @@ -import Link from "./Link"; +import PagesRouterLink from "./PagesRouterLink"; +import StyledLink from "./StyledLink"; -export default Link; +export { StyledLink, PagesRouterLink }; + +// To be backward-compatible, set default Link to PagesRouterLink +export default PagesRouterLink; diff --git a/packages/commons-ui-next/src/index.js b/packages/commons-ui-next/src/index.js index 4b21cb922..548f9c705 100644 --- a/packages/commons-ui-next/src/index.js +++ b/packages/commons-ui-next/src/index.js @@ -1,5 +1,6 @@ -/* eslint-disable import/prefer-default-export */ - export { default as Figure } from "./Figure"; + export { default as Link } from "./Link"; +export * from "./Link"; + export { default as RichTypography } from "./RichTypography"; diff --git a/packages/hurumap-next/src/Source/Source.snap.js b/packages/hurumap-next/src/Source/Source.snap.js index 3c0a29d24..b54076180 100644 --- a/packages/hurumap-next/src/Source/Source.snap.js +++ b/packages/hurumap-next/src/Source/Source.snap.js @@ -10,7 +10,7 @@ exports[`Source renders unchanged 1`] = ` :