const CLASS_NAME_DROPUP = 'dropup'
const CLASS_NAME_DROPEND = 'dropend'
const CLASS_NAME_DROPSTART = 'dropstart'
-const CLASS_NAME_MENUEND = 'dropdown-menu-end'
const CLASS_NAME_NAVBAR = 'navbar'
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]'
_getPlacement() {
const parentDropdown = this._element.parentNode
- let placement = PLACEMENT_BOTTOM
- // Handle dropup
+ if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
+ return PLACEMENT_RIGHT
+ }
+
+ if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
+ return PLACEMENT_LEFT
+ }
+
+ // We need to trim the value because custom properties can also include spaces
+ const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'
+
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
- placement = this._menu.classList.contains(CLASS_NAME_MENUEND) ?
- PLACEMENT_TOPEND :
- PLACEMENT_TOP
- } else if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
- placement = PLACEMENT_RIGHT
- } else if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
- placement = PLACEMENT_LEFT
- } else if (this._menu.classList.contains(CLASS_NAME_MENUEND)) {
- placement = PLACEMENT_BOTTOMEND
- }
-
- return placement
+ return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP
+ }
+
+ return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM
}
_detectNavbar() {
border: $dropdown-border-width solid $dropdown-border-color;
@include border-radius($dropdown-border-radius);
@include box-shadow($dropdown-box-shadow);
+
+ // Reset positioning when positioned with Popper
+ &[style] {
+ right: auto;
+ }
}
// scss-docs-start responsive-breakpoints
+// We deliberately hardcode the `bs-` prefix because we check
+// this custom property in JS to determine Popper's positioning
+
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.dropdown-menu#{$infix}-start {
+ --bs-position: start;
right: auto #{"/* rtl:ignore */"};
left: 0 #{"/* rtl:ignore */"};
}
.dropdown-menu#{$infix}-end {
+ --bs-position: end;
right: 0 #{"/* rtl:ignore */"};
left: auto #{"/* rtl:ignore */"};
}
}
}
-// When Popper is enabled, reset the basic dropdown position
-// stylelint-disable-next-line no-duplicate-selectors
-.dropdown-menu {
- &[data-popper-placement^="top"],
- &[data-popper-placement^="right"],
- &[data-popper-placement^="bottom"],
- &[data-popper-placement^="left"] {
- right: auto;
- bottom: auto;
- left: auto;
- }
-}
-
// Dividers (basically an `<hr>`) within the dropdown
.dropdown-divider {