Search code examples
htmlcssflexboxreactstrap

How do I right align a ButtonDrowpdown inside a ModalHeader with reactstrap?


I am pretty happy with the Modal that I have so far, except that the dropdown is not where I want it to be. I want it farther right, just to the left of the 'x' button. Here is the code I have so far:

<Modal isOpen={modal} toggle={toggleModal} className="modal-lg modal-dialog-scrollable" returnFocusAfterClose={false}>
    <ModalHeader toggle={toggleModal}>
        <span className="align-middle mr-auto">Modal Title</span>
        <ButtonDropdown isOpen={dropdownOpen} toggle={toggleDropdown}>
            <DropdownToggle caret color="info" className="btn-sm">
                Dropdown
            </DropdownToggle>
            <DropdownMenu>
                <DropdownItem header>Header</DropdownItem>
                <DropdownItem disabled>Action</DropdownItem>
                <DropdownItem>Another Action</DropdownItem>
                <DropdownItem divider />
                <DropdownItem>Another Action</DropdownItem>
            </DropdownMenu>
        </ButtonDropdown>
    </ModalHeader>
    <ModalBody>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </ModalBody>
</Modal>

Where I want the dropdown

I have tried to use bootstrap classes with a flex-row div around the stuff inside the ModalHeader and ml-auto on the ButtonDropdown but that didn't work for me.

Update 1 After some time looking into this, I still can't figure out how to solve this. I do know that the reactstrap source code is wrapping everything in a modal-title div before wrapping the modal-header around that (I found that out by looking at ModalHeader.js). To investigate further I wrote a basic example with reactstrap:

<Modal isOpen={modal} toggle={toggleModal}>
    <ModalHeader>
        <div className="d-flex flex-row">
        <h5 className="mr-auto">Test 1</h5>
        <h5>Test 2</h5>
        </div>            
    </ModalHeader>
    <ModalBody>
        Lorem ipsum .
    </ModalBody>
</Modal>

This gets rendered to the following html and css:

<div class="modal-header">
    <h5 class="modal-title">
        <div class="d-flex flex-row">
        <h5 class="mr-auto">Test 1</h5>
        <h5>Test 2</h5>
        </div>
    </h5>
</div>
.modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding: 1rem 1rem;
    border-bottom: 1px solid #dee2e6;
    border-top-left-radius: calc(.3rem - 1px);
    border-top-right-radius: calc(.3rem - 1px);
}

.modal-title {
    margin-bottom: 0;
    line-height: 1.5;
}

This still doesn't work, though: "Test 1" and "Test 2" are right next to each other as opposed to 1 on the left and 2 on the right. I know that if I remove the modal header display:flex that it looks like it's fixed but I'm not really sure why. I don't think the modal-title is the issue.


Solution

  • Reactstrap create after ModalHeader another tag <h5 class="modal-title">...</h5> which wrapping all what you put into the ModalHeader. And this is the first place, where need to fix the problem with this snippet.

    style.css

    .modal-title {
      width: 100%;
      display: flex;
    }
    

    The second place is <span className="align-middle mr-auto">Modal Title</span> replace mr-auto to flex-grow-1 codesandbox example

    App.js

    <Modal
        isOpen={modal}
        toggle={toggleModal}
        className="modal-lg modal-dialog-scrollable"
        returnFocusAfterClose={false}
      >
        <ModalHeader toggle={toggleModal}>
          <span className="align-middle flex-grow-1">Modal Title</span>
          <ButtonDropdown isOpen={dropdownOpen} toggle={toggleDropdown}>
            <DropdownToggle caret color="info" className="btn-sm">
              Dropdown
            </DropdownToggle>
            <DropdownMenu>
              <DropdownItem header>Header</DropdownItem>
              <DropdownItem disabled>Action</DropdownItem>
              <DropdownItem>Another Action</DropdownItem>
              <DropdownItem divider />
              <DropdownItem>Another Action</DropdownItem>
            </DropdownMenu>
          </ButtonDropdown>
        </ModalHeader>
        <ModalBody>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat. Duis aute irure dolor in
          reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
          pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
          culpa qui officia deserunt mollit anim id est laborum.
        </ModalBody>
      </Modal>