From da72c32eff5d3ed9522bce70575a82e1d62d2fbb Mon Sep 17 00:00:00 2001 From: Timmy Willison <4timmywil@gmail.com> Date: Tue, 29 Oct 2019 15:06:38 -0400 Subject: [PATCH] feat(exclude): add exclude option; change clickableClass to excludeClass Close gh-411 --- README.md | 4 +- demo/Demo.tsx | 7 +++- demo/examples/Exclude.tsx | 78 +++++++++++++++++++++++++++++++++++++++ demo/index.tsx | 2 + src/panzoom.ts | 11 ++++-- src/types.ts | 13 +++++-- 6 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 demo/examples/Exclude.tsx diff --git a/README.md b/README.md index c9788504..15fb2dc6 100644 --- a/README.md +++ b/README.md @@ -106,8 +106,8 @@ Object elements can eat up events, making it so they never reach Panzoom. To fix 3\. My links aren't working! How do I enable an anchor within a panzoom element? -Add class `options.clickableClass` (default is `"clickable"`) to whatever element you want to be clickable. Panzoom will check for this class before handling the event. -Alternatively, call `event.stopImmediatePropagation()` in an event handler on the clickable element. +Add class `options.excludeClass` (default is `"panzoom-exclude"`) to whatever element you want to be clickable. Panzoom will check for this class before handling the event. +Alternatively, add a reference to the element to the `exclude` option, or call `event.stopImmediatePropagation()` in an event handler on the clickable element. --- diff --git a/demo/Demo.tsx b/demo/Demo.tsx index 3b22e2e5..069d17d9 100644 --- a/demo/Demo.tsx +++ b/demo/Demo.tsx @@ -9,7 +9,12 @@ interface Props { export default function Demo({ title, code, children }: Props) { return (
-

{title}

+ +

{title}

+
{code}
{children}
diff --git a/demo/examples/Exclude.tsx b/demo/examples/Exclude.tsx new file mode 100644 index 00000000..e54ebb24 --- /dev/null +++ b/demo/examples/Exclude.tsx @@ -0,0 +1,78 @@ +import React, { CSSProperties, useEffect, useRef } from 'react' +import Panzoom from '../../src/panzoom' +import Code from '../Code' +import Demo from '../Demo' + +const code = ( + {`\ +Panzoom(elem, { + // Can add an element reference + exclude: [document.getElementById('link')], + // ...or set a class on the element + excludeClass: 'custom-excluded-class' +})`} +) + +const ANCHOR_TOP = 20 + +const anchorStyle: CSSProperties = { + position: 'absolute', + top: ANCHOR_TOP, + left: 0, + right: 0, + padding: '10px 0', + textAlign: 'center', + fontSize: 20, + color: '#baffc1', + backgroundColor: 'rgba(0, 0, 0, 0.8)', + borderWidth: 1, + borderColor: '#dd33aa' +} + +const lastAnchorStyle = { + ...anchorStyle, + top: ANCHOR_TOP + 50 +} + +export default function Exclude() { + const elem = useRef(null) + const elemTwo = useRef(null) + useEffect(() => { + Panzoom(elem.current, { + exclude: [document.getElementById('link')], + excludeClass: 'custom-excluded-class' + }) + Panzoom(elemTwo.current) + }, []) + return ( + +
+
+ + + This link will handle the click + + This one will pass through the event. +
+ This is a Panzoom element within another Panzoom element. This works by default. +
+
+
+
+ ) +} diff --git a/demo/index.tsx b/demo/index.tsx index 3bfc3ede..e3152e72 100644 --- a/demo/index.tsx +++ b/demo/index.tsx @@ -4,6 +4,7 @@ import './demo.css' import ContainInside from './examples/ContainInside' import ContainOutside from './examples/ContainOutside' import DisabledYAxis from './examples/DisabledYAxis' +import Exclude from './examples/Exclude' import Focal from './examples/Focal' import Standard from './examples/Standard' import SVG from './examples/SVG' @@ -25,6 +26,7 @@ function Demos() { + diff --git a/src/panzoom.ts b/src/panzoom.ts index 669bbaa0..6c686880 100644 --- a/src/panzoom.ts +++ b/src/panzoom.ts @@ -18,7 +18,6 @@ import { PanOptions, PanzoomEvent, PanzoomObject, PanzoomOptions, ZoomOptions } const defaultOptions: PanzoomOptions = { animate: false, - clickableClass: 'clickable', cursor: 'move', disablePan: false, disableZoom: false, @@ -26,6 +25,8 @@ const defaultOptions: PanzoomOptions = { disableYAxis: false, duration: 200, easing: 'ease-in-out', + exclude: [], + excludeClass: 'panzoom-exclude', maxScale: 4, minScale: 0.125, panOnlyWhenZoomed: false, @@ -334,8 +335,12 @@ function Panzoom(elem: HTMLElement | SVGElement, options?: PanzoomOptions): Panz const pointers: PointerEvent[] = [] function handleDown(event: PointerEvent) { - // Don't handle this event if the target is a clickable - if (event.target && (event.target as Element).classList.contains(options.clickableClass)) { + // Don't handle this event if the target is excluded + if ( + event.target && + ((event.target as Element).classList.contains(options.excludeClass) || + options.exclude.indexOf(event.target as Element) > -1) + ) { return } addPointer(pointers, event) diff --git a/src/types.ts b/src/types.ts index 021097ee..8cab2073 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,10 +12,17 @@ interface MiscOptions { /** Whether to animate transitions */ animate?: boolean /** - * Add this class to any element within the panzoom element - * that you want to be clickable and not initiate the drag + * Add elements to this array that should be excluded + * from Panzoom handling. + * e.g. links and buttons that should not propagate the click event. */ - clickableClass?: string + exclude?: Element[] + /** + * Add this class to any element within the Panzoom element + * that you want to exclude from Panzoom handling. + * e.g. links and buttons that should not propagate the click event. + */ + excludeClass?: string /** Duration of the transition (ms) */ duration?: number /** CSS Easing used for transitions */