diff --git a/apps/docs/src/content/guides/changelog.mdx b/apps/docs/src/content/guides/changelog.mdx index 70abe69..c89fd7c 100644 --- a/apps/docs/src/content/guides/changelog.mdx +++ b/apps/docs/src/content/guides/changelog.mdx @@ -15,6 +15,9 @@ ships, these entries move under a versioned heading. - `closeBtnLabel` (driver and step level) to set the close button's `aria-label`, for translated tours. Defaults to `Close`. ([#623](https://github.com/nilbuild/driver.js/issues/623)) +- `overlayClickBehavior: "none"` to ignore overlay clicks while Escape and the + close button still close the tour. + ([#435](https://github.com/nilbuild/driver.js/issues/435)) ### Changed diff --git a/apps/docs/src/content/guides/configuration.mdx b/apps/docs/src/content/guides/configuration.mdx index 2bf70d9..c85e9d6 100644 --- a/apps/docs/src/content/guides/configuration.mdx +++ b/apps/docs/src/content/guides/configuration.mdx @@ -44,10 +44,12 @@ type Config = { // Opacity of the backdrop. (default: 0.5) overlayOpacity?: number; // What to do when the overlay backdrop is clicked. - // Possible options are 'close', 'nextStep', or a custom function. (default: 'close') + // Possible options are 'close', 'nextStep', 'none', or a custom function. (default: 'close') + // Use 'none' to ignore overlay clicks while Escape and the close button still work. overlayClickBehavior?: | "close" | "nextStep" + | "none" | (( element?: Element, step: DriveStep, diff --git a/packages/driver/src/context.ts b/packages/driver/src/context.ts index 7c7ca5c..b893cba 100644 --- a/packages/driver/src/context.ts +++ b/packages/driver/src/context.ts @@ -24,7 +24,7 @@ export type Config = { smoothScroll?: boolean; allowClose?: boolean; allowScroll?: boolean; - overlayClickBehavior?: "close" | "nextStep" | DriverHook; + overlayClickBehavior?: "close" | "nextStep" | "none" | DriverHook; stagePadding?: number; stageRadius?: number; diff --git a/packages/driver/tests/interactions.test.ts b/packages/driver/tests/interactions.test.ts index baf7ba7..c560e88 100644 --- a/packages/driver/tests/interactions.test.ts +++ b/packages/driver/tests/interactions.test.ts @@ -191,6 +191,27 @@ describe("overlay click behaviour", () => { expect(d.isActive()).toBe(false); }); + it("ignores overlay clicks when behaviour is 'none'", async () => { + const d = createDriver({ animate: false, overlayClickBehavior: "none", steps: SAMPLE_STEPS }); + d.drive(); + await nextFrame(); + + clickOverlay(); + + expect(d.isActive()).toBe(true); + expect(d.getActiveIndex()).toBe(0); + }); + + it("still closes with the close button when behaviour is 'none'", async () => { + const d = createDriver({ animate: false, overlayClickBehavior: "none", steps: SAMPLE_STEPS }); + d.drive(); + await nextFrame(); + + navButton("close")?.click(); + + expect(d.isActive()).toBe(false); + }); + it("runs a custom overlayClickBehavior with the active element, step and driver", async () => { const overlayClickBehavior = vi.fn(); const d = createDriver({ animate: false, overlayClickBehavior, steps: SAMPLE_STEPS }); diff --git a/packages/driver/tests/keyboard.test.ts b/packages/driver/tests/keyboard.test.ts index 2a0832c..f00cf8d 100644 --- a/packages/driver/tests/keyboard.test.ts +++ b/packages/driver/tests/keyboard.test.ts @@ -20,6 +20,14 @@ describe("keyboard control", () => { expect(d.isActive()).toBe(true); }); + it("still closes with Escape when overlayClickBehavior is 'none'", () => { + const d = createDriver({ animate: false, overlayClickBehavior: "none", steps: SAMPLE_STEPS }); + d.drive(); + pressKey("Escape"); + + expect(d.isActive()).toBe(false); + }); + it("navigates with the arrow keys", async () => { const d = createDriver({ animate: false, steps: SAMPLE_STEPS }); d.drive();