Add focus state to species faces picker

This commit is contained in:
Emi Matchu 2021-02-02 13:31:57 -08:00
parent d16bfd9781
commit b0a8b41c80

View file

@ -686,21 +686,19 @@ function ItemPageOutfitPreview({ itemId }) {
</Box> </Box>
</Box> </Box>
</VStack> </VStack>
<Box maxWidth="400px"> <SpeciesFacesPicker
<SpeciesFacesPicker itemId={itemId}
itemId={itemId} selectedSpeciesId={petState.speciesId}
selectedSpeciesId={petState.speciesId} onChange={({ speciesId, colorId }) =>
onChange={({ speciesId, colorId }) => setPetState({
setPetState({ speciesId,
speciesId, colorId,
colorId, pose: idealPose,
pose: idealPose, appearanceId: null,
appearanceId: null, })
}) }
} isLoading={loading}
isLoading={loading} />
/>
</Box>
</Stack> </Stack>
); );
} }
@ -757,10 +755,20 @@ function PlayPauseButton({ isPaused, onClick }) {
function SpeciesFacesPicker({ selectedSpeciesId, onChange, isLoading }) { function SpeciesFacesPicker({ selectedSpeciesId, onChange, isLoading }) {
const selectedBorderColor = useColorModeValue("green.600", "green.400"); const selectedBorderColor = useColorModeValue("green.600", "green.400");
const selectedBackgroundColor = useColorModeValue("green.200", "green.600"); const selectedBackgroundColor = useColorModeValue("green.200", "green.600");
const focusBorderColor = "blue.400";
const focusBackgroundColor = "blue.100";
const [ const [
selectedBorderColorValue, selectedBorderColorValue,
selectedBackgroundColorValue, selectedBackgroundColorValue,
] = useToken("colors", [selectedBorderColor, selectedBackgroundColor]); focusBorderColorValue,
focusBackgroundColorValue,
] = useToken("colors", [
selectedBorderColor,
selectedBackgroundColor,
focusBorderColor,
focusBackgroundColor,
]);
const lgShadow = useToken("shadows", "xl");
const allSpeciesFaces = speciesFaces.sort((a, b) => const allSpeciesFaces = speciesFaces.sort((a, b) =>
a.speciesName.localeCompare(b.speciesName) a.speciesName.localeCompare(b.speciesName)
@ -769,71 +777,89 @@ function SpeciesFacesPicker({ selectedSpeciesId, onChange, isLoading }) {
return ( return (
<ClassNames> <ClassNames>
{({ css }) => ( {({ css }) => (
<Wrap <Box
spacing="0" _focusWithin={{
justify="center" boxShadow: `${focusBackgroundColorValue} 0 0 1px 2px`,
// On mobile, give this a scroll container, and some extra padding so }}
// the selected-face effects still fit inside. maxWidth="400px"
maxHeight={{ base: "200px", md: "none" }} boxSizing="content-box"
overflow={{ base: "auto", md: "visible" }} padding="2"
padding={{ base: "8px", md: "0" }} borderRadius="md"
transition="all 0.2s"
> >
{allSpeciesFaces.map( <Wrap
({ speciesId, speciesName, colorId, neopetsImageHash }) => ( spacing="0"
<WrapItem justify="center"
key={speciesId} // On mobile, give this a scroll container, and some extra padding so
as="label" // the selected-face effects still fit inside.
cursor={isLoading ? "wait" : "pointer"} maxHeight={{ base: "200px", md: "none" }}
position="relative" overflow={{ base: "auto", md: "visible" }}
> padding={{ base: "8px", md: "0" }}
<VisuallyHidden >
as="input" {allSpeciesFaces.map(
type="radio" ({ speciesId, speciesName, colorId, neopetsImageHash }) => (
aria-label={speciesName} <WrapItem
name="species-faces-picker" key={speciesId}
value={speciesId} as="label"
checked={speciesId === selectedSpeciesId} cursor={isLoading ? "wait" : "pointer"}
disabled={isLoading} position="relative"
onChange={() => onChange({ speciesId, colorId })}
/>
<Box
overflow="hidden"
transition="all 0.2s"
className={css`
input:checked + & {
background: ${selectedBackgroundColorValue};
border-radius: 6px;
box-shadow: ${selectedBorderColorValue} 0 0 0 3px;
transform: scale(1.2);
z-index: 1;
}
`}
> >
<VisuallyHidden
as="input"
type="radio"
aria-label={speciesName}
name="species-faces-picker"
value={speciesId}
checked={speciesId === selectedSpeciesId}
disabled={isLoading}
onChange={() => onChange({ speciesId, colorId })}
/>
<Box <Box
as="img" overflow="hidden"
src={`https://pets.neopets-asset-proxy.openneo.net/cp/${neopetsImageHash}/1/1.png`}
srcSet={
`https://pets.neopets-asset-proxy.openneo.net/cp/${neopetsImageHash}/1/1.png 1x, ` +
`https://pets.neopets-asset-proxy.openneo.net/cp/${neopetsImageHash}/1/6.png 2x`
}
alt={speciesName}
width={50}
height={50}
filter="saturate(90%)"
opacity="0.9"
transition="all 0.2s" transition="all 0.2s"
className={css` className={css`
input:checked + * > & { input:checked + & {
opacity: 1; background: ${selectedBackgroundColorValue};
filter: saturate(110%); border-radius: 6px;
box-shadow: ${lgShadow},
${selectedBorderColorValue} 0 0 2px 2px;
transform: scale(1.2);
z-index: 1;
}
input:focus + & {
background: ${focusBackgroundColorValue};
box-shadow: ${lgShadow},
${focusBorderColorValue} 0 0 0 3px;
} }
`} `}
/> >
</Box> <Box
</WrapItem> as="img"
) src={`https://pets.neopets-asset-proxy.openneo.net/cp/${neopetsImageHash}/1/1.png`}
)} srcSet={
</Wrap> `https://pets.neopets-asset-proxy.openneo.net/cp/${neopetsImageHash}/1/1.png 1x, ` +
`https://pets.neopets-asset-proxy.openneo.net/cp/${neopetsImageHash}/1/6.png 2x`
}
alt={speciesName}
width={50}
height={50}
filter="saturate(90%)"
opacity="0.9"
transition="all 0.2s"
className={css`
input:checked + * & {
opacity: 1;
filter: saturate(110%);
}
`}
/>
</Box>
</WrapItem>
)
)}
</Wrap>
</Box>
)} )}
</ClassNames> </ClassNames>
); );