fix species/color dropdown focus bug

Oops, creating a new `SpeciesColorPicker` fn on each render meant that React treated it as a whole new dropdown each time. I've extracted it out into a stable component class, and just pass in the extra props now!

This bug caused changes to kick you out of focus for the dropdown, because it had unmounted and remounted.
This commit is contained in:
Emi Matchu 2020-12-04 13:01:39 -08:00
parent 0674834fb2
commit d59a4948a0

View file

@ -58,48 +58,8 @@ function SpeciesColorPicker({
const allSpecies = (meta && [...meta.allSpecies]) || []; const allSpecies = (meta && [...meta.allSpecies]) || [];
allSpecies.sort((a, b) => a.name.localeCompare(b.name)); allSpecies.sort((a, b) => a.name.localeCompare(b.name));
const backgroundColor = useColorModeValue("white", "gray.600");
const borderColor = useColorModeValue("green.600", "transparent");
const textColor = useColorModeValue("inherit", "green.50"); const textColor = useColorModeValue("inherit", "green.50");
const SpeciesColorSelect = ({ isDisabled, isLoading, ...props }) => {
const loadingProps = isLoading
? {
// Visually the disabled state is the same as the normal state, but
// with a wait cursor. We don't expect this to take long, and the flash
// of content is rough!
opacity: "1 !important",
cursor: "wait !important",
}
: {};
return (
<Select
backgroundColor={backgroundColor}
color={textColor}
size={size}
border="1px"
borderColor={borderColor}
boxShadow="md"
width="auto"
transition="all 0.25s"
_hover={{
borderColor: "green.400",
}}
isInvalid={
valids &&
speciesId &&
colorId &&
!pairIsValid(valids, speciesId, colorId)
}
isDisabled={isDisabled || isLoading}
errorBorderColor="red.300"
{...props}
{...loadingProps}
/>
);
};
if ((loadingMeta || loadingValids) && !showPlaceholders) { if ((loadingMeta || loadingValids) && !showPlaceholders) {
return ( return (
<Delay ms={5000}> <Delay ms={5000}>
@ -191,6 +151,10 @@ function SpeciesColorPicker({
isLoading={allColors.length === 0} isLoading={allColors.length === 0}
isDisabled={isDisabled} isDisabled={isDisabled}
onChange={onChangeColor} onChange={onChangeColor}
size={size}
valids={valids}
speciesId={speciesId}
colorId={colorId}
> >
{ {
// If the selected color isn't in the set we have here, show the // If the selected color isn't in the set we have here, show the
@ -218,6 +182,10 @@ function SpeciesColorPicker({
isLoading={allSpecies.length === 0} isLoading={allSpecies.length === 0}
isDisabled={isDisabled} isDisabled={isDisabled}
onChange={onChangeSpecies} onChange={onChangeSpecies}
size={size}
valids={valids}
speciesId={speciesId}
colorId={colorId}
> >
{ {
// If the selected species isn't in the set we have here, show the // If the selected species isn't in the set we have here, show the
@ -243,6 +211,56 @@ function SpeciesColorPicker({
); );
} }
const SpeciesColorSelect = ({
size,
valids,
speciesId,
colorId,
isDisabled,
isLoading,
...props
}) => {
const backgroundColor = useColorModeValue("white", "gray.600");
const borderColor = useColorModeValue("green.600", "transparent");
const textColor = useColorModeValue("inherit", "green.50");
const loadingProps = isLoading
? {
// Visually the disabled state is the same as the normal state, but
// with a wait cursor. We don't expect this to take long, and the flash
// of content is rough!
opacity: "1 !important",
cursor: "wait !important",
}
: {};
return (
<Select
backgroundColor={backgroundColor}
color={textColor}
size={size}
border="1px"
borderColor={borderColor}
boxShadow="md"
width="auto"
transition="all 0.25s"
_hover={{
borderColor: "green.400",
}}
isInvalid={
valids &&
speciesId &&
colorId &&
!pairIsValid(valids, speciesId, colorId)
}
isDisabled={isDisabled || isLoading}
errorBorderColor="red.300"
{...props}
{...loadingProps}
/>
);
};
function getPairByte(valids, speciesId, colorId) { function getPairByte(valids, speciesId, colorId) {
// Reading a bit table, owo! // Reading a bit table, owo!
const speciesIndex = speciesId - 1; const speciesIndex = speciesId - 1;