Skip to content

Commit 9c6d766

Browse files
authored
Merge pull request #2 from raymondyangdev/main
1: Sync language selection across tabs and persist state using localStorage
2 parents e0b7c9f + d19bff4 commit 9c6d766

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

src/components/App/index.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
import '@styles/styles.sass'
22

33
import React from 'react'
4+
import { LanguageProvider } from '@components/Language/context'
45
import { SidebarProvider } from '@components/Sidebar/context'
56

67
import Background from '@components/Background'
78
import Appbar from '@/components/Appbar'
89
import Content from '@components/Content'
910

10-
1111
export default function App() {
1212
return (
1313
<React.StrictMode>
1414
<SidebarProvider>
15-
<div className="App">
16-
<Background />
17-
<Appbar />
18-
<Content />
19-
</div>
15+
<LanguageProvider>
16+
<div className="App">
17+
<Background />
18+
<Appbar />
19+
<Content />
20+
</div>
21+
</LanguageProvider>
2022
</SidebarProvider>
2123
</React.StrictMode>
2224
)

src/components/Code/code.module.sass

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
background-color: var(--code-line-hover-color)
1111

1212
.line
13-
display: inline
13+
display: block
1414
border-left: 0.5px solid var(--code-line-number-color)
1515
padding-left: 1em
1616

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
createContext,
3+
useContext,
4+
useState,
5+
ReactNode,
6+
useEffect,
7+
} from 'react'
8+
9+
type Language = 'python' | 'javascript' | 'java' | 'cpp'
10+
11+
interface LanguageContextType {
12+
selectedLanguage: Language
13+
setSelectedLanguage: (language: Language) => void
14+
}
15+
16+
const LanguageContext = createContext<LanguageContextType | undefined>(
17+
undefined
18+
)
19+
20+
interface LanguageProviderProps {
21+
children: ReactNode
22+
}
23+
24+
export const LanguageProvider = ({ children }: LanguageProviderProps) => {
25+
// Get the language from localStorage or default to 'python'
26+
const initialLanguage: Language =
27+
(localStorage.getItem('selectedLanguage') as Language) || 'python'
28+
29+
const [selectedLanguage, setSelectedLanguage] =
30+
useState<Language>(initialLanguage)
31+
32+
useEffect(() => {
33+
localStorage.setItem('selectedLanguage', selectedLanguage)
34+
}, [selectedLanguage])
35+
36+
return (
37+
<LanguageContext.Provider
38+
value={{ selectedLanguage, setSelectedLanguage }}
39+
>
40+
{children}
41+
</LanguageContext.Provider>
42+
)
43+
}
44+
45+
export function useLanguage() {
46+
const context = useContext(LanguageContext)
47+
48+
if (context === undefined) {
49+
throw new Error('useLanguage must be used within a LanguageProvider')
50+
}
51+
52+
return context as LanguageContextType
53+
}

src/components/Tabs/index.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import styles from './tabs.module.sass'
22

3-
import { Children, ReactElement, ReactNode, useState } from 'react'
3+
import { Children, ReactElement, ReactNode } from 'react'
44

55
import Code from '@components/Code'
66
import CopyButton from '@components/CopyButton'
@@ -9,7 +9,7 @@ import SvgPython from '@icons/Python'
99
import SvgJavascript from '@/icons/Javascript'
1010
import SvgCpp from '@icons/Cpp'
1111
import SvgJava from '@/icons/Java'
12-
12+
import { useLanguage } from '@components/Language/context'
1313

1414
interface TabsProps {
1515
title: string
@@ -21,22 +21,25 @@ interface TabProps {
2121
language: 'python' | 'javascript' | 'java' | 'cpp'
2222
}
2323

24-
2524
const LANGUAGE_ICONS = {
2625
python: SvgPython,
2726
javascript: SvgJavascript,
2827
cpp: SvgCpp,
29-
java: SvgJava
28+
java: SvgJava,
3029
}
3130

32-
3331
export default function Tabs({ title, children }: TabsProps) {
34-
const [activeIndex, setActiveIndex] = useState(0)
32+
const { selectedLanguage, setSelectedLanguage } = useLanguage()
3533
const tabs = Children.toArray(children) as ReactElement<TabProps>[]
34+
const activeIndex = tabs.findIndex(
35+
(tab) => tab.props.language === selectedLanguage
36+
)
3637
const code = tabs[activeIndex].props.code
3738
const language = tabs[activeIndex].props.language
3839

39-
const changeTab = (index: number) => setActiveIndex(index)
40+
const changeTab = (index: number) => {
41+
setSelectedLanguage(tabs[index].props.language)
42+
}
4043
const handleCopy = () => navigator.clipboard.writeText(code)
4144

4245
const renderTabButtons = () => {

0 commit comments

Comments
 (0)