Search code examples
javascriptreactjsselectmenuitemchakra-ui

Chakra UI Select option opens and closes immediately


I want to create a menu and make the menu items selectable. I am using Chakra UI's Menu and Select components. When I click on the Select, options open and then close immediately before I can select.

Does anyone have a solution for this or know what can cause this kind of problem?

Here is my code that contains MenuItem and Select component.

<Menu>
  <MenuButton
    as={IconButton}
    icon={<DnDIcon color={theme.colors.yellow[500]} />}
    w="2rem"
    h="2rem"
    pos="absolute"
    bg="none"
  />
  <MenuList
    bg="#17243a"
    border="none"
    height="265px"
    // className="scrollbarStyle"
    // overflowY="scroll"
  >
    <Flex position="absolute">
      <MenuItem
        p="0"
        _hover={{
          backgroundColor: theme.colors.whiteAlpha[300],
        }}
      >
        <Flex direction="row" transform="none" w="100%" h="2rem" p="0.25rem">
          <Box
            w="27.6px"
            bgColor="black"
            borderLeftRadius="md"
            alignItems="center"
            justifyContent="center"
          >
            <Box>
              <Text color={"#f5bd42"}>{1}</Text>
            </Box>
          </Box>
          <Box w="calc(100% - 27.6px)" borderRightRadius="md" bgColor="#f5bd42">
            <Flex>
              <Select size="xs">
                {plans?.Data?.slice(0, 8).map((plan, index) => (
                  <option key={index}>{plan.Name}</option>
                ))}
              </Select>
            </Flex>
          </Box>
        </Flex>
      </MenuItem>
    </Flex>
  </MenuList>
</Menu>;

`


Solution

  • I found your issue, the problem is that when you click on the Select, the parent Components also think that you click them (event bubbling: https://javascript.info/bubbling-and-capturing). What you have to do is to avoid this bubbling by adding the following on your Select component:

    <Select onClick={e => e.stopPropagation()} size="xs">
                {plans?.Data?.slice(0, 8).map((plan, index) => (
                  <option key={index}>{plan.Name}</option>
                ))}
    </Select>
    

    This will avoid that the event bubbles up to your parent components and avoids your select losing focus.