diff options
| author | Mark Otto <[email protected]> | 2017-10-29 16:13:37 -0700 |
|---|---|---|
| committer | Mark Otto <[email protected]> | 2017-10-29 16:13:37 -0700 |
| commit | b5cd9b91b2f93418bcaa6cb081cc842a6e6ef58c (patch) | |
| tree | d80b57010228641c23c2328120d894d901f2f4a2 | |
| parent | 136aefead43a231ec8fb4514c525da10ac30c497 (diff) | |
| parent | 2232b6b4d140cf8a01314deb7e4779c7fde8ab05 (diff) | |
| download | bootstrap-b5cd9b91b2f93418bcaa6cb081cc842a6e6ef58c.tar.xz bootstrap-b5cd9b91b2f93418bcaa6cb081cc842a6e6ef58c.zip | |
Merge branch 'v4-dev' of https://github.com/twbs/bootstrap into v4-dev
| -rw-r--r-- | docs/4.0/components/dropdowns.md | 126 | ||||
| -rw-r--r-- | docs/4.0/components/modal.md | 58 | ||||
| -rw-r--r-- | js/src/dropdown.js | 30 | ||||
| -rw-r--r-- | js/src/tooltip.js | 16 | ||||
| -rw-r--r-- | js/tests/visual/dropdown.html | 48 | ||||
| -rw-r--r-- | scss/_dropdown.scss | 28 | ||||
| -rw-r--r-- | scss/_modal.scss | 15 | ||||
| -rw-r--r-- | scss/mixins/_caret.scss | 30 |
8 files changed, 332 insertions, 19 deletions
diff --git a/docs/4.0/components/dropdowns.md b/docs/4.0/components/dropdowns.md index c4ada2b0f..cb307550d 100644 --- a/docs/4.0/components/dropdowns.md +++ b/docs/4.0/components/dropdowns.md @@ -410,6 +410,132 @@ Trigger dropdown menus above elements by adding `.dropup` to the parent element. </div> {% endhighlight %} +## Dropright variation + +Trigger dropdown menus at the right of the elements by adding `.dropright` to the parent element. + +<div class="bd-example"> + <div class="btn-group dropright"> + <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Dropright + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="#">Separated link</a> + </div> + </div> + + <div class="btn-group dropright"> + <button type="button" class="btn btn-secondary"> + Split dropright + </button> + <button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="sr-only">Toggle Dropdright</span> + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="#">Separated link</a> + </div> + </div> +</div> + +{% highlight html %} +<!-- Default dropright button --> +<div class="btn-group dropright"> + <button type="button" class="btn btn-secondary">Dropright</button> + <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="sr-only">Toggle Dropright</span> + </button> + <div class="dropdown-menu"> + <!-- Dropdown menu links --> + </div> +</div> + +<!-- Split dropright button --> +<div class="btn-group dropright"> + <button type="button" class="btn btn-secondary"> + Split dropright + </button> + <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="sr-only">Toggle Dropright</span> + </button> + <div class="dropdown-menu"> + <!-- Dropdown menu links --> + </div> +</div> +{% endhighlight %} + +## Dropleft variation + +Trigger dropdown menus at the left of the elements by adding `.dropleft` to the parent element. + +<div class="bd-example"> + <div class="btn-group dropleft"> + <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Dropleft + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="#">Separated link</a> + </div> + </div> + + <div class="btn-group"> + <div class="btn-group dropleft" role="group"> + <button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="sr-only">Toggle Dropleft</span> + </button> + <div class="dropdown-menu"> + <a class="dropdown-item" href="#">Action</a> + <a class="dropdown-item" href="#">Another action</a> + <a class="dropdown-item" href="#">Something else here</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="#">Separated link</a> + </div> + </div> + <button type="button" class="btn btn-secondary"> + Split dropleft + </button> + </div> +</div> + +{% highlight html %} +<!-- Default dropleft button --> +<div class="btn-group dropleft"> + <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Dropleft + </button> + <div class="dropdown-menu"> + <!-- Dropdown menu links --> + </div> +</div> + +<!-- Split dropleft button --> +<div class="btn-group"> + <div class="btn-group dropleft" role="group"> + <button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="sr-only">Toggle Dropleft</span> + </button> + <div class="dropdown-menu"> + <!-- Dropdown menu links --> + </div> + </div> + <button type="button" class="btn btn-secondary"> + Split dropleft + </button> +</div> +{% endhighlight %} + + ## Menu items Historically dropdown menu contents *had* to be links, but that's no longer the case with v4. Now you can optionally use `<button>` elements in your dropdowns instead of just `<a>`s. diff --git a/docs/4.0/components/modal.md b/docs/4.0/components/modal.md index c4191b83d..b9ebc4ad4 100644 --- a/docs/4.0/components/modal.md +++ b/docs/4.0/components/modal.md @@ -208,6 +208,64 @@ When modals become too long for the user's viewport or device, they scroll indep </div> {% endhighlight %} +### Vertically centered + +Add `.modal-dialog-centered` to `.modal-dialog` to vertically center the modal. **Do not use this with long modals**—it will overflow the viewport and potentially hide parts of your modal. + +<div id="exampleModalCenter" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> + <div class="modal-dialog modal-dialog-centered" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalCenterTitle">Modal title</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + <p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary">Save changes</button> + </div> + </div> + </div> +</div> + +<div class="bd-example"> + <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter"> + Launch demo modal + </button> +</div> + +{% highlight html %} +<!-- Button trigger modal --> +<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter"> + Launch demo modal +</button> + +<!-- Modal --> +<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> + <div class="modal-dialog" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <div class="modal-body"> + ... + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary">Save changes</button> + </div> + </div> + </div> +</div> +{% endhighlight %} + ### Tooltips and popovers [Tooltips]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/tooltips/) and [popovers]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/popovers/) can be placed within modals as needed. When modals are closed, any tooltips and popovers within are also automatically dismissed. diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 18b051b89..a18f0c28a 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -13,14 +13,6 @@ import Util from './util' const Dropdown = (($) => { /** - * Check for Popper dependency - * Popper - https://popper.js.org - */ - if (typeof Popper === 'undefined') { - throw new Error('Bootstrap dropdown require Popper.js (https://popper.js.org)') - } - - /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ @@ -55,6 +47,8 @@ const Dropdown = (($) => { DISABLED : 'disabled', SHOW : 'show', DROPUP : 'dropup', + DROPRIGHT : 'dropright', + DROPLEFT : 'dropleft', MENURIGHT : 'dropdown-menu-right', MENULEFT : 'dropdown-menu-left' } @@ -71,7 +65,11 @@ const Dropdown = (($) => { TOP : 'top-start', TOPEND : 'top-end', BOTTOM : 'bottom-start', - BOTTOMEND : 'bottom-end' + BOTTOMEND : 'bottom-end', + RIGHT : 'right-start', + RIGHTEND : 'right-end', + LEFT : 'left-start', + LEFTEND : 'left-end' } const Default = { @@ -145,6 +143,14 @@ const Dropdown = (($) => { return } + /** + * Check for Popper dependency + * Popper - https://popper.js.org + */ + if (typeof Popper === 'undefined') { + throw new Error('Bootstrap dropdown require Popper.js (https://popper.js.org)') + } + let element = this._element // for dropup with alignment we use the parent as popper container if ($(parent).hasClass(ClassName.DROPUP)) { @@ -227,7 +233,7 @@ const Dropdown = (($) => { _getPlacement() { const $parentDropdown = $(this._element).parent() - let placement = AttachmentMap.BOTTOM + let placement = AttachmentMap.BOTTOM // Handle dropup if ($parentDropdown.hasClass(ClassName.DROPUP)) { @@ -235,6 +241,10 @@ const Dropdown = (($) => { if ($(this._menu).hasClass(ClassName.MENURIGHT)) { placement = AttachmentMap.TOPEND } + } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) { + placement = AttachmentMap.RIGHT + } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) { + placement = AttachmentMap.LEFT } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) { placement = AttachmentMap.BOTTOMEND } diff --git a/js/src/tooltip.js b/js/src/tooltip.js index a3fc93c91..7cefd0be6 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -13,15 +13,6 @@ import Util from './util' const Tooltip = (($) => { /** - * Check for Popper dependency - * Popper - https://popper.js.org - */ - if (typeof Popper === 'undefined') { - throw new Error('Bootstrap tooltips require Popper.js (https://popper.js.org)') - } - - - /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ @@ -120,6 +111,13 @@ const Tooltip = (($) => { class Tooltip { constructor(element, config) { + /** + * Check for Popper dependency + * Popper - https://popper.js.org + */ + if (typeof Popper === 'undefined') { + throw new Error('Bootstrap tooltips require Popper.js (https://popper.js.org)') + } // private this._isEnabled = true diff --git a/js/tests/visual/dropdown.html b/js/tests/visual/dropdown.html index 11b89b0f2..b2e588677 100644 --- a/js/tests/visual/dropdown.html +++ b/js/tests/visual/dropdown.html @@ -93,6 +93,7 @@ </div> </div> </div> + <div class="col-sm-12 mt-4"> <div class="btn-group dropup" role="group"> <a href="#" class="btn btn-secondary">Dropup split align right</a> @@ -114,8 +115,55 @@ </div> </div> </div> + + <div class="col-sm-12 mt-4"> + <div class="btn-group dropright" role="group"> + <a href="#" class="btn btn-secondary">Dropright split</a> + <button type="button" id="dropdown-page-subheader-button-4" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="sr-only">Product actions</span> + </button> + <div class="dropdown-menu"> + <button class="dropdown-item" type="button">Action</button> + <button class="dropdown-item" type="button">Another action</button> + <button class="dropdown-item" type="button">Something else here with a long text</button> + </div> + </div> + <div class="btn-group dropright"> + <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuRight" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Dropright + </button> + <div class="dropdown-menu" aria-labelledby="dropdownMenuRight"> + <button class="dropdown-item" type="button">Action</button> + <button class="dropdown-item" type="button">Another action</button> + <button class="dropdown-item" type="button">Something else here</button> + </div> + </div> + <!-- dropleft --> + <div class="btn-group dropleft" role="group"> + <a href="#" class="btn btn-secondary">Dropleft split</a> + <button type="button" id="dropdown-page-subheader-button-5" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + <span class="sr-only">Product actions</span> + </button> + <div class="dropdown-menu"> + <button class="dropdown-item" type="button">Action</button> + <button class="dropdown-item" type="button">Another action</button> + <button class="dropdown-item" type="button">Something else here with a long text</button> + </div> + </div> + <div class="btn-group dropleft"> + <button class="btn btn-secondary dropdown-toggle" type="button" id="dropleftMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Dropleft + </button> + <div class="dropdown-menu" aria-labelledby="dropleftMenu"> + <button class="dropdown-item" type="button">Action</button> + <button class="dropdown-item" type="button">Another action</button> + <button class="dropdown-item" type="button">Something else here</button> + </div> + </div> </div> + </div> + </div> <script src="../../../assets/js/vendor/jquery-slim.min.js"></script> <script src="../../../assets/js/vendor/popper.min.js"></script> diff --git a/scss/_dropdown.scss b/scss/_dropdown.scss index 271764188..19edfca7a 100644 --- a/scss/_dropdown.scss +++ b/scss/_dropdown.scss @@ -44,6 +44,34 @@ } } +.dropright { + .dropdown-menu { + margin-top: 0; + margin-left: $dropdown-spacer; + } + + .dropdown-toggle { + @include caret(right); + &::after { + vertical-align: 0; + } + } +} + +.dropleft { + .dropdown-menu { + margin-top: 0; + margin-right: $dropdown-spacer; + } + + .dropdown-toggle { + @include caret(left); + &::before { + vertical-align: 0; + } + } +} + // Dividers (basically an `<hr>`) within the dropdown .dropdown-divider { @include nav-divider($dropdown-divider-bg); diff --git a/scss/_modal.scss b/scss/_modal.scss index 5fabc83f4..bd4abc7c6 100644 --- a/scss/_modal.scss +++ b/scss/_modal.scss @@ -50,11 +50,20 @@ } } +.modal-dialog-centered { + display: flex; + align-items: center; + height: 100%; + margin-top: 0; + margin-bottom: 0; +} + // Actual modal .modal-content { position: relative; display: flex; flex-direction: column; + width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog` // counteract the pointer-events: none; in the .modal-dialog pointer-events: auto; background-color: $modal-content-bg; @@ -144,11 +153,17 @@ margin: $modal-dialog-margin-y-sm-up auto; } + .modal-dialog-centered { + margin-top: 0; + margin-bottom: 0; + } + .modal-content { @include box-shadow($modal-content-box-shadow-sm-up); } .modal-sm { max-width: $modal-sm; } + } @include media-breakpoint-up(lg) { diff --git a/scss/mixins/_caret.scss b/scss/mixins/_caret.scss index daab9d03c..40478e492 100644 --- a/scss/mixins/_caret.scss +++ b/scss/mixins/_caret.scss @@ -12,6 +12,18 @@ border-left: $caret-width solid transparent; } +@mixin caret-right { + border-top: $caret-width solid transparent; + border-bottom: $caret-width solid transparent; + border-left: $caret-width solid; +} + +@mixin caret-left { + border-top: $caret-width solid transparent; + border-right: $caret-width solid; + border-bottom: $caret-width solid transparent; +} + @mixin caret($direction: down) { @if $enable-caret { &::after { @@ -25,6 +37,24 @@ @include caret-down; } @else if $direction == up { @include caret-up; + } @else if $direction == right { + @include caret-right; + } + } + + @if $direction == left { + &::after { + display: none; + } + + &::before { + display: inline-block; + width: 0; + height: 0; + margin-right: $caret-width * .85; + vertical-align: $caret-width * .85; + content: ""; + @include caret-left; } } |
