diff --git a/shepherd.js/src/step.ts b/shepherd.js/src/step.ts index f7d1921c1..6599df8e4 100644 --- a/shepherd.js/src/step.ts +++ b/shepherd.js/src/step.ts @@ -68,9 +68,9 @@ export interface StepOptions { advanceOn?: StepOptionsAdvanceOn; /** - * Whether to display the arrow for the tooltip or not + * Whether to display the arrow for the tooltip or not, or options for the arrow. */ - arrow?: boolean; + arrow?: boolean | StepOptionsArrow; /** * A function that returns a promise. @@ -221,6 +221,14 @@ export type PopperPlacement = | 'left-start' | 'left-end'; +export interface StepOptionsArrow { + /* + * The padding from the edge for the arrow. + * Not used if this is not a -start or -end placement. + */ + padding?: number +} + export interface StepOptionsAttachTo { element?: | HTMLElement diff --git a/shepherd.js/src/utils/floating-ui.ts b/shepherd.js/src/utils/floating-ui.ts index 97915ffef..393263999 100644 --- a/shepherd.js/src/utils/floating-ui.ts +++ b/shepherd.js/src/utils/floating-ui.ts @@ -211,8 +211,13 @@ export function getFloatingUIOptions( ); if (arrowEl) { + const arrowOptions = + typeof step.options.arrow === "object" + ? step.options.arrow + : { padding: 4 }; + options.middleware.push( - arrow({ element: arrowEl, padding: hasEdgeAlignment ? 4 : 0 }) + arrow({ element: arrowEl, padding: hasEdgeAlignment ? arrowOptions.padding : 0 }) ); } diff --git a/test/unit/components/shepherd-element.spec.js b/test/unit/components/shepherd-element.spec.js index 45315c20c..0c01ca589 100644 --- a/test/unit/components/shepherd-element.spec.js +++ b/test/unit/components/shepherd-element.spec.js @@ -44,6 +44,44 @@ describe('components/ShepherdElement', () => { container.querySelectorAll('.shepherd-element .shepherd-arrow').length ).toBe(0); }); + + it('arrow: object with padding shows arrow', async () => { + const testElement = document.createElement('div'); + const tour = new Tour(); + const step = new Step(tour, { + arrow: { padding: 10 }, + attachTo: { element: testElement, on: 'top' } + }); + + const { container } = render(ShepherdElement, { + props: { + step + } + }); + + expect( + container.querySelectorAll('.shepherd-element .shepherd-arrow').length + ).toBe(1); + }); + + it('arrow: empty object shows arrow', async () => { + const testElement = document.createElement('div'); + const tour = new Tour(); + const step = new Step(tour, { + arrow: {}, + attachTo: { element: testElement, on: 'top' } + }); + + const { container } = render(ShepherdElement, { + props: { + step + } + }); + + expect( + container.querySelectorAll('.shepherd-element .shepherd-arrow').length + ).toBe(1); + }); }); describe('handleKeyDown', () => {