diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json index da47da480145..36404b38cfda 100644 --- a/.bundlewatch.config.json +++ b/.bundlewatch.config.json @@ -34,7 +34,7 @@ }, { "path": "./dist/js/bootstrap.bundle.js", - "maxSize": "41 kB" + "maxSize": "42 kB" }, { "path": "./dist/js/bootstrap.bundle.min.js", diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 878a5a9a21d9..7221debfc29f 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -86,7 +86,7 @@ const DefaultType = { boundary: '(string|element)', reference: '(string|element|object)', display: 'string', - popperConfig: '(null|object)' + popperConfig: '(null|object|function)' } /** @@ -322,7 +322,7 @@ class Dropdown extends BaseComponent { } _getPopperConfig() { - const popperConfig = { + const defaultBsPopperConfig = { placement: this._getPlacement(), modifiers: [{ name: 'preventOverflow', @@ -341,15 +341,15 @@ class Dropdown extends BaseComponent { // Disable Popper if we have a static display if (this._config.display === 'static') { - popperConfig.modifiers = [{ + defaultBsPopperConfig.modifiers = [{ name: 'applyStyles', enabled: false }] } return { - ...popperConfig, - ...this._config.popperConfig + ...defaultBsPopperConfig, + ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig) } } diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 11209625cd18..42da4c93858e 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -58,7 +58,7 @@ const DefaultType = { sanitize: 'boolean', sanitizeFn: '(null|function)', allowList: 'object', - popperConfig: '(null|object)' + popperConfig: '(null|object|function)' } const AttachmentMap = { @@ -490,7 +490,7 @@ class Tooltip extends BaseComponent { } _getPopperConfig(attachment) { - const defaultBsConfig = { + const defaultBsPopperConfig = { placement: attachment, modifiers: [ { @@ -533,8 +533,8 @@ class Tooltip extends BaseComponent { } return { - ...defaultBsConfig, - ...this.config.popperConfig + ...defaultBsPopperConfig, + ...(typeof this.config.popperConfig === 'function' ? this.config.popperConfig(defaultBsPopperConfig) : this.config.popperConfig) } } diff --git a/js/tests/unit/dropdown.spec.js b/js/tests/unit/dropdown.spec.js index 01d599ceb6d4..e97ce7717ce6 100644 --- a/js/tests/unit/dropdown.spec.js +++ b/js/tests/unit/dropdown.spec.js @@ -123,6 +123,28 @@ describe('Dropdown', () => { expect(popperConfig.placement).toEqual('left') }) + + it('should allow to pass config to Popper with `popperConfig` as a function', () => { + fixtureEl.innerHTML = [ + '' + ].join('') + + const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]') + const getPopperConfig = jasmine.createSpy('getPopperConfig').and.returnValue({ placement: 'left' }) + const dropdown = new Dropdown(btnDropdown, { + popperConfig: getPopperConfig + }) + + const popperConfig = dropdown._getPopperConfig() + + expect(getPopperConfig).toHaveBeenCalled() + expect(popperConfig.placement).toEqual('left') + }) }) describe('toggle', () => { diff --git a/js/tests/unit/tooltip.spec.js b/js/tests/unit/tooltip.spec.js index 38af0235ba29..e1d037154661 100644 --- a/js/tests/unit/tooltip.spec.js +++ b/js/tests/unit/tooltip.spec.js @@ -156,6 +156,21 @@ describe('Tooltip', () => { expect(popperConfig.placement).toEqual('left') }) + + it('should allow to pass config to Popper with `popperConfig` as a function', () => { + fixtureEl.innerHTML = '' + + const tooltipEl = fixtureEl.querySelector('a') + const getPopperConfig = jasmine.createSpy('getPopperConfig').and.returnValue({ placement: 'left' }) + const tooltip = new Tooltip(tooltipEl, { + popperConfig: getPopperConfig + }) + + const popperConfig = tooltip._getPopperConfig('top') + + expect(getPopperConfig).toHaveBeenCalled() + expect(popperConfig.placement).toEqual('left') + }) }) describe('enable', () => { diff --git a/site/content/docs/5.0/components/dropdowns.md b/site/content/docs/5.0/components/dropdowns.md index d5efd3adbc1c..24353f0f4dd9 100644 --- a/site/content/docs/5.0/components/dropdowns.md +++ b/site/content/docs/5.0/components/dropdowns.md @@ -993,13 +993,28 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap popperConfig - null | object + null | object | function null - To change Bootstrap's default Popper config, see Popper's configuration + +

To change Bootstrap's default Popper config, see Popper's configuration.

+

When a function is used to create the Popper configuration, it's called with an object that contains the Bootstrap's default Popper configuration. It helps you use and merge the default with your own configuration. The function must return a configuration object for Popper.

+ +#### Using function with `popperConfig` + +```js +var dropdown = new bootstrap.Dropdown(element, { + popperConfig: function (defaultBsPopperConfig) { + // var newPopperConfig = {...} + // use defaultBsPopperConfig if needed... + // return newPopperConfig + } +}) +``` + ### Methods diff --git a/site/content/docs/5.0/components/popovers.md b/site/content/docs/5.0/components/popovers.md index 56616fd0cd14..8a2efa0a2a83 100644 --- a/site/content/docs/5.0/components/popovers.md +++ b/site/content/docs/5.0/components/popovers.md @@ -279,9 +279,12 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt - + - +
popperConfignull | objectnull | object | function nullTo change Bootstrap's default Popper config, see Popper's configuration +

To change Bootstrap's default Popper config, see Popper's configuration.

+

When a function is used to create the Popper configuration, it's called with an object that contains the Bootstrap's default Popper configuration. It helps you use and merge the default with your own configuration. The function must return a configuration object for Popper.

+
@@ -292,6 +295,18 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt Options for individual popovers can alternatively be specified through the use of data attributes, as explained above. {{< /callout >}} +#### Using function with `popperConfig` + +```js +var popover = new bootstrap.Popover(element, { + popperConfig: function (defaultBsPopperConfig) { + // var newPopperConfig = {...} + // use defaultBsPopperConfig if needed... + // return newPopperConfig + } +}) +``` + ### Methods {{< callout danger >}} diff --git a/site/content/docs/5.0/components/tooltips.md b/site/content/docs/5.0/components/tooltips.md index 9a5dd93931c4..ee6d06e9e9ba 100644 --- a/site/content/docs/5.0/components/tooltips.md +++ b/site/content/docs/5.0/components/tooltips.md @@ -304,9 +304,12 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt popperConfig - null | object + null | object | function null - To change Bootstrap's default Popper config, see Popper's configuration + +

To change Bootstrap's default Popper config, see Popper's configuration.

+

When a function is used to create the Popper configuration, it's called with an object that contains the Bootstrap's default Popper configuration. It helps you use and merge the default with your own configuration. The function must return a configuration object for Popper.

+ @@ -317,6 +320,18 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt Options for individual tooltips can alternatively be specified through the use of data attributes, as explained above. {{< /callout >}} +#### Using function with `popperConfig` + +```js +var tooltip = new bootstrap.Tooltip(element, { + popperConfig: function (defaultBsPopperConfig) { + // var newPopperConfig = {...} + // use defaultBsPopperConfig if needed... + // return newPopperConfig + } +}) +``` + ### Methods {{< callout danger >}} diff --git a/site/content/docs/5.0/migration.md b/site/content/docs/5.0/migration.md index 6e4839348e87..99a9c9e38ce5 100644 --- a/site/content/docs/5.0/migration.md +++ b/site/content/docs/5.0/migration.md @@ -24,6 +24,7 @@ toc: true - The default value for the `fallbackPlacements` is changed to `['top', 'right', 'bottom', 'left']` for better placement of popper elements. - All the events for the dropdown are now triggered on the dropdown toggle button and then bubbled up to the parent element. - Dropdown menus now have a `data-bs-popper="static"` attribute set when the positioning of the dropdown is static and `data-bs-popper="none"` when dropdown is in the navbar. This is added by our JavaScript and helps us use custom position styles without interfering with Popper's positioning. +- `popperConfig` can be passed as a function that accepts the Bootstrap's default Popper config as an argument, so that you can merge this default configuration in your way. ## v5.0.0-beta1