-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(anni): persistent state with contexts
- Loading branch information
1 parent
1d5d687
commit 77d4c4a
Showing
10 changed files
with
210 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import Link from 'next/link'; | ||
import { useRouter } from 'next/router'; | ||
import { createElement, PropsWithChildren } from 'react'; | ||
|
||
import { BrickFilterContextProvider } from '../contexts/brickFilter'; | ||
import { LanguageContextProvider } from '../contexts/language'; | ||
|
||
export type ContextProvider = ({ children }: PropsWithChildren) => JSX.Element; | ||
|
||
interface TabDefinition { | ||
activePaths: RegExp; | ||
title: string; | ||
linkPath: string; | ||
providers: ContextProvider[]; | ||
} | ||
|
||
export function ResolvedProviders({ | ||
providers, | ||
children, | ||
}: PropsWithChildren<{ providers: ContextProvider[] }>) { | ||
if (providers.length === 0) return <>{children}</>; | ||
return createElement( | ||
providers[0], | ||
null, | ||
<ResolvedProviders providers={providers.slice(1)}> | ||
{children} | ||
</ResolvedProviders>, | ||
); | ||
} | ||
|
||
const tabDefinitions: TabDefinition[] = [ | ||
{ activePaths: /^\/$/, title: 'Home', linkPath: '/', providers: [] }, | ||
{ | ||
activePaths: /^\/annotations.*$/, | ||
title: 'Annotations', | ||
linkPath: '/annotations', | ||
providers: [LanguageContextProvider], | ||
}, | ||
{ | ||
activePaths: /^\/bricks.*$/, | ||
title: 'Bricks', | ||
linkPath: '/bricks', | ||
providers: [LanguageContextProvider, BrickFilterContextProvider], | ||
}, | ||
]; | ||
|
||
const Layout = ({ children }: PropsWithChildren) => { | ||
const router = useRouter(); | ||
const activeIndex = tabDefinitions.findIndex((definition) => | ||
router.pathname.match(definition.activePaths), | ||
); | ||
return ( | ||
<> | ||
<div className="h-screen fixed px-8 py-16"> | ||
<ul className="space-y-2"> | ||
{tabDefinitions.map((tabDefinition, index) => ( | ||
<li | ||
key={index} | ||
className={`font-medium ${ | ||
index === activeIndex && 'underline' | ||
}`} | ||
> | ||
<Link href={tabDefinition.linkPath}> | ||
<a>{tabDefinition.title}</a> | ||
</Link> | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
<div className="max-w-screen-md mx-auto pt-4"> | ||
{activeIndex === -1 ? ( | ||
children | ||
) : ( | ||
<ResolvedProviders | ||
providers={tabDefinitions[activeIndex].providers} | ||
> | ||
{children} | ||
</ResolvedProviders> | ||
)} | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default Layout; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { | ||
createContext, | ||
Dispatch, | ||
SetStateAction, | ||
useContext, | ||
useState, | ||
} from 'react'; | ||
|
||
import { brickUsages } from '../common/constants'; | ||
import { ContextProvider } from '../components/Layout'; | ||
|
||
export const displayCategories = ['All', ...brickUsages] as const; | ||
export type DisplayCategory = typeof displayCategories[number]; | ||
export const displayCategoryForIndex = (index: number): DisplayCategory => | ||
displayCategories[index]; | ||
export const indexForDisplayCategory = (category: DisplayCategory): number => | ||
displayCategories.indexOf(category); | ||
|
||
interface IBrickFilterContext { | ||
categoryIndex: number; | ||
setCategoryIndex: Dispatch<SetStateAction<number>>; | ||
} | ||
|
||
const BrickFilterContext = createContext<IBrickFilterContext | undefined>( | ||
undefined, | ||
); | ||
|
||
export const BrickFilterContextProvider: ContextProvider = ({ children }) => { | ||
const [categoryIndex, setCategoryIndex] = useState(0); | ||
return ( | ||
<BrickFilterContext.Provider | ||
value={{ categoryIndex, setCategoryIndex }} | ||
> | ||
{children} | ||
</BrickFilterContext.Provider> | ||
); | ||
}; | ||
|
||
export const useBrickFilterContext = (): IBrickFilterContext => { | ||
const context = useContext(BrickFilterContext); | ||
if (!context) throw Error('Missing provider for language context'); | ||
return context; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { | ||
createContext, | ||
Dispatch, | ||
SetStateAction, | ||
useContext, | ||
useState, | ||
} from 'react'; | ||
|
||
import { SupportedLanguage } from '../common/constants'; | ||
import { ContextProvider } from '../components/Layout'; | ||
|
||
interface ILanguageContext { | ||
language: SupportedLanguage; | ||
setLanguage: Dispatch<SetStateAction<SupportedLanguage>>; | ||
} | ||
|
||
const LanguageContext = createContext<ILanguageContext | undefined>(undefined); | ||
|
||
export const LanguageContextProvider: ContextProvider = ({ children }) => { | ||
const [language, setLanguage] = useState<SupportedLanguage>('English'); | ||
return ( | ||
<LanguageContext.Provider value={{ language, setLanguage }}> | ||
{children} | ||
</LanguageContext.Provider> | ||
); | ||
}; | ||
|
||
export const useLanguageContext = (): ILanguageContext => { | ||
const context = useContext(LanguageContext); | ||
if (!context) throw Error('Missing provider for language context'); | ||
return context; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.