@@ -10,6 +10,7 @@ import ShowcaseCardIcon from "../ShowcaseIcon/index";
1010import useBaseUrl from "@docusaurus/useBaseUrl" ;
1111import { useColorMode } from "@docusaurus/theme-common" ;
1212import siteConfig from "@generated/docusaurus.config" ;
13+ import { useHistory , useLocation } from "@docusaurus/router" ;
1314
1415type GitHubRepoInfo = {
1516 forks : number ;
@@ -27,6 +28,8 @@ function ShowcaseCard({
2728 const tags = user . tags ;
2829 const title = user . title ;
2930 const { colorMode } = useColorMode ( ) ;
31+ const history = useHistory ( ) ;
32+ const location = useLocation ( ) ;
3033
3134 const lightTheme : PartialTheme = {
3235 semanticColors : {
@@ -45,6 +48,44 @@ function ShowcaseCard({
4548 const [ isOpen , { setTrue : openPanel , setFalse : dismissPanel } ] = useBoolean ( false ) ;
4649 const [ githubData , setGithubData ] = useState < GitHubRepoInfo > ( null ) ;
4750
51+ // Create a URL-safe slug from the title
52+ const createSlug = ( text : string ) => {
53+ return encodeURIComponent ( text . toLowerCase ( ) . replace ( / [ ^ a - z 0 - 9 ] + / g, '-' ) . replace ( / ^ - | - $ / g, '' ) ) ;
54+ } ;
55+
56+ const cardSlug = createSlug ( title ) ;
57+
58+ // Handle opening panel with deep link
59+ const handleCardClick = ( ) => {
60+ const searchParams = new URLSearchParams ( location . search ) ;
61+ searchParams . set ( 'card' , cardSlug ) ;
62+ history . push ( {
63+ pathname : location . pathname ,
64+ search : searchParams . toString ( ) ,
65+ } ) ;
66+ openPanel ( ) ;
67+ } ;
68+
69+ // Handle closing panel and removing deep link
70+ const handleDismissPanel = ( ) => {
71+ const searchParams = new URLSearchParams ( location . search ) ;
72+ searchParams . delete ( 'card' ) ;
73+ history . push ( {
74+ pathname : location . pathname ,
75+ search : searchParams . toString ( ) ,
76+ } ) ;
77+ dismissPanel ( ) ;
78+ } ;
79+
80+ // Check if this card should be opened based on URL parameter
81+ useEffect ( ( ) => {
82+ const searchParams = new URLSearchParams ( location . search ) ;
83+ const cardParam = searchParams . get ( 'card' ) ;
84+ if ( cardParam === cardSlug && ! isOpen ) {
85+ openPanel ( ) ;
86+ }
87+ } , [ location . search , cardSlug , isOpen , openPanel ] ) ;
88+
4889 const fetchGitHubData = async ( owner : string , repo : string ) => {
4990 const token = siteConfig . customFields . REACT_APP_GITHUB_TOKEN ;
5091 try {
@@ -98,14 +139,14 @@ function ShowcaseCard({
98139 key = { title }
99140 className = { styleCSS . card }
100141 appearance = "filled"
101- onClick = { openPanel }
142+ onClick = { handleCardClick }
102143 >
103144 < div >
104145 < ThemeProvider theme = { colorMode !== "dark" ? lightTheme : darkTheme } >
105146 < Panel
106147 isLightDismiss
107148 isOpen = { isOpen }
108- onDismiss = { dismissPanel }
149+ onDismiss = { handleDismissPanel }
109150 closeButtonAriaLabel = "Close"
110151 type = { PanelType . medium }
111152 >
0 commit comments