Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chakra UI using multiple models in a single component

I am using Chakra UI and I want to use two modals in a single component.

const { isOpen , onOpen, onClose } = useDisclosure()

 <Button colorScheme="teal" size="xs" mr='2' onClick={onOpen} >
                        Edit
                    </Button>
                    {/* Edit modal */}
                    <Modal isOpen={isOpen} onClose={onClose}>
                            <ModalOverlay />
                            <ModalContent>
                            <ModalHeader>Edit Modal</ModalHeader>
                            <ModalCloseButton />
                            <ModalBody>
                               Edit Modal
                            </ModalBody>

                            <ModalFooter>
                            <Button variant="ghost" mr={3} onClick={onClose}>Cancel</Button>
                                <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
                                    Delete
                                </Button>
                                
                            </ModalFooter>
                            </ModalContent>
                        </Modal>


                    {/* Delete Address */}

                    <Button colorScheme="red" size="xs"  onClick={onOpen}>
                        Delete
                    </Button> 
                    <Modal isOpen={isOpen} onClose={onClose}>
                            <ModalOverlay />
                            <ModalContent>
                            <ModalHeader>Delete Shipping Address</ModalHeader>
                            <ModalCloseButton />
                            <ModalBody>
                                Are you sure you want to delete the shipping address?
                            </ModalBody>

                            <ModalFooter>
                            <Button variant="ghost" mr={3} onClick={onClose}>Cancel</Button>
                                <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
                                    Delete
                                </Button>
                                
                            </ModalFooter>
                            </ModalContent>
                        </Modal>

isOpen, onOpen and onClose can't be changed as variables since they are inbuilt Chakra functions.

Can someone suggest me a method to variate two of these modal (Chakra UI) operations?

like image 397
Pasan Madhushan Avatar asked Feb 01 '21 07:02

Pasan Madhushan


People also ask

What is useDisclosure?

useDisclosure is a custom hook used to help handle common open , close , or toggle scenarios. It can be used to control feedback component such as Modal, AlertDialog, Drawer, etc.

How good is Chakra UI?

Conclusion. Chakra UI has helped me boost my development process to another level. It's very flexible, the documentation is great, and there are a lot of pre-built templates to help you speed up the process.

Is Chakra UI a design system?

YOGI is a React Design System starter-kit for Backlight, based on Chakra UI.


3 Answers

You can simply change the name of variables isOpen, onOpen and onClose lets go:

const { isOpen: isEditOpen , onOpen: onEditOpen, onClose: onEditClose } = useDisclosure()
const { isOpen: isDeleteOpen , onOpen: onDeleteOpen, onClose: onDeleteClose } = useDisclosure()

{/* Edit Button*/}
<Button colorScheme="teal" size="xs" mr='2' onClick={onEditOpen} >
    Edit
</Button>

{/* Edit Modal */}
<Modal isOpen={isEditOpen} onClose={onEditClose}>
    <ModalOverlay />
    <ModalContent>
    <ModalHeader>Edit Modal</ModalHeader>
    <ModalCloseButton />
    <ModalBody>
        Edit Modal
    </ModalBody>
    <ModalFooter>
    <Button variant="ghost" mr={3} onClick={onEditClose}>Cancel</Button>
        <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
            Delete
        </Button>
    </ModalFooter>
    </ModalContent>
</Modal>


{/* Delete Button*/}
<Button colorScheme="red" size="xs"  onClick={onDeleteOpen}>
    Delete
</Button> 

{/* Delete Modal*/}
<Modal isOpen={isDeleteOpen} onClose={onSecondModalClose}>
    <ModalOverlay />
    <ModalContent>
    <ModalHeader>Delete Shipping Address</ModalHeader>
    <ModalCloseButton />
    <ModalBody>
        Are you sure you want to delete the shipping address?
    </ModalBody>
    <ModalFooter>
    <Button variant="ghost" mr={3} onClick={onDeleteClose}>Cancel</Button>
        <Button colorScheme="red" onClick={()=>{deleteAddress(address.id)}}>
            Delete
        </Button>
    </ModalFooter>
    </ModalContent>
</Modal>

One more example:

First modal:

const { isOpen: isFirstModalOpen , onOpen: onFirstModalOpen, onClose: onFirstModalClose } = useDisclosure()

Second modal:

const { isOpen: isSecondModalOpen , onOpen: onSecondModalOpen, onClose: onSecondModalClose } = useDisclosure()

Now these variables have different values so you can use new names every where!

like image 166
Alireza Khanamani Avatar answered Nov 15 '22 09:11

Alireza Khanamani


You could create a custom modal component that uses useDisclosure. Then you can have multiple instances of this custom modal component without the modals sharing the same state:

const CustomModal = ({ showModalButtonText, modalHeader, modalBody }) => {
  const { isOpen, onOpen, onClose } = useDisclosure();
  return (
    <>
      <Button colorScheme="red" size="xs" onClick={onOpen}>
        {showModalButtonText}
      </Button>
      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>{modalHeader}</ModalHeader>
          <ModalCloseButton />
          <ModalBody>{modalBody}</ModalBody>

          <ModalFooter>
            <Button variant="ghost" mr={3} onClick={onClose}>
              Cancel
            </Button>
            <Button
              colorScheme="red"
              onClick={() => {
                alert(1);
              }}
            >
              Delete
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </>
  );
};

export default function App() {
  return (
    <div className="App">
      <CustomModal
        showModalButtonText="Edit"
        modalHeader="Edit Modal"
        modalBody="Edit Modal"
      />
      <CustomModal
        showModalButtonText="Delete"
        modalHeader="Delete Shipping Address"
        modalBody="Are you sure you want to delete the shipping address?"
      />
    </div>
  );
}

This way each instance of CustomModal keeps track of its own isOpen, onOpen and onClose state.

Since in your question the only dynamic parts were the button for opening, the modal, the header text and the modal body text, I've made props so these can be set separately for each instance. If more parts need to be dynamic you can add props as needed.

I've changed some small things to the modal to make it easier to test.

like image 43
Bas van der Linden Avatar answered Nov 15 '22 10:11

Bas van der Linden


you can simply create two instances of useDisclosure hook.

  const {
    isOpen: isAssociationModalOpen,
    onOpen: onOpenAssociationModal,
    onClose: onCloseAssociationModal,
  } = useDisclosure();
  const {
    isOpen: isRevocationModalOpen,
    onOpen: onOpenRevocationModal,
    onClose: onCloseRevocationModal,
  } = useDisclosure();
like image 27
Ion Moraru Avatar answered Nov 15 '22 08:11

Ion Moraru