From 8e5258a142080cfed0436ae9635b7dccdaf06d28 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Mon, 12 Dec 2022 11:11:09 -0500 Subject: [PATCH] Fix centering steps with no attachTo.on --- src/js/utils/floating-ui.js | 52 ++++++++++++++++++++++++------------- test/unit/tour.spec.js | 7 +++-- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/js/utils/floating-ui.js b/src/js/utils/floating-ui.js index b303a1355..7d25a7d97 100644 --- a/src/js/utils/floating-ui.js +++ b/src/js/utils/floating-ui.js @@ -31,8 +31,9 @@ export function setupTooltip(step) { let target = attachToOptions.element; const floatingUIOptions = getFloatingUIOptions(attachToOptions, step); + const shouldCenter = shouldCenterStep(attachToOptions); - if (shouldCenterStep(attachToOptions)) { + if (shouldCenter) { target = document.body; const content = step.shepherdElementComponent.getElement(); content.classList.add('shepherd-centered'); @@ -45,7 +46,7 @@ export function setupTooltip(step) { return; } - setPosition(target, step, floatingUIOptions); + setPosition(target, step, floatingUIOptions, shouldCenter); }); step.target = attachToOptions.element; @@ -87,10 +88,10 @@ export function destroyTooltip(step) { * * @return {Promise<*>} */ -function setPosition(target, step, floatingUIOptions) { +function setPosition(target, step, floatingUIOptions, shouldCenter) { return ( computePosition(target, step.el, floatingUIOptions) - .then(floatingUIposition(step)) + .then(floatingUIposition(step, shouldCenter)) // Wait before forcing focus. .then( (step) => @@ -110,19 +111,29 @@ function setPosition(target, step, floatingUIOptions) { /** * * @param step + * @param shouldCenter * @return {function({x: *, y: *, placement: *, middlewareData: *}): Promise} */ -function floatingUIposition(step) { +function floatingUIposition(step, shouldCenter) { return ({ x, y, placement, middlewareData }) => { if (!step.el) { return step; } - Object.assign(step.el.style, { - position: 'absolute', - left: `${x}px`, - top: `${y}px` - }); + if (shouldCenter) { + Object.assign(step.el.style, { + position: 'fixed', + left: '50%', + top: '50%', + transform: 'translate(-50%, -50%)' + }); + } else { + Object.assign(step.el.style, { + position: 'absolute', + left: `${x}px`, + top: `${y}px` + }); + } step.el.dataset.popperPlacement = placement; @@ -167,22 +178,27 @@ function placeArrow(el, middlewareData) { export function getFloatingUIOptions(attachToOptions, step) { const options = { strategy: 'absolute', - middleware: [ + middleware: [] + }; + + const arrowEl = addArrow(step); + + const shouldCenter = shouldCenterStep(attachToOptions); + + if (!shouldCenter) { + options.middleware.push( flip(), // Replicate PopperJS default behavior. shift({ limiter: limitShift(), crossAxis: true }) - ] - }; + ); - const arrowEl = addArrow(step); - if (arrowEl) { - options.middleware.push(arrow({ element: arrowEl })); - } + if (arrowEl) { + options.middleware.push(arrow({ element: arrowEl })); + } - if (!shouldCenterStep(attachToOptions)) { options.placement = attachToOptions.on; } diff --git a/test/unit/tour.spec.js b/test/unit/tour.spec.js index 58ec7ed34..d66e6096f 100644 --- a/test/unit/tour.spec.js +++ b/test/unit/tour.spec.js @@ -441,7 +441,7 @@ describe('Tour | Top-Level Class', function() { instance.start(); const floatingUIOptions = setupTooltip(step); - expect(floatingUIOptions.middleware.length).toBe(3); + expect(floatingUIOptions.middleware.length).toBe(1); }); it('adds a step modifer to default modifiers', function() { @@ -458,7 +458,7 @@ describe('Tour | Top-Level Class', function() { instance.start(); const floatingUIOptions = setupTooltip(step); - expect(floatingUIOptions.middleware.length).toBe(4); + expect(floatingUIOptions.middleware.length).toBe(2); }); it('correctly changes modifiers when going from centered to attached', function() { @@ -488,10 +488,9 @@ describe('Tour | Top-Level Class', function() { const centeredOptions = setupTooltip(centeredStep); const centeredMiddlewareNames = centeredOptions.middleware.map(({name}) => name); - expect(centeredOptions.middleware.length).toBe(4); + expect(centeredOptions.middleware.length).toBe(2); expect(centeredMiddlewareNames.includes('offset')).toBe(true); expect(centeredMiddlewareNames.includes('foo')).toBe(true); - expect(centeredMiddlewareNames.includes('shift')).toBe(true); expect(centeredMiddlewareNames.includes('arrow')).toBe(false); instance.next();