From b6e72a39437c8827b10237a5be5db09da059bef8 Mon Sep 17 00:00:00 2001 From: HZ991 Date: Thu, 26 Sep 2024 14:10:18 +1000 Subject: [PATCH 1/6] fix: testing deep-linking feature --- .../table-of-contents.component.tsx | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx index 2fa6df8ff..b078126d4 100644 --- a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx +++ b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx @@ -1,7 +1,7 @@ 'use client'; - import { List, ListItem } from '@westpac/ui'; -import { MouseEventHandler, useCallback } from 'react'; +import { usePathname, useRouter } from 'next/navigation'; +import { MouseEventHandler, useCallback, useEffect, useState } from 'react'; import { ArrowDownRightIcon } from '@/components/icons'; @@ -20,7 +20,7 @@ export function TableOfContents({ contents = [] }: TableOfContentsProps) { .join('-'); return ( - {title} + {title} ); })} @@ -37,17 +37,48 @@ const HEADER_HEIGHT = { const BREAKPOINT_MD = 768; function Link({ href, children }: { children?: React.ReactNode; href?: string }) { + const router = useRouter(); + const pathname = usePathname(); + const [scrollToHash, setScrollToHash] = useState(null); + + useEffect(() => { + if (scrollToHash) { + setTimeout(() => { + const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; + const bodyRect = document.body.getBoundingClientRect(); + const elemRect = document?.querySelector(`#${scrollToHash}`)?.getBoundingClientRect(); + const offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; + + window?.scrollTo({ top: offset, behavior: 'smooth' }); + }, 500); + setScrollToHash(null); + } + }, [scrollToHash, pathname]); + const handleClick: MouseEventHandler = useCallback( - ev => { + async ev => { ev.preventDefault(); - const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; - const bodyRect = document.body.getBoundingClientRect(), - elemRect = document?.querySelector(href || '')?.getBoundingClientRect(), - offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; + if (!href) return; - window?.scrollTo({ top: offset, behavior: 'smooth' }); + const [path, hash] = href.split('#'); + const currentPath = pathname; + + if (path === currentPath || !path) { + const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; + const bodyRect = document.body.getBoundingClientRect(); + const elemRect = document?.querySelector(`#${hash}`)?.getBoundingClientRect(); + const offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; + + window?.scrollTo({ top: offset, behavior: 'smooth' }); + window.history.pushState(null, '', `#${hash}`); + } else { + router.prefetch(path); + setScrollToHash(hash); + await router.push(path); + // window.history.pushState(null, '', `#${hash}`); + } }, - [href], + [href, router, pathname], ); return ( @@ -55,4 +86,4 @@ function Link({ href, children }: { children?: React.ReactNode; href?: string }) {children} ); -} +} \ No newline at end of file From 3df78130e5984c013522a276f16caeb524f8540c Mon Sep 17 00:00:00 2001 From: HZ991 Date: Mon, 30 Sep 2024 12:07:27 +1000 Subject: [PATCH 2/6] fix: format --- .../table-of-contents.component.tsx | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx index b078126d4..15f6bed01 100644 --- a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx +++ b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx @@ -20,7 +20,7 @@ export function TableOfContents({ contents = [] }: TableOfContentsProps) { .join('-'); return ( - {title} + {title} ); })} @@ -36,49 +36,45 @@ const HEADER_HEIGHT = { const BREAKPOINT_MD = 768; -function Link({ href, children }: { children?: React.ReactNode; href?: string }) { +function Link({ href, children }: { children?: React.ReactNode; href: string }) { const router = useRouter(); const pathname = usePathname(); const [scrollToHash, setScrollToHash] = useState(null); + const [path, hash] = href.split('#'); + + const scrollToSection = useCallback(() => { + const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; + const bodyRect = document.body.getBoundingClientRect(); + const elemRect = document?.querySelector(`#${hash}`)?.getBoundingClientRect(); + const offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; + + window?.scrollTo({ top: offset, behavior: 'smooth' }); + window.history.pushState(null, '', `#${hash}`); + }, [hash]); useEffect(() => { if (scrollToHash) { setTimeout(() => { - const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; - const bodyRect = document.body.getBoundingClientRect(); - const elemRect = document?.querySelector(`#${scrollToHash}`)?.getBoundingClientRect(); - const offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; - - window?.scrollTo({ top: offset, behavior: 'smooth' }); + scrollToSection(); }, 500); setScrollToHash(null); } - }, [scrollToHash, pathname]); + }, [scrollToHash, pathname, scrollToSection]); const handleClick: MouseEventHandler = useCallback( async ev => { ev.preventDefault(); - if (!href) return; - - const [path, hash] = href.split('#'); const currentPath = pathname; if (path === currentPath || !path) { - const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; - const bodyRect = document.body.getBoundingClientRect(); - const elemRect = document?.querySelector(`#${hash}`)?.getBoundingClientRect(); - const offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; - - window?.scrollTo({ top: offset, behavior: 'smooth' }); - window.history.pushState(null, '', `#${hash}`); + scrollToSection(); } else { router.prefetch(path); setScrollToHash(hash); await router.push(path); - // window.history.pushState(null, '', `#${hash}`); } }, - [href, router, pathname], + [path, hash, router, pathname, scrollToSection], ); return ( @@ -86,4 +82,4 @@ function Link({ href, children }: { children?: React.ReactNode; href?: string }) {children} ); -} \ No newline at end of file +} From bc34de9ba1a3b7c4be2ad63fe79924ed63c23564 Mon Sep 17 00:00:00 2001 From: HZ991 Date: Wed, 2 Oct 2024 15:00:55 +1000 Subject: [PATCH 3/6] fix: added variable for DELAY_TIME_TO_SCROLL - removes magic number --- .../table-of-contents/table-of-contents.component.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx index 15f6bed01..3d8757c41 100644 --- a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx +++ b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx @@ -41,6 +41,7 @@ function Link({ href, children }: { children?: React.ReactNode; href: string }) const pathname = usePathname(); const [scrollToHash, setScrollToHash] = useState(null); const [path, hash] = href.split('#'); + const DELAY_TIME_TO_SCROLL = 500; const scrollToSection = useCallback(() => { const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; @@ -56,7 +57,7 @@ function Link({ href, children }: { children?: React.ReactNode; href: string }) if (scrollToHash) { setTimeout(() => { scrollToSection(); - }, 500); + }, DELAY_TIME_TO_SCROLL); setScrollToHash(null); } }, [scrollToHash, pathname, scrollToSection]); From 6e866f11c537095a33e7f66c9152405fffa33587 Mon Sep 17 00:00:00 2001 From: HZ991 Date: Thu, 17 Oct 2024 14:52:12 +1100 Subject: [PATCH 4/6] navigation using scrollTo and NextJS Link --- .../table-of-contents.component.tsx | 57 ++++++------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx index 3d8757c41..dc2f5e992 100644 --- a/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx +++ b/apps/site/src/app/design-system/[brand]/[...component]/components/content-tabs/components/intro/components/table-of-contents/table-of-contents.component.tsx @@ -1,5 +1,6 @@ 'use client'; import { List, ListItem } from '@westpac/ui'; +import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; import { MouseEventHandler, useCallback, useEffect, useState } from 'react'; @@ -20,7 +21,7 @@ export function TableOfContents({ contents = [] }: TableOfContentsProps) { .join('-'); return ( - {title} + {title} ); })} @@ -36,51 +37,25 @@ const HEADER_HEIGHT = { const BREAKPOINT_MD = 768; -function Link({ href, children }: { children?: React.ReactNode; href: string }) { - const router = useRouter(); - const pathname = usePathname(); - const [scrollToHash, setScrollToHash] = useState(null); +function NavLink({ href, children }: { children?: React.ReactNode; href: string }) { const [path, hash] = href.split('#'); - const DELAY_TIME_TO_SCROLL = 500; + const DELAY_TIME_TO_SCROLL = 100; - const scrollToSection = useCallback(() => { - const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; - const bodyRect = document.body.getBoundingClientRect(); - const elemRect = document?.querySelector(`#${hash}`)?.getBoundingClientRect(); - const offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; + const handleClick: MouseEventHandler = () => { + setTimeout(() => { + const viewport = window.innerWidth < BREAKPOINT_MD ? 'sm' : 'lg'; + const bodyRect = document.body.getBoundingClientRect(); + const elemRect = document?.querySelector(`#${hash}`)?.getBoundingClientRect(); + const offset = (elemRect?.top || 0) - bodyRect.top - HEADER_HEIGHT[viewport]; - window?.scrollTo({ top: offset, behavior: 'smooth' }); - window.history.pushState(null, '', `#${hash}`); - }, [hash]); - - useEffect(() => { - if (scrollToHash) { - setTimeout(() => { - scrollToSection(); - }, DELAY_TIME_TO_SCROLL); - setScrollToHash(null); - } - }, [scrollToHash, pathname, scrollToSection]); - - const handleClick: MouseEventHandler = useCallback( - async ev => { - ev.preventDefault(); - const currentPath = pathname; - - if (path === currentPath || !path) { - scrollToSection(); - } else { - router.prefetch(path); - setScrollToHash(hash); - await router.push(path); - } - }, - [path, hash, router, pathname, scrollToSection], - ); + window?.scrollTo({ top: offset, behavior: 'smooth' }); + window.history.pushState(null, '', `#${hash}`); + }, DELAY_TIME_TO_SCROLL); + }; return ( - + {children} - + ); } From 3e6318911a74dc4bc85d857cfaa2578a0c3c2aad Mon Sep 17 00:00:00 2001 From: HZ991 Date: Thu, 31 Oct 2024 14:35:19 +1100 Subject: [PATCH 5/6] fix: header className mismatch bug for site --- .../components/header/header.component.tsx | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/apps/site/src/app/design-system/[brand]/[...component]/components/header/header.component.tsx b/apps/site/src/app/design-system/[brand]/[...component]/components/header/header.component.tsx index eb0636bc3..ba0c18b99 100644 --- a/apps/site/src/app/design-system/[brand]/[...component]/components/header/header.component.tsx +++ b/apps/site/src/app/design-system/[brand]/[...component]/components/header/header.component.tsx @@ -11,7 +11,7 @@ import { styles as headerStyles } from './header.styles'; const FIXED_HEADER = 162; // 228 - 66 = height to stick export function Header({ className, title, brand }: { brand: string; className?: string; title?: string }) { - const [fixed, setFixed] = useState(typeof window !== 'undefined' ? window.scrollY >= FIXED_HEADER : false); + const [fixed, setFixed] = useState(false); const styles = headerStyles({ brand: brand.toLowerCase() as BrandKey, fixed, className }); const headerRef = useRef(null); const { setOpen } = useSidebar(); @@ -20,32 +20,21 @@ export function Header({ className, title, brand }: { brand: string; className?: if (typeof window !== 'undefined') { const handleScroll = () => { const isFixed = window.scrollY >= FIXED_HEADER; + console.log('window position:' + window.scrollY); + console.log('header position:' + FIXED_HEADER); + console.log('isFixed:' + isFixed); setFixed(isFixed); }; + handleScroll(); window.addEventListener('scroll', handleScroll); + window.addEventListener('load', handleScroll); + return () => window.removeEventListener('scroll', handleScroll); } }, []); return (
-
- Active breakpoint: - SM - MD - LG - -
{/* The tab order on the original site was the grid button before wrapper when coming from the browser bar */} diff --git a/apps/site/src/components/document-renderer/heading/heading.style.ts b/apps/site/src/components/document-renderer/heading/heading.style.ts index f47f4e68b..87e099ce4 100644 --- a/apps/site/src/components/document-renderer/heading/heading.style.ts +++ b/apps/site/src/components/document-renderer/heading/heading.style.ts @@ -1,7 +1,8 @@ import { tv } from 'tailwind-variants'; +// scroll margin top = header height + 24px export const styles = tv({ - base: 'mt-5 font-bold first:mt-0', + base: 'mt-5 scroll-mt-[9.125rem] font-bold first:mt-0 md:scroll-mt-[11.25rem]', variants: { textAlign: { left: 'text-left', @@ -10,7 +11,7 @@ export const styles = tv({ }, level: { 1: 'typography-body-5 mb-3', - 2: 'typography-body-7 mb-4 sm:typography-body-6 sm:mb-7', + 2: 'typography-body-7 sm:typography-body-6 mb-4 sm:mb-7', 3: 'typography-body-8 mb-2', 4: 'typography-body-10 mb-2 uppercase', 5: 'typography-body-9 mb-2',