dark mode first draft!
Hey wow this was not so hard, just set some global styles, removed some hardcoded colors, and walked through the remaining hardcoded colors to pick a dark mode variant :) neat!!
This commit is contained in:
parent
12bd9f6b17
commit
086cf8b335
15 changed files with 139 additions and 51 deletions
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import { ApolloProvider } from "@apollo/client";
|
||||
import { CSSReset, ChakraProvider } from "@chakra-ui/core";
|
||||
import theme from "@chakra-ui/theme";
|
||||
import defaultTheme from "@chakra-ui/theme";
|
||||
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
|
||||
import loadable from "@loadable/component";
|
||||
|
||||
|
@ -10,6 +10,19 @@ import apolloClient from "./apolloClient";
|
|||
const WardrobePage = loadable(() => import("./WardrobePage"));
|
||||
const HomePage = loadable(() => import("./HomePage"));
|
||||
|
||||
const theme = {
|
||||
...defaultTheme,
|
||||
styles: {
|
||||
...defaultTheme.styles,
|
||||
global: ({ colorMode, ...rest }) => ({
|
||||
...defaultTheme.styles.global({ colorMode, ...rest }),
|
||||
color: colorMode === "light" ? "green.800" : "green.50",
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
console.log(defaultTheme.styles.global, defaultTheme.styles);
|
||||
|
||||
/**
|
||||
* App is the entry point of our application. There's not a ton of exciting
|
||||
* stuff happening here, mostly just setting up some globals and theming!
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
import React from "react";
|
||||
import { css } from "emotion";
|
||||
import gql from "graphql-tag";
|
||||
import { Box, Button, Flex, Input, useTheme, useToast } from "@chakra-ui/core";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Flex,
|
||||
IconButton,
|
||||
Input,
|
||||
useColorMode,
|
||||
useColorModeValue,
|
||||
useTheme,
|
||||
useToast,
|
||||
} from "@chakra-ui/core";
|
||||
import { MoonIcon, SunIcon } from "@chakra-ui/icons";
|
||||
import { useHistory, useLocation } from "react-router-dom";
|
||||
import { useLazyQuery } from "@apollo/client";
|
||||
|
||||
|
@ -19,13 +30,8 @@ function HomePage() {
|
|||
const [previewState, setPreviewState] = React.useState(null);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
color="green.800"
|
||||
direction="column"
|
||||
p="6"
|
||||
align="center"
|
||||
textAlign="center"
|
||||
>
|
||||
<Flex direction="column" p="6" align="center" textAlign="center">
|
||||
<ColorModeToggleButton />
|
||||
<Box height="8" />
|
||||
<Box
|
||||
width="200px"
|
||||
|
@ -93,6 +99,9 @@ function StartOutfitForm({ onChange }) {
|
|||
history.push(`/outfits/new?${params}`);
|
||||
};
|
||||
|
||||
const buttonBgColor = useColorModeValue("green.600", "green.300");
|
||||
const buttonBgColorHover = useColorModeValue("green.700", "green.200");
|
||||
|
||||
return (
|
||||
<form onSubmit={onSubmit}>
|
||||
<Flex>
|
||||
|
@ -121,8 +130,8 @@ function StartOutfitForm({ onChange }) {
|
|||
type="submit"
|
||||
colorScheme="green"
|
||||
disabled={!isValid}
|
||||
backgroundColor="green.600" // for AA contrast
|
||||
_hover={{ backgroundColor: "green.700" }}
|
||||
backgroundColor={buttonBgColor}
|
||||
_hover={{ backgroundColor: buttonBgColorHover }}
|
||||
>
|
||||
Start
|
||||
</Button>
|
||||
|
@ -192,6 +201,11 @@ function SubmitPetForm() {
|
|||
import("./WardrobePage");
|
||||
};
|
||||
|
||||
const inputBorderColor = useColorModeValue("green.600", "green.500");
|
||||
const inputBorderColorHover = useColorModeValue("green.400", "green.300");
|
||||
const buttonBgColor = useColorModeValue("green.600", "green.300");
|
||||
const buttonBgColorHover = useColorModeValue("green.700", "green.200");
|
||||
|
||||
return (
|
||||
<form onSubmit={onSubmit}>
|
||||
<Flex>
|
||||
|
@ -201,8 +215,8 @@ function SubmitPetForm() {
|
|||
isDisabled={loading}
|
||||
placeholder="Enter a pet's name"
|
||||
aria-label="Enter a pet's name"
|
||||
borderColor="green.600"
|
||||
_hover={{ borderColor: "green.400" }}
|
||||
borderColor={inputBorderColor}
|
||||
_hover={{ borderColor: inputBorderColorHover }}
|
||||
boxShadow="md"
|
||||
width="14em"
|
||||
className={css`
|
||||
|
@ -217,8 +231,8 @@ function SubmitPetForm() {
|
|||
colorScheme="green"
|
||||
isDisabled={!petName}
|
||||
isLoading={loading}
|
||||
backgroundColor="green.600" // for AA contrast
|
||||
_hover={{ backgroundColor: "green.700" }}
|
||||
backgroundColor={buttonBgColor} // for AA contrast
|
||||
_hover={{ backgroundColor: buttonBgColorHover }}
|
||||
>
|
||||
Start
|
||||
</Button>
|
||||
|
@ -227,6 +241,21 @@ function SubmitPetForm() {
|
|||
);
|
||||
}
|
||||
|
||||
function ColorModeToggleButton() {
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
icon={colorMode === "light" ? <MoonIcon /> : <SunIcon />}
|
||||
onClick={toggleColorMode}
|
||||
variant="ghost"
|
||||
position="absolute"
|
||||
bottom="3"
|
||||
right="3"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* useSupportSetup helps our support staff get set up with special access.
|
||||
* If you provide ?supportSecret=... in the URL, we'll save it in a cookie and
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
Image,
|
||||
Skeleton,
|
||||
Tooltip,
|
||||
useColorModeValue,
|
||||
useTheme,
|
||||
} from "@chakra-ui/core";
|
||||
import { EditIcon, DeleteIcon, InfoIcon } from "@chakra-ui/icons";
|
||||
|
@ -120,6 +121,21 @@ function ItemSkeleton() {
|
|||
function ItemContainer({ children }) {
|
||||
const theme = useTheme();
|
||||
|
||||
const focusBackgroundColor = useColorModeValue(
|
||||
theme.colors.gray["100"],
|
||||
theme.colors.gray["700"]
|
||||
);
|
||||
|
||||
const activeBorderColor = useColorModeValue(
|
||||
theme.colors.green["400"],
|
||||
theme.colors.green["500"]
|
||||
);
|
||||
|
||||
const focusCheckedBorderColor = useColorModeValue(
|
||||
theme.colors.green["800"],
|
||||
theme.colors.green["300"]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
p="1"
|
||||
|
@ -135,15 +151,15 @@ function ItemContainer({ children }) {
|
|||
css`
|
||||
&:hover,
|
||||
input:focus + & {
|
||||
background-color: ${theme.colors.gray["100"]};
|
||||
background-color: ${focusBackgroundColor};
|
||||
}
|
||||
|
||||
input:active + & {
|
||||
border-color: ${theme.colors.green["400"]};
|
||||
border-color: ${activeBorderColor};
|
||||
}
|
||||
|
||||
input:checked:focus + & {
|
||||
border-color: ${theme.colors.green["800"]};
|
||||
border-color: ${focusCheckedBorderColor};
|
||||
}
|
||||
`,
|
||||
])}
|
||||
|
@ -159,6 +175,17 @@ function ItemContainer({ children }) {
|
|||
*/
|
||||
function ItemThumbnail({ src, isWorn }) {
|
||||
const theme = useTheme();
|
||||
|
||||
const borderColor = useColorModeValue(
|
||||
theme.colors.green["700"],
|
||||
"transparent"
|
||||
);
|
||||
|
||||
const focusBorderColor = useColorModeValue(
|
||||
theme.colors.green["600"],
|
||||
"transparent"
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
borderRadius="lg"
|
||||
|
@ -171,14 +198,14 @@ function ItemThumbnail({ src, isWorn }) {
|
|||
transformOrigin="center"
|
||||
className={css([
|
||||
{
|
||||
borderColor: theme.colors.green["700"],
|
||||
borderColor: `${borderColor} !important`,
|
||||
transform: "scale(0.8)",
|
||||
},
|
||||
!isWorn && {
|
||||
[containerHasFocus]: {
|
||||
opacity: "0.9",
|
||||
transform: "scale(0.9)",
|
||||
borderColor: theme.colors.green["600"],
|
||||
borderColor: `${focusBorderColor} !important`,
|
||||
},
|
||||
},
|
||||
isWorn && {
|
||||
|
@ -202,7 +229,6 @@ function ItemName({ children, ...props }) {
|
|||
return (
|
||||
<Box
|
||||
fontSize="md"
|
||||
color="green.800"
|
||||
transition="all 0.15s"
|
||||
className={css`
|
||||
${containerHasFocus} {
|
||||
|
@ -228,6 +254,15 @@ function ItemName({ children, ...props }) {
|
|||
function ItemActionButton({ icon, label, href, onClick }) {
|
||||
const theme = useTheme();
|
||||
|
||||
const focusBackgroundColor = useColorModeValue(
|
||||
theme.colors.gray["300"],
|
||||
theme.colors.gray["800"]
|
||||
);
|
||||
const focusColor = useColorModeValue(
|
||||
theme.colors.gray["700"],
|
||||
theme.colors.gray["200"]
|
||||
);
|
||||
|
||||
return (
|
||||
<Tooltip label={label} placement="top">
|
||||
<IconButton
|
||||
|
@ -250,8 +285,8 @@ function ItemActionButton({ icon, label, href, onClick }) {
|
|||
&:focus,
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
background-color: ${theme.colors.gray["300"]};
|
||||
color: ${theme.colors.gray["700"]};
|
||||
background-color: ${focusBackgroundColor};
|
||||
color: ${focusColor};
|
||||
}
|
||||
|
||||
/* On touch devices, always show the buttons! This avoids having to
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
InputGroup,
|
||||
InputLeftElement,
|
||||
InputRightElement,
|
||||
useColorModeValue,
|
||||
} from "@chakra-ui/core";
|
||||
import { CloseIcon, SearchIcon } from "@chakra-ui/icons";
|
||||
|
||||
|
@ -103,6 +104,8 @@ function SearchToolbar({
|
|||
}
|
||||
};
|
||||
|
||||
const focusBorderColor = useColorModeValue("green.600", "green.400");
|
||||
|
||||
return (
|
||||
<InputGroup>
|
||||
<InputLeftElement>
|
||||
|
@ -111,8 +114,7 @@ function SearchToolbar({
|
|||
<Input
|
||||
placeholder="Search for items to add…"
|
||||
aria-label="Search for items to add…"
|
||||
focusBorderColor="green.600"
|
||||
color="green.800"
|
||||
focusBorderColor={focusBorderColor}
|
||||
value={query}
|
||||
ref={searchQueryRef}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
|
|
|
@ -33,7 +33,7 @@ function ItemsPanel({ outfitState, loading, dispatchToOutfit }) {
|
|||
const { zonesAndItems } = outfitState;
|
||||
|
||||
return (
|
||||
<Box color="green.800">
|
||||
<Box>
|
||||
<Box px="1">
|
||||
<OutfitHeading
|
||||
outfitState={outfitState}
|
||||
|
@ -202,7 +202,6 @@ function OutfitHeading({ outfitState, dispatchToOutfit }) {
|
|||
<IconButton
|
||||
icon={<EditIcon />}
|
||||
variant="link"
|
||||
color="green.600"
|
||||
aria-label="Edit outfit name"
|
||||
title="Edit outfit name"
|
||||
/>
|
||||
|
|
|
@ -2,6 +2,7 @@ import React from "react";
|
|||
import { css, cx } from "emotion";
|
||||
import {
|
||||
Box,
|
||||
DarkMode,
|
||||
Flex,
|
||||
IconButton,
|
||||
Stack,
|
||||
|
@ -155,13 +156,14 @@ function OutfitControls({ outfitState, dispatchToOutfit }) {
|
|||
*/}
|
||||
<Box flex="1 1 0" />
|
||||
<Box flex="0 0 auto">
|
||||
<SpeciesColorPicker
|
||||
speciesId={outfitState.speciesId}
|
||||
colorId={outfitState.colorId}
|
||||
idealPose={outfitState.pose}
|
||||
dark
|
||||
onChange={onSpeciesColorChange}
|
||||
/>
|
||||
<DarkMode>
|
||||
<SpeciesColorPicker
|
||||
speciesId={outfitState.speciesId}
|
||||
colorId={outfitState.colorId}
|
||||
idealPose={outfitState.pose}
|
||||
onChange={onSpeciesColorChange}
|
||||
/>
|
||||
</DarkMode>
|
||||
</Box>
|
||||
<Flex flex="1 1 0" align="center" pl="4">
|
||||
<PosePicker
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
PopoverTrigger,
|
||||
Portal,
|
||||
VisuallyHidden,
|
||||
useColorModeValue,
|
||||
useTheme,
|
||||
} from "@chakra-ui/core";
|
||||
|
||||
|
@ -258,6 +259,11 @@ function PoseOption({ poseInfo, onChange, inputRef }) {
|
|||
label += ` (not modeled yet)`;
|
||||
}
|
||||
|
||||
const borderColor = useColorModeValue(
|
||||
theme.colors.green["600"],
|
||||
theme.colors.green["300"]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
as="label"
|
||||
|
@ -316,7 +322,7 @@ function PoseOption({ poseInfo, onChange, inputRef }) {
|
|||
zIndex="2"
|
||||
className={cx(
|
||||
css`
|
||||
border: 0px solid ${theme.colors.green["600"]};
|
||||
border: 0px solid ${borderColor};
|
||||
transition: border-width 0.2s;
|
||||
|
||||
&.not-available {
|
||||
|
|
|
@ -39,7 +39,6 @@ function SearchPanel({
|
|||
|
||||
return (
|
||||
<Box
|
||||
color="green.800"
|
||||
onKeyDown={(e) => {
|
||||
// This will catch any Escape presses when the user's focus is inside
|
||||
// the SearchPanel.
|
||||
|
@ -125,7 +124,7 @@ function SearchResults({
|
|||
);
|
||||
} else if (error) {
|
||||
return (
|
||||
<Text color="green.500">
|
||||
<Text>
|
||||
We hit an error trying to load your search results{" "}
|
||||
<span role="img" aria-label="(sweat emoji)">
|
||||
😓
|
||||
|
@ -135,7 +134,7 @@ function SearchResults({
|
|||
);
|
||||
} else if (items.length === 0) {
|
||||
return (
|
||||
<Text color="green.500">
|
||||
<Text>
|
||||
We couldn't find any matching items{" "}
|
||||
<span role="img" aria-label="(thinking emoji)">
|
||||
🤔
|
||||
|
|
|
@ -122,7 +122,7 @@ function ItemLayerSupportModal({
|
|||
return (
|
||||
<Modal size="xl" isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay>
|
||||
<ModalContent color="green.800">
|
||||
<ModalContent>
|
||||
<ModalHeader>
|
||||
Layer {itemLayer.id}: {item.name}
|
||||
</ModalHeader>
|
||||
|
|
|
@ -144,7 +144,7 @@ function ItemLayerSupportUploadModal({ item, itemLayer, isOpen, onClose }) {
|
|||
onClose={onClose}
|
||||
>
|
||||
<ModalOverlay>
|
||||
<ModalContent color="green.800">
|
||||
<ModalContent>
|
||||
<ModalHeader textAlign="center">
|
||||
Upload PNG for {item.name}
|
||||
</ModalHeader>
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
Spinner,
|
||||
Stack,
|
||||
useBreakpointValue,
|
||||
useColorModeValue,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/core";
|
||||
import { CheckCircleIcon, EditIcon, ExternalLinkIcon } from "@chakra-ui/icons";
|
||||
|
@ -66,13 +67,13 @@ function ItemSupportDrawer({ item, isOpen, onClose }) {
|
|||
overflow="auto"
|
||||
>
|
||||
<DrawerCloseButton />
|
||||
<DrawerHeader color="green.800">
|
||||
<DrawerHeader>
|
||||
{item.name}
|
||||
<Badge colorScheme="pink" marginLeft="3">
|
||||
Support <span aria-hidden="true">💖</span>
|
||||
</Badge>
|
||||
</DrawerHeader>
|
||||
<DrawerBody color="green.800">
|
||||
<DrawerBody>
|
||||
<Box paddingBottom="5">
|
||||
<Stack spacing="8">
|
||||
<ItemSupportSpecialColorFields item={item} />
|
||||
|
@ -156,6 +157,8 @@ function ItemSupportSpecialColorFields({ item }) {
|
|||
colorsData?.allColors?.filter((c) => !c.isStandard) || [];
|
||||
nonStandardColors.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
const linkColor = useColorModeValue("green.500", "green.300");
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
isInvalid={colorsError || itemError || mutationError ? true : false}
|
||||
|
@ -217,7 +220,7 @@ function ItemSupportSpecialColorFields({ item }) {
|
|||
href={`https://impress.openneo.net/items/${
|
||||
item.id
|
||||
}-${item.name.replace(/ /g, "-")}`}
|
||||
color="green.500"
|
||||
color={linkColor}
|
||||
isExternal
|
||||
>
|
||||
item page <ExternalLinkIcon />
|
||||
|
|
|
@ -82,7 +82,7 @@ function HangerSpinner(props) {
|
|||
}
|
||||
`}
|
||||
>
|
||||
<HangerIcon {...props} />
|
||||
<HangerIcon color="green.300" {...props} />
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -176,7 +176,7 @@ export function OutfitLayers({
|
|||
/>
|
||||
</FullScreenCenter>
|
||||
<FullScreenCenter zIndex="9001">
|
||||
<HangerSpinner color="green.300" boxSize="48px" />
|
||||
<HangerSpinner boxSize="48px" />
|
||||
</FullScreenCenter>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import gql from "graphql-tag";
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { Box, Flex, Select, Text } from "@chakra-ui/core";
|
||||
import { Box, Flex, Select, Text, useColorModeValue } from "@chakra-ui/core";
|
||||
|
||||
import { Delay, useFetch } from "../util";
|
||||
|
||||
|
@ -55,9 +55,10 @@ function SpeciesColorPicker({
|
|||
const allSpecies = (meta && [...meta.allSpecies]) || [];
|
||||
allSpecies.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
const backgroundColor = dark ? "gray.600" : "white";
|
||||
const borderColor = dark ? "transparent" : "green.600";
|
||||
const textColor = dark ? "gray.50" : "inherit";
|
||||
const backgroundColor = useColorModeValue("white", "gray.600");
|
||||
const borderColor = useColorModeValue("green.600", "transparent");
|
||||
const textColor = useColorModeValue("inherit", "green.50");
|
||||
|
||||
const SpeciesColorSelect = ({ isDisabled, isLoading, ...props }) => {
|
||||
const loadingProps = isLoading
|
||||
? {
|
||||
|
|
|
@ -34,9 +34,9 @@ export function Delay({ children, ms = 300 }) {
|
|||
export function Heading1({ children, ...props }) {
|
||||
return (
|
||||
<Heading
|
||||
size="2xl"
|
||||
fontFamily="Delicious, sans-serif"
|
||||
fontWeight="800"
|
||||
size="2xl"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
@ -52,7 +52,6 @@ export function Heading2({ children, ...props }) {
|
|||
return (
|
||||
<Heading
|
||||
size="xl"
|
||||
color="green.800"
|
||||
fontFamily="Delicious, sans-serif"
|
||||
fontWeight="700"
|
||||
{...props}
|
||||
|
|
Loading…
Reference in a new issue