Skip to content

Commit

Permalink
Add dropright and dropleft (right and left placements for our dropdow…
Browse files Browse the repository at this point in the history
…n) (#23860)

* Add dropright (right placement for our dropdown)

* Add dropleft

* moves drop left arrow to the left
  • Loading branch information
Johann-S authored and mdo committed Oct 29, 2017
1 parent b1623c4 commit e454c8e
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 2 deletions.
126 changes: 126 additions & 0 deletions docs/4.0/components/dropdowns.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 12 additions & 2 deletions js/src/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ const Dropdown = (($) => {
DISABLED : 'disabled',
SHOW : 'show',
DROPUP : 'dropup',
DROPRIGHT : 'dropright',
DROPLEFT : 'dropleft',
MENURIGHT : 'dropdown-menu-right',
MENULEFT : 'dropdown-menu-left'
}
Expand All @@ -71,7 +73,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 = {
Expand Down Expand Up @@ -227,14 +233,18 @@ const Dropdown = (($) => {

_getPlacement() {
const $parentDropdown = $(this._element).parent()
let placement = AttachmentMap.BOTTOM
let placement = AttachmentMap.BOTTOM

// Handle dropup
if ($parentDropdown.hasClass(ClassName.DROPUP)) {
placement = AttachmentMap.TOP
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
}
Expand Down
48 changes: 48 additions & 0 deletions js/tests/visual/dropdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ <h1>Dropdown <small>Bootstrap Visual Test</small></h1>
</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>
Expand All @@ -114,8 +115,55 @@ <h1>Dropdown <small>Bootstrap Visual Test</small></h1>
</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>
Expand Down
28 changes: 28 additions & 0 deletions scss/_dropdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
30 changes: 30 additions & 0 deletions scss/mixins/_caret.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
}

Expand Down

0 comments on commit e454c8e

Please sign in to comment.