Skip to content

Commit

Permalink
feat(contexts, hooks): Implement context and hook for app state
Browse files Browse the repository at this point in the history
  • Loading branch information
ruedap committed May 31, 2020
1 parent 0622910 commit 9b1e5bd
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 21 deletions.
2 changes: 1 addition & 1 deletion components/templates/styleguide/_styled_tag4.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import styled from 'styled-components'

export const StyledTag4 = styled.div`border: 4px solid black;`
export const StyledTag4 = styled.div`border: 4px solid ${({ theme }) => theme.colors.primary};`
10 changes: 10 additions & 0 deletions components/templates/styleguide/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Index2 } from './index2'
import { FooBar, FooBarTag4 } from './_foo_bar'
import styled, { css, keyframes, Keyframes } from 'styled-components'
import { StyledTag4 } from './_styled_tag4'
import { useSetAppState, useAppState } from '@/hooks/app_state'

const hover = css`
&:hover {
Expand All @@ -17,6 +18,8 @@ const prop = css`
`

const Styleguide = () => {
const setAppState = useSetAppState()
console.log(useAppState())
return (
<>
<Index2 />
Expand All @@ -31,6 +34,12 @@ const Styleguide = () => {
<StyledTag3 animation={ bounce }>Let&apos;s bounce.</StyledTag3>
<StyledTag3 animation={ shake }>Let&apos;s shake.</StyledTag3>
<StyledTag4>This is Styled.Tag4</StyledTag4>
<button onClick={ () => setAppState({ themeName: 'dark' }) }>
dark mode
</button>
<button onClick={ () => setAppState({ themeName: 'light' }) }>
light mode
</button>
</>
)
}
Expand Down Expand Up @@ -90,4 +99,5 @@ const StyledTag3 = styled.div<{ animation: Keyframes }>`
background-color: linen;
}
animation: ${({ animation }) => animation} 0.2s infinite ease-in-out alternate;
content: "${({ theme }) => theme.colors.primary}";
`
41 changes: 41 additions & 0 deletions contexts/app_state.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { createContext, Dispatch, SetStateAction, useState } from 'react'
import { ThemeProvider } from 'styled-components'
import { lightTheme, darkTheme } from '@/styles/app_theme'

interface AppState {
// TODO: Add null
themeName: 'light' | 'dark'
}

const initialAppState: AppState = {
themeName: 'light'
}

export const AppStateContext = createContext<AppState>(initialAppState)
export const SetAppStateContext = createContext<
Dispatch<SetStateAction<AppState>>
>(() => {})

export const AppStateProvider = (props: {
initialAppState?: AppState
children: React.ReactNode
}) => {
const [appState, setAppState] = useState<AppState>(
props.initialAppState ?? initialAppState
)
return (
<AppStateContext.Provider value={ appState }>
<SetAppStateContext.Provider value={ setAppState }>
<AppStateContext.Consumer>
{ value => (
<ThemeProvider theme={ value.themeName === 'light'
? lightTheme : darkTheme
}>
{ props.children }
</ThemeProvider>
) }
</AppStateContext.Consumer>
</SetAppStateContext.Provider>
</AppStateContext.Provider>
)
}
10 changes: 10 additions & 0 deletions hooks/app_state.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { useContext } from 'react'
import { AppStateContext, SetAppStateContext } from '@/contexts/app_state'

export const useAppState = () => {
return useContext(AppStateContext)
}

export const useSetAppState = () => {
return useContext(SetAppStateContext)
}
15 changes: 6 additions & 9 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { AppProps } from 'next/app'
import Router from 'next/router'
import { ThemeProvider, DefaultTheme } from 'styled-components'
import * as gtag from '@/utils/gtag'
import Styles from '@/styles'
import { AppStateProvider } from '@/contexts/app_state'
import { useAppState } from '@/hooks/app_state'
import '@/styles/normalize.scss'
import '@/styles/highlightjs.scss'
import '@/styles/fonts.scss'

Router.events.on('routeChangeComplete', url => gtag.pageview(url))

const theme: DefaultTheme = {
colors: {
primary: 'skyblue'
}
}

export default function App ({ Component, pageProps }: AppProps) {
const appState = useAppState()

return (
<ThemeProvider theme={ theme }>
<AppStateProvider initialAppState={ appState }>
<Styles.CustomProperties />
<Styles.Elements />
<Component { ...pageProps } />
</ThemeProvider>
</AppStateProvider>
)
}
46 changes: 46 additions & 0 deletions styles/app_theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
export interface AppTheme {
colors: {
primary: string
}
sizes: {
font: {
XS: number
SM: number
MD: number
LG: number
XL: number
}
width: {
CONTENT: number
}
}
}

export const lightTheme: AppTheme = {
colors: {
primary: 'skyblue'
},
sizes: {
font: {
XS: 12,
SM: 14,
MD: 16,
LG: 18,
XL: 20
},
width: {
CONTENT: 1000
}
}
} as const

export const darkTheme: AppTheme = {
...lightTheme,
colors: {
primary: 'pink'
}
} as const

declare module 'styled-components' {
interface DefaultTheme extends AppTheme {}
}
11 changes: 0 additions & 11 deletions types/styled.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,2 @@
import 'styled-components'
import { fiboMap } from '@/styles/abstractions/funcs'

declare module 'styled-components' {
export interface DefaultTheme {
colors: {
primary: string
}
}
}

export type TFiboSizeName = 'xl6'|'xl5'|'xl4'|'xl3'|'xl2'|'xl'|'lg'|'md'|'sm'|'xs'|'xs2'|'xs3'|'xs4'|'xs5'|'xs6'
export type TFiboUnit = 'px'|'rem'|'alpha'

0 comments on commit 9b1e5bd

Please sign in to comment.