UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

148 lines (142 loc) 4.42 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import { createPopper } from '@popperjs/core'; import { bind } from 'bind-event-listener'; const startingOffset = { name: 'offset', options: { offset: [0, 4] } }; const endingOffset = { name: 'offset', options: { offset: [0, 8] } }; /** * A tooltip component similar to "@atlaskit/tooltip" but built for vanilla scenarios * * Uses Popover API for accessibility + stacking context: https://developer.mozilla.org/en-US/docs/Web/API/Popover_API * Uses popperJS for positioning */ export class VanillaTooltip { constructor(button, content, /** * Id associated to the tooltip - must be unique. */ id, /** * Class Name – used for styling. */ className, timeout = 300) { _defineProperty(this, "listeners", []); _defineProperty(this, "shouldHidePopover", false); _defineProperty(this, "isDisplayed", false); this.button = button; this.timeout = timeout; const tooltip = document.createElement('span'); tooltip.role = 'tooltip'; tooltip.popover = 'hint'; tooltip.className = className; tooltip.id = id; tooltip.textContent = content; this.tooltip = tooltip; // Button preparation button.appendChild(tooltip); // Prepare the button to have the popover target and accessibility properties button.setAttribute('popovertarget', tooltip.id); button.setAttribute('aria-describedby', tooltip.id); const showEvents = ['mouseenter', 'focus']; const hideEvents = ['mouseleave', 'blur']; showEvents.forEach(event => { this.listeners.push(bind(button, { type: event, listener: () => this.show() })); }); hideEvents.forEach(event => { this.listeners.push(bind(button, { type: event, listener: () => this.hide() })); }); this.listeners.push(bind(window, { type: 'keydown', listener: e => { if (e.key === 'Escape') { this.hide(true); } } })); // Hide the tooltip if the hide transition has completed this.tooltip.ontransitionend = () => { if (this.shouldHidePopover) { this.tooltip.hidePopover(); } }; } createPopperInstance() { this.popperInstance = createPopper(this.button, this.tooltip, { placement: 'top', modifiers: [startingOffset] }); } destroy() { var _this$popperInstance; (_this$popperInstance = this.popperInstance) === null || _this$popperInstance === void 0 ? void 0 : _this$popperInstance.destroy(); this.listeners.forEach(listener => { listener(); }); } hide(immediate = false) { clearTimeout(this.currentTimeoutId); this.shouldHidePopover = true; // Disable the event listeners this.currentTimeoutId = setTimeout(() => { var _this$popperInstance2; (_this$popperInstance2 = this.popperInstance) === null || _this$popperInstance2 === void 0 ? void 0 : _this$popperInstance2.setOptions(options => ({ ...options, modifiers: [startingOffset, { name: 'eventListeners', enabled: false }] })); this.tooltip.style.opacity = '0'; this.isDisplayed = false; // If transition animations are disabled immediately hide the popover if (this.tooltip.style.transition === 'none') { this.tooltip.hidePopover(); } }, immediate ? 0 : this.timeout); } show() { if (this.isDisplayed) { return; } clearTimeout(this.currentTimeoutId); this.shouldHidePopover = false; // Make the tooltip visible - but hide until this.tooltip.style.visibility = 'hidden'; this.tooltip.showPopover(); // Update its position if (!this.popperInstance) { this.createPopperInstance(); } else { this.popperInstance.update(); } // Enable the event listeners this.currentTimeoutId = setTimeout(() => { var _this$popperInstance3; this.tooltip.style.opacity = '1'; this.tooltip.style.visibility = 'visible'; (_this$popperInstance3 = this.popperInstance) === null || _this$popperInstance3 === void 0 ? void 0 : _this$popperInstance3.setOptions(options => ({ ...options, modifiers: [endingOffset, { name: 'eventListeners', enabled: true }] })); this.isDisplayed = true; }, this.timeout); } }