diff --git a/src/App.tsx b/src/App.tsx index 2e72541f7..23b3a971f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import { RouterProvider, createBrowserRouter, createRoutesFromElements, + Navigate, } from "react-router-dom"; import "@abgov/web-components"; @@ -151,6 +152,12 @@ const router = createBrowserRouter( } /> + {/* Redirects from DS2 (Astro) canonical URLs back to this site's canonical URLs */} + } /> + } /> + {/* Old URL alias — both sites use the compact version as canonical */} + } /> + {/* Examples Pages */} }> } /> diff --git a/src/components/component-header/ComponentHeader.tsx b/src/components/component-header/ComponentHeader.tsx index 49e66124d..959b39141 100644 --- a/src/components/component-header/ComponentHeader.tsx +++ b/src/components/component-header/ComponentHeader.tsx @@ -1,8 +1,8 @@ import { GoabBadge, GoabBlock, GoabText } from "@abgov/react-components"; import "./ComponentHeader.css"; -import { Link } from "react-router-dom"; +import { Link, useLocation } from "react-router-dom"; import { useEffect, useState } from "react"; -import { toSentenceCase, fetchAllIssueCounts, fetchComponentMetadataFromProject } from "../../utils"; +import { toSentenceCase, fetchAllIssueCounts, fetchComponentMetadataFromProject, getV2Link } from "../../utils"; export enum Category { CONTENT_AND_LAYOUT = "Content and layout", @@ -23,6 +23,7 @@ interface Props { export const ComponentHeader: React.FC = (props) => { const [issueCount, setIssueCount] = useState(null); + const v2Link = getV2Link(useLocation().pathname); useEffect(() => { if (!props.githubLink) return; @@ -49,6 +50,7 @@ export const ComponentHeader: React.FC = (props) => { {(props.githubLink || props.figmaLink) && ( + New version {/* GitHub Issues link, if we have a "githubLink" */} {props.githubLink && ( diff --git a/src/components/example-header/ExampleHeader.tsx b/src/components/example-header/ExampleHeader.tsx index 7de2e3a6d..13166e0ab 100644 --- a/src/components/example-header/ExampleHeader.tsx +++ b/src/components/example-header/ExampleHeader.tsx @@ -1,5 +1,7 @@ import { GoabBlock, GoabText, GoabBadge } from "@abgov/react-components"; import "../component-header/ComponentHeader.css"; // reusing existing styling from component pages +import { getV2Link } from "../../utils"; +import { useLocation } from "react-router-dom"; interface Props { name: string; @@ -10,6 +12,9 @@ interface Props { } export const ExampleHeader: React.FC = ({ name, description, githubLink, figmaLink, tags }) => { + + const v2Link = getV2Link(useLocation().pathname); + return (
@@ -46,6 +51,7 @@ export const ExampleHeader: React.FC = ({ name, description, githubLink, {(githubLink || figmaLink) && ( + New version {githubLink && ( diff --git a/src/components/version-language-switcher/HelpButton.tsx b/src/components/version-language-switcher/HelpButton.tsx index cb3a58c79..0e4a0aaa3 100644 --- a/src/components/version-language-switcher/HelpButton.tsx +++ b/src/components/version-language-switcher/HelpButton.tsx @@ -1,30 +1,19 @@ import { useContext } from "react"; -import { useLocation } from "react-router-dom"; import { GoabIconButton, GoabTooltip } from "@abgov/react-components"; import { useVersionUpdateNotification } from "@components/version-language-switcher/VersionUpdateNotificationContext"; -import { useSiteWideNotification } from "@contexts/SiteWideNotificationContext"; import { LanguageVersionContext } from "@contexts/LanguageVersionContext"; export function HelpButton() { const { reset: resetVersion } = useVersionUpdateNotification(); - const { reset: resetSiteWideNotification } = useSiteWideNotification(); useContext(LanguageVersionContext); - const location = useLocation(); - const handleHelpClick = () => { - const isComponentOrExamplePage = - location.pathname.startsWith("/components") || location.pathname.startsWith("/examples"); - - if (isComponentOrExamplePage) { - resetVersion(); - } else { - resetSiteWideNotification(); - } + const handleHelpClick = () => { + resetVersion(); }; return ( - + { }, 0); // timeout related to popover collapse }; - const updateVersion = (newValue: "old" | "new") => { + const updateVersion = (newValue: LanguageVersion) => { + if (newValue === "next") return; setTimeout(() => { setVersion(newValue); updateURL("version", newValue); @@ -87,9 +88,10 @@ export const VersionLanguageSwitcher = () => { const getCurrentVersionLabel = (language: string, version: string) => { if (language === "react") { - return version === "new" ? REACT_VERSIONS.NEW.label : REACT_VERSIONS.OLD.label; - } if (language === "angular") { - return version === "new" ? ANGULAR_VERSIONS.NEW.label : ANGULAR_VERSIONS.OLD.label; + return version === "next" ? REACT_VERSIONS.NEXT.label : version === "new" ? REACT_VERSIONS.NEW.label : REACT_VERSIONS.OLD.label; + } + if (language === "angular") { + return version === "next" ? ANGULAR_VERSIONS.NEXT.label : version === "new" ? ANGULAR_VERSIONS.NEW.label : ANGULAR_VERSIONS.OLD.label; } } @@ -119,11 +121,20 @@ export const VersionLanguageSwitcher = () => {
} padded={false}> <> - {["new", "old"].map(ver => ( - updateVersion(ver as LanguageVersion)}> - {getCurrentVersionLabel(language, ver)} - - ))} + {["next", "new", "old"].map(ver => { + if (ver === "next") { + return ( + + {getCurrentVersionLabel(language, ver)} + + ); + } + return ( + updateVersion(ver as LanguageVersion)}> + {getCurrentVersionLabel(language, ver)} + + ); + })} diff --git a/src/components/version-language-switcher/VersionUpdateNotification.tsx b/src/components/version-language-switcher/VersionUpdateNotification.tsx index 63047a1d6..f210364b2 100644 --- a/src/components/version-language-switcher/VersionUpdateNotification.tsx +++ b/src/components/version-language-switcher/VersionUpdateNotification.tsx @@ -2,14 +2,11 @@ import { useEffect } from "react"; import { GoabNotification } from "@abgov/react-components"; import { MAX_CONTENT_WIDTH } from "../../global-constants"; import { useVersionUpdateNotification } from "./VersionUpdateNotificationContext"; -import type { LanguageVersion } from "@components/version-language-switcher/version-language-constants"; +import { getV2Link } from "../../utils"; -interface VersionUpdateNotificationProps { - version: LanguageVersion; -} - -export function VersionUpdateNotification({ version }: VersionUpdateNotificationProps) { - const { isDismissed, dismiss, oldLinkRef, newLinkRef } = useVersionUpdateNotification(); +export function VersionUpdateNotification() { + const { isDismissed, dismiss, newLinkRef } = useVersionUpdateNotification(); + const v2UpgradeLink = getV2Link("/upgrade-guide"); useEffect(() => { const el = document.querySelector("goa-notification"); @@ -24,22 +21,19 @@ export function VersionUpdateNotification({ version }: VersionUpdateNotification if (isDismissed) return null; return ( - - {version === "old" ? ( - <> - Support for v3 (Angular) and v5 (React) has ended. Read the{" "} - - upgrade guide - - - ) : ( + <> - Upgrading to the latest version of the design system?{" "} - - View the upgrade guide - + The new Design System is now available! Check out the{" "} + + migration guide + . - )} ); } diff --git a/src/components/version-language-switcher/VersionUpdateNotificationContext.tsx b/src/components/version-language-switcher/VersionUpdateNotificationContext.tsx index 315a68811..30ae2c1db 100644 --- a/src/components/version-language-switcher/VersionUpdateNotificationContext.tsx +++ b/src/components/version-language-switcher/VersionUpdateNotificationContext.tsx @@ -25,17 +25,17 @@ export const VersionUpdateNotificationProvider = ({ const newLinkRef = useRef(null); useEffect(() => { - const storedValue = localStorage.getItem(storageKey); + const storedValue = sessionStorage.getItem(storageKey); setIsDismissed(storedValue === "true"); }, [version]); const dismiss = () => { - localStorage.setItem(storageKey, "true"); + sessionStorage.setItem(storageKey, "true"); setIsDismissed(true); }; const reset = () => { - localStorage.removeItem(storageKey); + sessionStorage.removeItem(storageKey); setIsDismissed(false); }; diff --git a/src/components/version-language-switcher/version-language-constants.ts b/src/components/version-language-switcher/version-language-constants.ts index 8473c021d..684be49e2 100644 --- a/src/components/version-language-switcher/version-language-constants.ts +++ b/src/components/version-language-switcher/version-language-constants.ts @@ -1,4 +1,4 @@ -export type LanguageVersion = "old" | "new"; +export type LanguageVersion = "old" | "new" | "next"; export type Language = "react" | "angular"; export const ANGULAR_VERSIONS = { OLD: { @@ -8,6 +8,10 @@ export const ANGULAR_VERSIONS = { NEW: { label: "v4.0.0+", value: "new" + }, + NEXT: { + label: "v5.0.0+", + value: "next" } } export const REACT_VERSIONS = { @@ -18,9 +22,15 @@ export const REACT_VERSIONS = { NEW: { label: "v6.0.0+", value: "new" + }, + NEXT: { + label: "v7.0.0+", + value: "next" } } +export const DS_V2_URL = "https://design.alberta.ca/"; + export const LOCAL_STORAGE_LANGUAGE_KEY = "goa-docs-lang"; export const LOCAL_STORAGE_VERSION_KEY = "goa-docs-version"; diff --git a/src/routes/root.tsx b/src/routes/root.tsx index 576a1ef84..0a9cbaad5 100644 --- a/src/routes/root.tsx +++ b/src/routes/root.tsx @@ -22,10 +22,6 @@ import { HelpButton } from "@components/version-language-switcher/HelpButton"; import { VersionLanguageSwitcher } from "@components/version-language-switcher/VersionLanguageSwitcher"; -import { LanguageVersionContext } from "@contexts/LanguageVersionContext"; -import { useContext } from "react"; -import SiteWideNotification from "@components/version-language-switcher/SiteWideNotification"; - function ScrollToTop() { const { pathname } = useLocation(); @@ -38,10 +34,7 @@ function ScrollToTop() { } export default function Root() { - const { version } = useContext(LanguageVersionContext); const location = useLocation(); - const showNotification = - location.pathname.startsWith("/components") || location.pathname.startsWith("/examples"); const [visible, setVisibility] = useState(false); // to show temporary notification on examples route, except temporary-notification playground which needs playground bindings @@ -81,8 +74,7 @@ export default function Root() { Tokens Get support - {showNotification && } - + diff --git a/src/utils/index.ts b/src/utils/index.ts index 081c1042a..ece9e0e41 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -6,6 +6,10 @@ import { type IssueGroup = "Components" | "Examples"; +export function getV2Link(pathname: string): string { + return `https://design.alberta.ca${pathname}`; +} + export function toKebabCase(str: string) { return str .replace(/\s+/g, "-") // Replace spaces with - diff --git a/src/versioned-router.tsx b/src/versioned-router.tsx index ae1c72b75..5cde69440 100644 --- a/src/versioned-router.tsx +++ b/src/versioned-router.tsx @@ -1,4 +1,4 @@ -import { Route, Routes, useParams } from "react-router-dom"; +import { Route, Routes, useParams, Navigate } from "react-router-dom"; import ComponentsPage from "@routes/components/Components.tsx"; import ComponentNotFoundPage from "@routes/not-found/NotFound.tsx"; import AllComponentsPage from "@routes/components/AllComponents.tsx"; @@ -128,6 +128,15 @@ export const ComponentsRouter = () => { radio: , "side-menu": , "skeleton-loader": , + // DS2 (Astro) URL aliases — redirect to DS1 canonical URLs + "circular-progress": , + "file-upload-input": , + "app-header": , + icon: , + "linear-progress": , + notification: , + "radio-group": , + skeleton: , spacer: , table: , tabs: ,