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:
parent
0674834fb2
commit
d59a4948a0
1 changed files with 58 additions and 40 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue