fix large-icon visual bug

Looks like there was some kind of runtime conflict when running @emotion/css and @emotion/react at the same time in this app? Some styles would just get clobbered, making things look all weird.

Here, I've removed our @emotion/css dependency, and use the `<ClassNames>` utility element from `@emotion/react` instead. I'm not thrilled about the solution, but it seems okay for now...

...one other thing I tried was passing a `css` prop to Chakra elements, which seemed to work, but to clobber the element's own Emotion-based styles. I assumed that the Babel macro wouldn't help us, and wouldn't convert css props to className props for non-HTML elements... but I suppose I'm not sure!

Anyway, I don't love this syntax... but I'm happy for the site to be working again. I wonder if we can find something better.
This commit is contained in:
Emi Matchu 2021-01-04 03:11:46 +00:00
parent 40728daa99
commit 4120c7aa88
16 changed files with 1460 additions and 1349 deletions

View file

@ -9,7 +9,6 @@
"@chakra-ui/icons": "^1.0.2",
"@chakra-ui/react": "^1.0.4",
"@chakra-ui/theme-tools": "^1.0.2",
"@emotion/css": "^11.1.3",
"@emotion/react": "^11.1.4",
"@emotion/styled": "^11.0.0",
"@loadable/component": "^5.12.0",

View file

