custom theme started using context

This commit is contained in:
Sendou
2020-01-22 18:28:43 +02:00
parent ec0c4a4012
commit 8d8ea5617b
14 changed files with 118 additions and 100 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react"
import React, { useState, useContext } from "react"
import { Build } from "../../types"
import {
Box,
@@ -10,12 +10,12 @@ import {
PopoverContent,
PopoverBody,
} from "@chakra-ui/core"
import useTheme from "../../hooks/useTheme"
import WeaponImage from "../common/WeaponImage"
import { top500 } from "../../assets/imageImports"
import { FaInfo, FaPlus, FaMinus } from "react-icons/fa"
import ViewGear from "./ViewGear"
import ViewAP from "./ViewAP"
import MyThemeContext from "../../themeContext"
interface BuildCardProps {
build: Build
@@ -24,7 +24,9 @@ interface BuildCardProps {
const BuildCard: React.FC<BuildCardProps> = ({ build, defaultToAPView }) => {
const [apView, setApView] = useState(defaultToAPView)
const { borderStyle, themeColor, darkerBgColor, grayWithShade } = useTheme()
const { borderStyle, themeColor, darkerBgColor, grayWithShade } = useContext(
MyThemeContext
)
return (
<Box

View File

@@ -1,11 +1,11 @@
// This while is bit of a mess from TS PoV - might be worth while to do it better later
import React from "react"
import React, { useContext } from "react"
import { Build, Ability } from "../../types"
import { Box, Flex } from "@chakra-ui/core"
import DividingBox from "../ui/DividingBox"
import AbilityIcon from "./AbilityIcon"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
const mainOnlyAbilities = [
"CB",
@@ -27,7 +27,7 @@ interface ViewAPProps {
}
const ViewAP: React.FC<ViewAPProps> = ({ build }) => {
const { grayWithShade } = useTheme()
const { grayWithShade } = useContext(MyThemeContext)
const abilityArrays: Ability[][] = [
build.headgear,
build.clothing,

View File

@@ -1,11 +1,11 @@
import React from "react"
import React, { useContext } from "react"
import { Spinner, Box } from "@chakra-ui/core"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
interface LoadingProps {}
const Loading: React.FC<LoadingProps> = () => {
const { themeColorWithShade } = useTheme()
const { themeColorWithShade } = useContext(MyThemeContext)
return (
<Box textAlign="center">
<Spinner

View File

@@ -1,28 +1,66 @@
import React from "react"
import { Box } from "@chakra-ui/core"
import { Box, useColorMode, useTheme as useChakraTheme } from "@chakra-ui/core"
import { MenuBar } from "./MenuBar"
import SideNav from "./SideNav"
import Routes from "./Routes"
import useTheme from "../../hooks/useTheme"
import useLocalStorage from "@rehooks/local-storage"
import { ThemeColor } from "../../types"
import { MyThemeProvider } from "../../themeContext"
import { Theme } from "../../types"
const App: React.FC = () => {
const { bgColor, textColor } = useTheme()
const chakraTheme = useChakraTheme()
const { colorMode } = useColorMode()
const [themeColorFromStorage] = useLocalStorage<ThemeColor>("colorPreference")
const themeColor = themeColorFromStorage
? themeColorFromStorage
: colorMode === "light"
? "pink"
: "orange"
const theme = {
light: {
colorMode: "light",
bgColor: "#eff0f3",
darkerBgColor: "#D6D7DA",
textColor: "#0d0d0d",
borderStyle: "1px solid rgba(0, 0, 0, .2)",
themeColorWithShade: `${themeColor}.500`,
grayWithShade: "gray.600",
themeColorHex: chakraTheme.colors[themeColor]["500"],
themeColor,
} as Theme,
dark: {
colorMode: "dark",
bgColor: "#232946",
darkerBgColor: "#0A102D",
textColor: "#fffffe",
borderStyle: "1px solid rgba(255, 255, 255, .2)",
themeColorWithShade: `${themeColor}.200`,
grayWithShade: "gray.300",
themeColorHex: chakraTheme.colors[themeColor]["500"],
themeColor,
} as Theme,
}
return (
<Box
marginLeft={[null, null, "250px"]}
mt={["4em", null, "0"]}
color={textColor}
bg={bgColor}
minH="100vh"
>
<SideNav />
<MenuBar />
<Box maxWidth="46em" pt={8} px={8} ml="auto" mr="auto">
<Routes />
<MyThemeProvider value={theme[colorMode]}>
<Box
marginLeft={[null, null, "250px"]}
mt={["4em", null, "0"]}
color={theme[colorMode].textColor}
bg={theme[colorMode].bgColor}
minH="100vh"
>
<SideNav />
<MenuBar />
<Box maxWidth="46em" pt={8} px={8} ml="auto" mr="auto">
<Routes />
</Box>
</Box>
</Box>
</MyThemeProvider>
)
}

View File

@@ -1,4 +1,4 @@
import React from "react"
import React, { useContext } from "react"
import {
Box,
PopoverTrigger,
@@ -10,12 +10,12 @@ import {
import { CirclePicker, ColorResult } from "react-color"
import { writeStorage } from "@rehooks/local-storage"
import { themeColors as choices } from "../../utils/lists"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
const size = "20px" as const
const ColorPicker: React.FC = () => {
const { themeColorHex, bgColor } = useTheme()
const { themeColorHex, bgColor } = useContext(MyThemeContext)
const theme = useChakraTheme()
const hexCodes = choices.map(color =>

View File

@@ -1,8 +1,8 @@
import React from "react"
import React, { useContext } from "react"
import { PseudoBox, ListIcon, ListItem } from "@chakra-ui/core"
import { Link } from "@reach/router"
import { IconType } from "react-icons/lib/cjs"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
/*const hoverColor = { light: "gray.900", dark: "whiteAlpha.900" }
const activeColor = { light: "orange.800", dark: "pink.100" }
@@ -15,7 +15,7 @@ interface NavItemProps {
}
const NavItem: React.FC<NavItemProps> = ({ to, Icon, title }) => {
const { themeColorWithShade } = useTheme()
const { themeColorWithShade } = useContext(MyThemeContext)
return (
<ListItem>

View File

@@ -1,7 +1,7 @@
import { Box } from "@chakra-ui/core"
import React from "react"
import React, { useContext } from "react"
import { SideNavContent } from "./SideNavContent"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
const shadow = {
light: "0px 1px 10px 8px rgba(0,0,0,0.15)",
@@ -9,7 +9,7 @@ const shadow = {
} as const
const SideNav = () => {
const { darkerBgColor, colorMode } = useTheme()
const { darkerBgColor, colorMode } = useContext(MyThemeContext)
return (
<Box
bg={darkerBgColor}

View File

@@ -1,6 +1,6 @@
import React from "react"
import React, { useContext } from "react"
import { Button as ChakraButton, useColorMode } from "@chakra-ui/core"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
interface ButtonProps {
children: string | string[]
@@ -8,7 +8,7 @@ interface ButtonProps {
}
export const Button: React.FC<ButtonProps> = ({ children, onClick }) => {
const { themeColor } = useTheme()
const { themeColor } = useContext(MyThemeContext)
return (
<ChakraButton variantColor={themeColor} onClick={onClick}>
{children}

View File

@@ -1,6 +1,6 @@
import React from "react"
import React, { useContext } from "react"
import { Box } from "@chakra-ui/core"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
interface DividingBoxProps {
children: JSX.Element | JSX.Element[] | string
@@ -15,7 +15,7 @@ const DividingBox: React.FC<DividingBoxProps> = ({
width = undefined,
margin = "0.4em",
}) => {
const { borderStyle } = useTheme()
const { borderStyle } = useContext(MyThemeContext)
return (
<Box
borderLeft={location === "left" ? borderStyle : undefined}

View File

@@ -1,4 +1,4 @@
import React from "react"
import React, { useContext } from "react"
import { RouteComponentProps, Redirect } from "@reach/router"
import { useQuery } from "@apollo/react-hooks"
@@ -18,10 +18,10 @@ import { IconType } from "react-icons/lib/cjs"
import AvatarWithInfo from "./AvatarWithInfo"
import WeaponPool from "./WeaponPool"
import { Box, Tabs, TabList, Tab, TabPanels, TabPanel } from "@chakra-ui/core"
import useTheme from "../../hooks/useTheme"
import { Helmet } from "react-helmet-async"
import { SEARCH_FOR_BUILDS } from "../../graphql/queries/searchForBuilds"
import BuildTab from "./BuildTab"
import MyThemeContext from "../../themeContext"
interface Tab {
id: number
@@ -53,7 +53,9 @@ const UserPage: React.FC<RouteComponentProps & UserPageProps> = ({ id }) => {
skip: !data || !data.searchForUser,
})
const { textColor, themeColor, themeColorWithShade } = useTheme()
const { textColor, themeColor, themeColorWithShade } = useContext(
MyThemeContext
)
if (loading || userLoading || buildsLoading) return <Loading />
if (error) return <Error errorMessage={error.message} />

View File

@@ -1,8 +1,8 @@
import React from "react"
import React, { useContext } from "react"
import { Weapon } from "../../types"
import { Box, Flex } from "@chakra-ui/core"
import WeaponImage from "../common/WeaponImage"
import useTheme from "../../hooks/useTheme"
import MyThemeContext from "../../themeContext"
interface WeaponPoolProps {
weapons: Weapon[]
@@ -14,7 +14,7 @@ const styles = {
} as const
const WeaponPool: React.FC<WeaponPoolProps> = ({ weapons }) => {
const { colorMode, grayWithShade } = useTheme()
const { colorMode, grayWithShade } = useContext(MyThemeContext)
const borderStyle: string = styles[colorMode]
return (

View File

@@ -1,55 +0,0 @@
import { useColorMode, useTheme as useChakraTheme } from "@chakra-ui/core"
import { useLocalStorage } from "@rehooks/local-storage"
import { ThemeColor } from "../types"
interface Theme {
colorMode: "light" | "dark"
bgColor: "#eff0f3" | "#232946"
darkerBgColor: "#D6D7DA" | "#0A102D"
textColor: "#0d0d0d" | "#fffffe"
borderStyle:
| "1px solid rgba(0, 0, 0, .2)"
| "1px solid rgba(255, 255, 255, .2)"
grayWithShade: "gray.300" | "gray.600"
themeColorWithShade: string
themeColorHex: string
themeColor: ThemeColor
}
function useTheme(): Theme {
const { colorMode } = useColorMode()
const chakraTheme = useChakraTheme()
const light = colorMode === "light"
const bgColor = light ? "#eff0f3" : "#232946"
const darkerBgColor = light ? "#D6D7DA" : "#0A102D"
const textColor = light ? "#0d0d0d" : "#fffffe"
const grayWithShade = light ? "gray.600" : "gray.300"
const borderStyle = light
? "1px solid rgba(0, 0, 0, .2)"
: "1px solid rgba(255, 255, 255, .2)"
const [themeColorFromStorage] = useLocalStorage<ThemeColor>("colorPreference")
const themeColor = themeColorFromStorage
? themeColorFromStorage
: light
? "pink"
: "orange"
const themeColorWithShade = light ? `${themeColor}.500` : `${themeColor}.200`
const themeColorHex = chakraTheme.colors[themeColor]["500"]
return {
colorMode,
bgColor,
darkerBgColor,
textColor,
borderStyle,
themeColorWithShade,
grayWithShade,
themeColorHex,
themeColor,
}
}
export default useTheme

View File

@@ -0,0 +1,17 @@
import React from "react"
import { Theme } from "./types"
const MyThemeContext = React.createContext<Theme>({
colorMode: "dark",
bgColor: "#232946",
darkerBgColor: "#0A102D",
textColor: "#fffffe",
borderStyle: "1px solid rgba(255, 255, 255, .2)",
themeColorWithShade: "pink.200",
grayWithShade: "gray.300",
themeColorHex: "#D53F8C",
themeColor: "pink",
})
export const MyThemeProvider = MyThemeContext.Provider
export default MyThemeContext

View File

@@ -36,6 +36,20 @@ export type HeadGear = ElementType<typeof headGearEnglish>
export type ClothingGear = ElementType<typeof clothingGearEnglish>
export type ShoesGear = ElementType<typeof shoesGearEnglish>
export interface Theme {
colorMode: "dark" | "light"
bgColor: "#eff0f3" | "#232946"
darkerBgColor: "#0A102D" | "#D6D7DA"
textColor: "#fffffe" | "#0d0d0d"
borderStyle:
| "1px solid rgba(0, 0, 0, .2)"
| "1px solid rgba(255, 255, 255, .2)"
grayWithShade: "gray.300" | "gray.600"
themeColorWithShade: string
themeColorHex: string
themeColor: ThemeColor
}
export interface UserLean {
id: string
username: string