From 38e030af5c9d91b21a64eef28cbdc08b22b4efcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 27 Aug 2024 15:19:55 -0700 Subject: [PATCH] Support permalinking examples (#365) closes #361 --- examples/demo.tsx | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/examples/demo.tsx b/examples/demo.tsx index ed855ee..83b71be 100644 --- a/examples/demo.tsx +++ b/examples/demo.tsx @@ -1,4 +1,4 @@ -import React, {useState, StrictMode} from 'react'; +import React, {useState, StrictMode, useCallback, useEffect} from 'react'; import {createRoot} from 'react-dom/client'; import {version} from '../package.json'; import {FullDemo} from './full'; @@ -30,8 +30,35 @@ const DEMOS = { type DemoComponentKeys = keyof typeof DEMOS; +function getInitialDemo(): DemoComponentKeys { + const urlParams = new URLSearchParams(window.location.search); + const demo = urlParams.get('demo'); + return demo && demo in DEMOS ? (demo as DemoComponentKeys) : 'full'; +} + function Demo() { - const [demo, setDemo] = useState('full'); + const [demo, setDemo] = useState(getInitialDemo()); + + const handleDemoChange = useCallback((nextDemo: DemoComponentKeys) => { + setDemo(nextDemo); + history.pushState({demo: nextDemo}, '', `?demo=${nextDemo}`); + }, []); + + // handle back/forward navigation + useEffect(() => { + function handlePopState(e: PopStateEvent) { + setDemo(e.state?.demo || 'full'); + } + window.addEventListener('popstate', handlePopState); + return () => { + window.removeEventListener('popstate', handlePopState); + }; + }); + + // update document title + useEffect(() => { + document.title = `QRCode.react Demo - ${DEMOS[demo].label}`; + }, [demo]); const demoData = DEMOS[demo]; @@ -49,7 +76,9 @@ function Demo() {