@ -1,5 +1,5 @@
import React from "react";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import gql from "graphql-tag";
import {
Box,
@ -213,6 +213,8 @@ function SubmitPetForm() {
const buttonBgColorHover = useColorModeValue("green.700", "green.200");
return (
<ClassNames>
{({ css }) => (
<form onSubmit={onSubmit}>
<Flex>
<Input
@ -244,6 +246,8 @@ function SubmitPetForm() {
</Button>
</Flex>
</form>
)}
</ClassNames>
);
}

View file

@ -1,5 +1,5 @@
import React from "react";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
AspectRatio,
Button,
@ -205,6 +205,8 @@ function ItemPageOwnButton({ itemId, isChecked }) {
);
return (
<ClassNames>
{({ css }) => (
<Box as="label">
<VisuallyHidden
as="input"
@ -216,7 +218,8 @@ function ItemPageOwnButton({ itemId, isChecked }) {
console.error(e);
toast({
title: "We had trouble adding this to the items you own.",
description: "Check your internet connection, and try again.",
description:
"Check your internet connection, and try again.",
status: "error",
duration: 5000,
});
@ -225,8 +228,10 @@ function ItemPageOwnButton({ itemId, isChecked }) {
sendRemoveMutation().catch((e) => {
console.error(e);
toast({
title: "We had trouble removing this from the items you own.",
description: "Check your internet connection, and try again.",
title:
"We had trouble removing this from the items you own.",
description:
"Check your internet connection, and try again.",
status: "error",
duration: 5000,
});
@ -254,6 +259,8 @@ function ItemPageOwnButton({ itemId, isChecked }) {
I own this
</Button>
</Box>
)}
</ClassNames>
);
}
@ -306,6 +313,8 @@ function ItemPageWantButton({ itemId, isChecked }) {
);
return (
<ClassNames>
{({ css }) => (
<Box as="label">
<VisuallyHidden
as="input"
@ -317,7 +326,8 @@ function ItemPageWantButton({ itemId, isChecked }) {
console.error(e);
toast({
title: "We had trouble adding this to the items you want.",
description: "Check your internet connection, and try again.",
description:
"Check your internet connection, and try again.",
status: "error",
duration: 5000,
});
@ -326,8 +336,10 @@ function ItemPageWantButton({ itemId, isChecked }) {
sendRemoveMutation().catch((e) => {
console.error(e);
toast({
title: "We had trouble removing this from the items you want.",
description: "Check your internet connection, and try again.",
title:
"We had trouble removing this from the items you want.",
description:
"Check your internet connection, and try again.",
status: "error",
duration: 5000,
});
@ -355,6 +367,8 @@ function ItemPageWantButton({ itemId, isChecked }) {
I want this
</Button>
</Box>
)}
</ClassNames>
);
}

View file

@ -1,5 +1,5 @@
import React from "react";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import { Box, Skeleton, useColorModeValue, useToken } from "@chakra-ui/react";
import gql from "graphql-tag";
import { useQuery } from "@apollo/client";
@ -165,6 +165,8 @@ function ItemTradesTable({
};
return (
<ClassNames>
{({ css }) => (
<Box
as="table"
width="100%"
@ -243,6 +245,8 @@ function ItemTradesTable({
)}
</Box>
</Box>
)}
</ClassNames>
);
}
@ -263,6 +267,8 @@ function ItemTradesTableRow({
);
return (
<ClassNames>
{({ css }) => (
<Box
as="tr"
cursor="pointer"
@ -320,6 +326,8 @@ function ItemTradesTableRow({
</Box>
</ItemTradesTableCell>
</Box>
)}
</ClassNames>
);
}
@ -350,6 +358,8 @@ function ItemTradesTableCell({ children, as = "td", ...props }) {
const borderRadiusCss = useToken("radii", "md");
return (
<ClassNames>
{({ css }) => (
<Box
as={as}
paddingX="4"
@ -391,6 +401,8 @@ function ItemTradesTableCell({ children, as = "td", ...props }) {
>
{children}
</Box>
)}
</ClassNames>
);
}

View file

@ -1,5 +1,5 @@
import React from "react";
import { css } from "@emotion/css";
import { css } from "@emotion/react";
import { VStack } from "@chakra-ui/react";
import { Heading1, Heading2, Heading3 } from "./util";
@ -11,7 +11,7 @@ function PrivacyPolicyPage() {
<VStack
spacing="4"
alignItems="flex-start"
className={css`
css={css`
max-width: 800px;
p {

View file

@ -1,5 +1,5 @@
import React from "react";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
Badge,
Box,
@ -149,6 +149,8 @@ function UserItemsPage() {
).size;
return (
<ClassNames>
{({ css }) => (
<Box>
<Flex align="center" wrap="wrap-reverse">
<Box>
@ -248,7 +250,9 @@ function UserItemsPage() {
</Box>
)}
<Heading2 id="owned-items" marginBottom="2">
{isCurrentUser ? "Items you own" : `Items ${data.user.username} owns`}
{isCurrentUser
? "Items you own"
: `Items ${data.user.username} owns`}
</Heading2>
<VStack
spacing="8"
@ -269,7 +273,9 @@ function UserItemsPage() {
</Box>
<Heading2 id="wanted-items" marginTop="10" marginBottom="2">
{isCurrentUser ? "Items you want" : `Items ${data.user.username} wants`}
{isCurrentUser
? "Items you want"
: `Items ${data.user.username} wants`}
</Heading2>
<VStack spacing="4" alignItems="stretch">
{listsOfWantedItems.map((closetList) => (
@ -282,6 +288,8 @@ function UserItemsPage() {
))}
</VStack>
</Box>
)}
</ClassNames>
);
}
@ -588,6 +596,8 @@ function MarkdownAndSafeHTML({ children }) {
});
return (
<ClassNames>
{({ css }) => (
<Box
dangerouslySetInnerHTML={{ __html: sanitizedHtml }}
className={css`
@ -602,7 +612,9 @@ function MarkdownAndSafeHTML({ children }) {
margin-left: 2em;
}
`}
></Box>
/>
)}
</ClassNames>
);
}

View file

@ -1,5 +1,5 @@
import React from "react";
import { css, cx } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
Box,
Flex,
@ -166,6 +166,8 @@ function ItemContainer({ children, isDisabled = false }) {
);
return (
<ClassNames>
{({ css, cx }) => (
<Box
p="1"
my="1"
@ -195,6 +197,8 @@ function ItemContainer({ children, isDisabled = false }) {
>
{children}
</Box>
)}
</ClassNames>
);
}
@ -242,6 +246,8 @@ function ItemActionButton({ icon, label, to, onClick }) {
);
return (
<ClassNames>
{({ css }) => (
<Tooltip label={label} placement="top">
<IconButton
as={to ? Link : "button"}
@ -275,6 +281,8 @@ function ItemActionButton({ icon, label, to, onClick }) {
`}
/>
</Tooltip>
)}
</ClassNames>
);
}

View file

@ -1,5 +1,5 @@
import React from "react";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
Box,
Editable,
@ -34,6 +34,8 @@ function ItemsPanel({ outfitState, loading, dispatchToOutfit }) {
const { zonesAndItems, incompatibleItems } = outfitState;
return (
<ClassNames>
{({ css }) => (
<Box>
<Box px="1">
<OutfitHeading
@ -43,11 +45,16 @@ function ItemsPanel({ outfitState, loading, dispatchToOutfit }) {
</Box>
<Flex direction="column">
{loading ? (
<ItemZoneGroupsSkeleton itemCount={outfitState.allItemIds.length} />
<ItemZoneGroupsSkeleton
itemCount={outfitState.allItemIds.length}
/>
) : (
<TransitionGroup component={null}>
{zonesAndItems.map(({ zoneLabel, items }) => (
<CSSTransition key={zoneLabel} {...fadeOutAndRollUpTransition}>
<CSSTransition
key={zoneLabel}
{...fadeOutAndRollUpTransition(css)}
>
<ItemZoneGroup
zoneLabel={zoneLabel}
items={items}
@ -78,6 +85,8 @@ function ItemsPanel({ outfitState, loading, dispatchToOutfit }) {
)}
</Flex>
</Box>
)}
</ClassNames>
);
}
@ -125,6 +134,8 @@ function ItemZoneGroup({
);
return (
<ClassNames>
{({ css }) => (
<Box mb="10">
<Heading2 display="flex" alignItems="center" mx="1">
{zoneLabel}
@ -149,7 +160,10 @@ function ItemZoneGroup({
);
return (
<CSSTransition key={item.id} {...fadeOutAndRollUpTransition}>
<CSSTransition
key={item.id}
{...fadeOutAndRollUpTransition(css)}
>
{isDisabled ? (
itemNode
) : (
@ -178,6 +192,8 @@ function ItemZoneGroup({
</TransitionGroup>
</ItemListContainer>
</Box>
)}
</ClassNames>
);
}
@ -273,7 +289,7 @@ function OutfitHeading({ outfitState, dispatchToOutfit }) {
*
* See react-transition-group docs for more info!
*/
const fadeOutAndRollUpTransition = {
const fadeOutAndRollUpTransition = (css) => ({
classNames: css`
&-exit {
opacity: 1;
@ -292,6 +308,6 @@ const fadeOutAndRollUpTransition = {
onExit: (e) => {
e.style.height = e.offsetHeight + "px";
},
};
});
export default ItemsPanel;

View file

@ -1,5 +1,5 @@
import React from "react";
import { css, cx } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
Box,
Button,
@ -84,6 +84,8 @@ function OutfitControls({
};
return (
<ClassNames>
{({ css, cx }) => (
<Box
role="group"
pos="absolute"
@ -120,7 +122,9 @@ function OutfitControls({
focusIsLocked && "focus-is-locked"
)}
onClickCapture={(e) => {
const opacity = parseFloat(getComputedStyle(e.currentTarget).opacity);
const opacity = parseFloat(
getComputedStyle(e.currentTarget).opacity
);
if (opacity < 0.5) {
// If the controls aren't visible right now, then clicks on them are
// probably accidental. Ignore them! (We prevent default to block
@ -198,6 +202,8 @@ function OutfitControls({
</Flex>
</Flex>
</Box>
)}
</ClassNames>
);
}
@ -277,6 +283,8 @@ function PlayPauseButton() {
}, [blinkInState, setBlinkInState]);
return (
<ClassNames>
{({ css }) => (
<>
<PlayPauseButtonContent
isPaused={isPaused}
@ -326,6 +334,8 @@ function PlayPauseButton() {
</Portal>
)}
</>
)}
</ClassNames>
);
}

View file

@ -1,7 +1,7 @@
import React from "react";
import gql from "graphql-tag";
import { useQuery } from "@apollo/client";
import { css, cx } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
Box,
Button,
@ -107,6 +107,8 @@ function PosePicker({
};
return (
<ClassNames>
{({ css, cx }) => (
<Popover
placement="bottom-end"
returnFocusOnClose
@ -198,6 +200,8 @@ function PosePicker({
</>
)}
</Popover>
)}
</ClassNames>
);
}
@ -343,6 +347,8 @@ function PoseOption({
);
return (
<ClassNames>
{({ css, cx }) => (
<Box
as="label"
cursor="pointer"
@ -428,7 +434,11 @@ function PoseOption({
)}
/>
{poseInfo.isAvailable ? (
<Box width="100%" height="100%" transform={getTransform(poseInfo)}>
<Box
width="100%"
height="100%"
transform={getTransform(poseInfo)}
>
<OutfitLayers visibleLayers={getVisibleLayers(poseInfo, [])} />
</Box>
) : (
@ -447,6 +457,8 @@ function PoseOption({
</Box>
)}
</Box>
)}
</ClassNames>
);
}

View file

@ -12,7 +12,7 @@ import {
useColorModeValue,
} from "@chakra-ui/react";
import { CloseIcon, SearchIcon } from "@chakra-ui/icons";
import { css, cx } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import Autosuggest from "react-autosuggest";
/**
@ -79,6 +79,8 @@ function SearchToolbar({
({ containerProps, children }) => {
const { className, ...otherContainerProps } = containerProps;
return (
<ClassNames>
{({ css, cx }) => (
<Box
{...otherContainerProps}
borderBottomRadius="md"
@ -96,6 +98,8 @@ function SearchToolbar({
>
{children}
</Box>
)}
</ClassNames>
);
},
[]
@ -111,6 +115,8 @@ function SearchToolbar({
const focusBorderColor = useColorModeValue("green.600", "green.400");
return (
<ClassNames>
{({ css }) => (
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={({ value }) =>
@ -122,7 +128,8 @@ function SearchToolbar({
onChange({
...query,
value: valueWithoutLastWord,
filterToZoneLabel: suggestion.zoneLabel || query.filterToZoneLabel,
filterToZoneLabel:
suggestion.zoneLabel || query.filterToZoneLabel,
filterToItemKind: suggestion.itemKind || query.filterToItemKind,
});
}}
@ -203,7 +210,10 @@ function SearchToolbar({
return;
}
onMoveFocusDownToResults(e);
} else if (e.key === "Backspace" && e.target.selectionStart === 0) {
} else if (
e.key === "Backspace" &&
e.target.selectionStart === 0
) {
onChange({
...query,
filterToItemKind: null,
@ -213,6 +223,8 @@ function SearchToolbar({
},
}}
/>
)}
</ClassNames>
);
}

View file

@ -1,7 +1,7 @@
import * as React from "react";
import gql from "graphql-tag";
import { useQuery, useMutation } from "@apollo/client";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
Badge,
Box,
@ -454,6 +454,8 @@ function ItemSupportAppearanceLayer({
const iconButtonColor = useColorModeValue("green.800", "gray.900");
return (
<ClassNames>
{({ css }) => (
<Box
as="button"
width="150px"
@ -519,6 +521,8 @@ function ItemSupportAppearanceLayer({
onClose={onClose}
/>
</Box>
)}
</ClassNames>
);
}

View file

@ -1,5 +1,5 @@
import * as React from "react";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import { Box, useColorModeValue } from "@chakra-ui/react";
import { createIcon } from "@chakra-ui/icons";
@ -21,7 +21,8 @@ function HangerSpinner({ size = "md", ...props }) {
const color = useColorModeValue("green.500", "green.300");
return (
<>
<ClassNames>
{({ css }) => (
<Box
className={css`
/*
@ -88,7 +89,8 @@ function HangerSpinner({ size = "md", ...props }) {
>
<HangerIcon boxSize={boxSize} color={color} transition="color 0.2s" />
</Box>
</>
)}
</ClassNames>
);
}

View file

@ -1,5 +1,5 @@
import React from "react";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import {
Badge,
Box,
@ -102,6 +102,8 @@ export function ItemThumbnail({
);
return (
<ClassNames>
{({ css }) => (
<Box
width={size === "lg" ? "80px" : "50px"}
height={size === "lg" ? "80px" : "50px"}
@ -155,6 +157,8 @@ export function ItemThumbnail({
/>
</Box>
</Box>
)}
</ClassNames>
);
}
@ -166,6 +170,8 @@ function ItemName({ children, isDisabled, focusSelector, ...props }) {
const theme = useTheme();
return (
<ClassNames>
{({ css }) => (
<Box
fontSize="md"
transition="all 0.15s"
@ -190,6 +196,8 @@ function ItemName({ children, isDisabled, focusSelector, ...props }) {
>
{children}
</Box>
)}
</ClassNames>
);
}

View file

@ -1,7 +1,7 @@
import React from "react";
import { Box, DarkMode, Flex, Text } from "@chakra-ui/react";
import { WarningIcon } from "@chakra-ui/icons";
import { css } from "@emotion/css";
import { ClassNames } from "@emotion/react";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import OutfitMovieLayer, {
@ -149,6 +149,8 @@ export function OutfitLayers({
}, [setCanvasSize]);
return (
<ClassNames>
{({ css }) => (
<Box
pos="relative"
height="100%"
@ -243,10 +245,17 @@ export function OutfitLayers({
</>
)}
{spinnerVariant === "corner" && (
<HangerSpinner size="sm" position="absolute" bottom="2" right="2" />
<HangerSpinner
size="sm"
position="absolute"
bottom="2"
right="2"
/>
)}
</FullScreenCenter>
</Box>
)}
</ClassNames>
);
}

View file

@ -2750,17 +2750,6 @@
"@emotion/weak-memoize" "^0.2.5"
stylis "^4.0.3"
"@emotion/css@^11.1.3":
version "11.1.3"
resolved "https://registry.yarnpkg.com/@emotion/css/-/css-11.1.3.tgz#9ed44478b19e5d281ccbbd46d74d123d59be793f"
integrity sha512-RSQP59qtCNTf5NWD6xM08xsQdCZmVYnX/panPYvB6LQAPKQB6GL49Njf0EMbS3CyDtrlWsBcmqBtysFvfWT3rA==
dependencies:
"@emotion/babel-plugin" "^11.0.0"
"@emotion/cache" "^11.1.3"
"@emotion/serialize" "^1.0.0"
"@emotion/sheet" "^1.0.0"
"@emotion/utils" "^1.0.0"
"@emotion/hash@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"