diff --git a/README.md b/README.md index b5b30246b..36a17e656 100644 --- a/README.md +++ b/README.md @@ -188,9 +188,15 @@ When the footnote content is being removed this option specifies how long after Default: `500` +### `dismissOnDocumentTouch` + +Determines whether touching the document will dimiss all active footnotes. When `false`, footnotes can be dismissed by touching the button again. + +Default: `true` + ### `dismissOnUnhover` -Determines whether footnotes that were presented when hovering on a footnote button are removed once the footnote button or footnote popover is un-hovered. +Determines whether footnotes that were presented when hovering on a footnote button are dismissed once the footnote button or footnote popover is un-hovered. Default: `false` @@ -202,7 +208,7 @@ Default: `'li'` ### `hoverDelay` -If `dismissOnUnhover` is true, this specifies the amount of time (in milliseconds) that must pass after the footnote button/content is un-hovered before the footnote is removed. +If `dismissOnUnhover` is true, this specifies the amount of time (in milliseconds) that must pass after the footnote button/content is un-hovered before the footnote is dismissed. Default: `250` diff --git a/src/dom/events.ts b/src/dom/events.ts index 3402bd1f9..83381ddef 100644 --- a/src/dom/events.ts +++ b/src/dom/events.ts @@ -12,17 +12,6 @@ const closestTarget = (event: Event, selector: string) => const getFootnoteId = (element: HTMLElement | null) => element?.dataset.footnoteId -const touchHandler = - (action: FootnoteAction, dismissAll: () => void) => (event: Event) => { - const element = closestTarget(event, SELECTOR_BUTTON) - const id = getFootnoteId(element) - if (id) { - action(id) - } else if (!closestTarget(event, SELECTOR_POPOVER)) { - dismissAll() - } - } - const hoverHandler = (action: FootnoteAction) => (event: Event) => { event.preventDefault() const element = closestTarget(event, SELECTOR_FOOTNOTE) @@ -32,12 +21,6 @@ const hoverHandler = (action: FootnoteAction) => (event: Event) => { } } -const escapeHandler = (fn: () => void) => (event: KeyboardEvent) => { - if (event.keyCode === 27 || event.key === 'Escape' || event.key === 'Esc') { - fn() - } -} - const onDocument = document.addEventListener const onWindow = window.addEventListener @@ -57,15 +40,28 @@ const delegate = ( } export function addListeners(useCases: UseCases): () => void { - const controller = new AbortController() - const { signal } = controller - const toggleOnTouch = touchHandler(useCases.toggle, useCases.documentTouch) - const dismissOnEscape = escapeHandler(useCases.dismissAll) + const toggleOnTouch = (event: Event) => { + const element = closestTarget(event, SELECTOR_BUTTON) + const id = getFootnoteId(element) + if (id) { + useCases.toggle(id) + } else if (!closestTarget(event, SELECTOR_POPOVER)) { + useCases.touchOutside() + } + } + const dismissOnEscape = (event: KeyboardEvent) => { + if (event.keyCode === 27 || event.key === 'Escape' || event.key === 'Esc') { + useCases.dismissAll() + } + } const throttledReposition = throttle(useCases.repositionAll, FRAME) const throttledResize = throttle(useCases.resizeAll, FRAME) const showOnHover = hoverHandler(useCases.hover) const hideOnHover = hoverHandler(useCases.unhover) + const controller = new AbortController() + const { signal } = controller + onDocument('touchend', toggleOnTouch, { signal }) onDocument('click', toggleOnTouch, { signal }) onDocument('keyup', dismissOnEscape, { signal }) diff --git a/src/use-cases.ts b/src/use-cases.ts index 72fa36abf..467a3c604 100644 --- a/src/use-cases.ts +++ b/src/use-cases.ts @@ -37,7 +37,7 @@ export type UseCases = Readonly<{ activate: DelayedFootnoteAction dismiss: DelayedFootnoteAction dismissAll: () => void - documentTouch: () => void + touchOutside: () => void hover: FootnoteAction repositionAll: () => void resizeAll: () => void @@ -93,7 +93,7 @@ export function createUseCases( dismissAll, - documentTouch: () => { + touchOutside: () => { if (settings.dismissOnDocumentTouch) { dismissAll() } diff --git a/test/options/dismissOnDocumentTouch.test.ts b/test/options/dismissOnDocumentTouch.test.ts index c1ea6a55c..402d8c100 100644 --- a/test/options/dismissOnDocumentTouch.test.ts +++ b/test/options/dismissOnDocumentTouch.test.ts @@ -11,7 +11,11 @@ import littlefoot from '../../src/littlefoot' test('do not dismiss footnote when clicking the document body', async () => { setDocumentBody('single.html') - littlefoot({ dismissOnDocumentTouch: false, activateDelay: 0, dismissDelay: 0 }) + littlefoot({ + dismissOnDocumentTouch: false, + activateDelay: 0, + dismissDelay: 0, + }) const button = getButton('1') fireEvent.click(button) @@ -26,7 +30,11 @@ test('do not dismiss footnote when clicking the document body', async () => { test('dismiss footnote when clicking the button again', async () => { setDocumentBody('single.html') - littlefoot({ dismissOnDocumentTouch: false, activateDelay: 0, dismissDelay: 0 }) + littlefoot({ + dismissOnDocumentTouch: false, + activateDelay: 0, + dismissDelay: 0, + }) const button = getButton('1') fireEvent.click(button) await waitToStopChanging(button) @@ -42,7 +50,11 @@ test('dismiss footnote when clicking the button again', async () => { test('disallow multiple activations', async () => { setDocumentBody('default.html') - littlefoot({ dismissOnDocumentTouch: false, activateDelay: 0, dismissDelay: 0 }) + littlefoot({ + dismissOnDocumentTouch: false, + activateDelay: 0, + dismissDelay: 0, + }) const one = getButton('1') fireEvent.click(one)