diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json index 525d29f6a0..8be4f8c7ab 100644 --- a/.bundlewatch.config.json +++ b/.bundlewatch.config.json @@ -10,7 +10,7 @@ }, { "path": "./dist/css/bootstrap-reboot.css", - "maxSize": "2 kB" + "maxSize": "2.25 kB" }, { "path": "./dist/css/bootstrap-reboot.min.css", @@ -54,7 +54,7 @@ }, { "path": "./dist/js/bootstrap.min.js", - "maxSize": "15.5 kB" + "maxSize": "15.75 kB" } ], "ci": { diff --git a/js/src/carousel.js b/js/src/carousel.js index 9c6fb53ee0..d8ad3a1354 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -79,8 +79,8 @@ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` const CLASS_NAME_CAROUSEL = 'carousel' const CLASS_NAME_ACTIVE = 'active' const CLASS_NAME_SLIDE = 'slide' -const CLASS_NAME_RIGHT = 'carousel-item-right' -const CLASS_NAME_LEFT = 'carousel-item-left' +const CLASS_NAME_END = 'carousel-item-end' +const CLASS_NAME_START = 'carousel-item-start' const CLASS_NAME_NEXT = 'carousel-item-next' const CLASS_NAME_PREV = 'carousel-item-prev' const CLASS_NAME_POINTER_EVENT = 'pointer-event' @@ -442,11 +442,11 @@ class Carousel extends BaseComponent { let eventDirectionName if (direction === DIRECTION_NEXT) { - directionalClassName = CLASS_NAME_LEFT + directionalClassName = CLASS_NAME_START orderClassName = CLASS_NAME_NEXT eventDirectionName = DIRECTION_LEFT } else { - directionalClassName = CLASS_NAME_RIGHT + directionalClassName = CLASS_NAME_END orderClassName = CLASS_NAME_PREV eventDirectionName = DIRECTION_RIGHT } diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 7b3bf5b4ec..0ac108ab81 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -11,6 +11,7 @@ import { getElementFromSelector, isElement, isVisible, + isRTL, noop, typeCheckConfig } from './util/index' @@ -53,9 +54,9 @@ const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}` const CLASS_NAME_DISABLED = 'disabled' const CLASS_NAME_SHOW = 'show' const CLASS_NAME_DROPUP = 'dropup' -const CLASS_NAME_DROPRIGHT = 'dropright' -const CLASS_NAME_DROPLEFT = 'dropleft' -const CLASS_NAME_MENURIGHT = 'dropdown-menu-right' +const CLASS_NAME_DROPEND = 'dropend' +const CLASS_NAME_DROPSTART = 'dropstart' +const CLASS_NAME_MENUEND = 'dropdown-menu-end' const CLASS_NAME_NAVBAR = 'navbar' const CLASS_NAME_POSITION_STATIC = 'position-static' @@ -65,12 +66,12 @@ const SELECTOR_MENU = '.dropdown-menu' const SELECTOR_NAVBAR_NAV = '.navbar-nav' const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' -const PLACEMENT_TOP = 'top-start' -const PLACEMENT_TOPEND = 'top-end' -const PLACEMENT_BOTTOM = 'bottom-start' -const PLACEMENT_BOTTOMEND = 'bottom-end' -const PLACEMENT_RIGHT = 'right-start' -const PLACEMENT_LEFT = 'left-start' +const PLACEMENT_TOP = isRTL ? 'top-end' : 'top-start' +const PLACEMENT_TOPEND = isRTL ? 'top-start' : 'top-end' +const PLACEMENT_BOTTOM = isRTL ? 'bottom-end' : 'bottom-start' +const PLACEMENT_BOTTOMEND = isRTL ? 'bottom-start' : 'bottom-end' +const PLACEMENT_RIGHT = isRTL ? 'left-start' : 'right-start' +const PLACEMENT_LEFT = isRTL ? 'right-start' : 'left-start' const Default = { offset: 0, @@ -277,14 +278,14 @@ class Dropdown extends BaseComponent { // Handle dropup if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { - placement = this._menu.classList.contains(CLASS_NAME_MENURIGHT) ? + placement = this._menu.classList.contains(CLASS_NAME_MENUEND) ? PLACEMENT_TOPEND : PLACEMENT_TOP - } else if (parentDropdown.classList.contains(CLASS_NAME_DROPRIGHT)) { + } else if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { placement = PLACEMENT_RIGHT - } else if (parentDropdown.classList.contains(CLASS_NAME_DROPLEFT)) { + } else if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { placement = PLACEMENT_LEFT - } else if (this._menu.classList.contains(CLASS_NAME_MENURIGHT)) { + } else if (this._menu.classList.contains(CLASS_NAME_MENUEND)) { placement = PLACEMENT_BOTTOMEND } diff --git a/js/src/modal.js b/js/src/modal.js index a9cf8ae6cf..94bf95f8ad 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -13,6 +13,7 @@ import { getElementFromSelector, getTransitionDurationFromElement, isVisible, + isRTL, reflow, typeCheckConfig } from './util/index' @@ -435,11 +436,11 @@ class Modal extends BaseComponent { const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight - if (!this._isBodyOverflowing && isModalOverflowing) { + if ((!this._isBodyOverflowing && isModalOverflowing && !isRTL) || (this._isBodyOverflowing && !isModalOverflowing && isRTL)) { this._element.style.paddingLeft = `${this._scrollbarWidth}px` } - if (this._isBodyOverflowing && !isModalOverflowing) { + if ((this._isBodyOverflowing && !isModalOverflowing && !isRTL) || (!this._isBodyOverflowing && isModalOverflowing && isRTL)) { this._element.style.paddingRight = `${this._scrollbarWidth}px` } } diff --git a/js/src/popover.js b/js/src/popover.js index 66dcb47b90..d8bd92eefb 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -115,7 +115,7 @@ class Popover extends Tooltip { // Private _addAttachmentClass(attachment) { - this.getTipElement().classList.add(`${CLASS_PREFIX}-${attachment}`) + this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`) } _getContent() { diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 25599bb42f..17148ed9a6 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -14,6 +14,7 @@ import { getTransitionDurationFromElement, getUID, isElement, + isRTL, noop, typeCheckConfig } from './util/index' @@ -64,9 +65,9 @@ const DefaultType = { const AttachmentMap = { AUTO: 'auto', TOP: 'top', - RIGHT: 'right', + RIGHT: isRTL ? 'left' : 'right', BOTTOM: 'bottom', - LEFT: 'left' + LEFT: isRTL ? 'right' : 'left' } const Default = { @@ -453,6 +454,18 @@ class Tooltip extends BaseComponent { return title } + updateAttachment(attachment) { + if (attachment === 'right') { + return 'end' + } + + if (attachment === 'left') { + return 'start' + } + + return attachment + } + // Private _getPopperConfig(attachment) { @@ -485,7 +498,7 @@ class Tooltip extends BaseComponent { } _addAttachmentClass(attachment) { - this.getTipElement().classList.add(`${CLASS_PREFIX}-${attachment}`) + this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`) } _getOffset() { diff --git a/js/src/util/index.js b/js/src/util/index.js index 874827b168..96cadc65bc 100644 --- a/js/src/util/index.js +++ b/js/src/util/index.js @@ -186,6 +186,8 @@ const onDOMContentLoaded = callback => { } } +const isRTL = document.documentElement.dir === 'rtl' + export { TRANSITION_END, getUID, @@ -201,5 +203,6 @@ export { noop, reflow, getjQuery, - onDOMContentLoaded + onDOMContentLoaded, + isRTL } diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index 145763d20f..f6a5feb1b9 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -227,7 +227,7 @@ describe('Dropdown', () => { fixtureEl.innerHTML = [ '