UNPKG

@atlaskit/editor-plugin-mentions

Version:

Mentions plugin for @atlaskit/editor-core

193 lines (186 loc) 8.19 kB
/* disabledTooltipRenderer.tsx generated by @compiled/babel-plugin v0.39.1 */ "use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.disabledTooltipRenderer = void 0; require("./disabledTooltipRenderer.compiled.css"); var _runtime = require("@compiled/react/runtime"); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _bindEventListener = require("bind-event-listener"); var _v = _interopRequireDefault(require("uuid/v4")); var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- mirror existing renderer pattern var styles = { hiddenTrigger: "_1e0cglyw" }; /** * ADS `<Tooltip>` hands us a ref via its render-prop child. That ref may be * either a callback ref or a mutable ref object — React supports both shapes * and ADS's typing keeps both possible. This helper assigns the supplied * element to whichever ref shape was provided so the tooltip ends up using * the chip's bounding box for positioning and its DOM for trigger events. */ var assignRef = function assignRef(ref, element) { if (typeof ref === 'function') { ref(element); } else if (ref) { ref.current = element; } }; /** * Names of the React-style trigger-prop handlers we forward from ADS * `<Tooltip>` onto the chip element. */ /** * Maps each React-style trigger-prop handler ADS `<Tooltip>` hands us in its * render-prop callback to the DOM event name we attach to the chip via * `bind-event-listener`. The chip lives in the ProseMirror document and is * not a React child of the tooltip, so we have to bridge React handlers to * native event listeners ourselves. * * Names are listed in the same order ADS internally registers them. */ var TRIGGER_EVENT_MAP = [['onMouseOver', 'mouseover'], ['onMouseOut', 'mouseout'], ['onMouseMove', 'mousemove'], ['onMouseDown', 'mousedown'], ['onFocus', 'focusin'], ['onBlur', 'focusout']]; /** * Anchors an ADS `<Tooltip>` to a ProseMirror chip element that is **not** a * React child of the tooltip. The chip itself stays in the PM document; this * renderer mounts an always-present React subtree via `portalProviderAPI` whose * sole job is to host the tooltip and forward the ADS-provided trigger ref + * event handlers onto the chip. * * The forwarding is deliberate: ADS `<Tooltip>` expects to attach its hover / * focus / blur listeners to its render-prop child, but our render-prop child * is a `display: none` placeholder span that no real event can reach. We bridge * those listeners to the chip via `addEventListener` so the tooltip opens and * closes in response to the user actually interacting with the chip — keyboard * focus, mouse hover, screen-reader focus, the lot. */ /** * Hook that mirrors ADS Tooltip's React trigger props onto a DOM element * which is not a React child of the tooltip. Re-attaches whenever ADS hands * us a fresh set of props (which happens on every render of the render-prop * child) and cleans up on unmount. * * We use `bind-event-listener`'s `bindAll` rather than raw * `addEventListener` / `removeEventListener` calls so the lifetime of every * subscription is paired with a single `UnbindFn` — the AFM-mandated pattern * for keeping listener bookkeeping leak-free. */ var useBridgedTriggerListeners = function useBridgedTriggerListeners(chip, triggerProps) { (0, _react.useEffect)(function () { // Build the bindAll bindings array out of only the handlers ADS actually // supplied. Each React handler is wrapped in a thin adapter so the // listener signature matches the native `EventListener` shape; ADS // handlers ignore the synthetic-event-only fields they don't use // (target, currentTarget), so passing the raw DOM event through // `unknown` is safe in practice. var bindings = TRIGGER_EVENT_MAP.flatMap(function (_ref) { var _ref2 = (0, _slicedToArray2.default)(_ref, 2), propName = _ref2[0], eventName = _ref2[1]; var handler = triggerProps[propName]; if (!handler) { return []; } return [{ type: eventName, listener: function listener(event) { handler(event); } }]; }); if (bindings.length === 0) { return; } var unbind = (0, _bindEventListener.bindAll)(chip, bindings); return unbind; }, [chip, triggerProps]); }; var AnchoredTooltip = function AnchoredTooltip(_ref3) { var subscribe = _ref3.subscribe, getInitialTooltip = _ref3.getInitialTooltip, referenceElement = _ref3.referenceElement; var _useState = (0, _react.useState)(getInitialTooltip), _useState2 = (0, _slicedToArray2.default)(_useState, 2), tooltip = _useState2[0], setTooltipState = _useState2[1]; (0, _react.useEffect)(function () { return subscribe(setTooltipState); }, [subscribe]); if (!tooltip) { return null; } return /*#__PURE__*/_react.default.createElement(_tooltip.default, { content: tooltip, position: "top" }, function (tooltipProps) { return /*#__PURE__*/_react.default.createElement(TriggerBridge, { referenceElement: referenceElement, tooltipProps: tooltipProps }); }); }; /** * Render-prop child for ADS `<Tooltip>`. The element it returns is a * `display: none` placeholder that satisfies the render-prop API; the * real trigger surface is the chip in the PM document, which receives * both the ADS ref and the bridged event listeners via the side-effects * declared on this component. */ var TriggerBridge = function TriggerBridge(_ref4) { var referenceElement = _ref4.referenceElement, tooltipProps = _ref4.tooltipProps; useBridgedTriggerListeners(referenceElement, tooltipProps); return /*#__PURE__*/_react.default.createElement("span", { ref: function ref() { return assignRef(tooltipProps.ref, referenceElement); }, "aria-hidden": "true", className: (0, _runtime.ax)([styles.hiddenTrigger]) }); }; var disabledTooltipRenderer = exports.disabledTooltipRenderer = function disabledTooltipRenderer(_ref5) { var chipElement = _ref5.chipElement, portalProviderAPI = _ref5.portalProviderAPI; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- mirror existing renderer pattern var key = (0, _v.default)(); var currentTooltip; var listeners = new Set(); var broadcast = function broadcast() { listeners.forEach(function (listener) { return listener(currentTooltip); }); }; var getInitialTooltip = function getInitialTooltip() { return currentTooltip; }; var subscribe = function subscribe(listener) { listeners.add(listener); return function () { listeners.delete(listener); }; }; var renderElement = function renderElement() { return /*#__PURE__*/_react.default.createElement(AnchoredTooltip, { referenceElement: chipElement, getInitialTooltip: getInitialTooltip, subscribe: subscribe }); }; portalProviderAPI.render(renderElement, chipElement, key); return { setTooltip: function setTooltip(text) { currentTooltip = text; broadcast(); }, destroy: function destroy() { portalProviderAPI.remove(key); listeners.clear(); } }; };