UNPKG

@atlaskit/editor-common

Version:

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

104 lines 3.79 kB
/** * @jsxRuntime classic * @jsx jsx */ import { useCallback, useLayoutEffect, useState } from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 import { css, jsx } from '@emotion/react'; import { useIntl } from 'react-intl'; import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext'; import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state'; import PreferencesIcon from '@atlaskit/icon/core/customize'; import Tooltip from '@atlaskit/tooltip'; import { cardMessages } from '../../messages'; import Dropdown from './Dropdown'; import { StyledButton } from './StyledButton'; import { useLinkOverlayAnalyticsEvents } from './useLinkOverlayAnalyticsEvents'; const buttonWrapperStyles = css({ position: 'absolute', zIndex: 100, display: 'inline-flex', top: '50%', transform: 'translateY(-50%)', background: "var(--ds-surface-raised, #FFFFFF)", borderRadius: "var(--ds-radius-small, 3px)" }); const showDropdownThresholdPx = 50; export const OverlayButton = withAnalyticsContext()(({ editorView, testId = 'link-configure-overlay-button', targetElementPos = 0, onDropdownChange, onOpenLinkClick }) => { var _docNode$nodeSize; const { formatMessage } = useIntl(); const configureLinkLabel = formatMessage(cardMessages.inlineConfigureLink); const [showDropdown, setShowDropdown] = useState(false); const { fireActionClickEvent, fireLinkClickEvent } = useLinkOverlayAnalyticsEvents(); useLayoutEffect(() => { var _domNode; let domNode = editorView.nodeDOM(targetElementPos); if (((_domNode = domNode) === null || _domNode === void 0 ? void 0 : _domNode.nodeType) === Node.TEXT_NODE) { domNode = domNode.parentElement; } if (domNode instanceof HTMLElement) { const { width } = domNode.getBoundingClientRect(); if (width < showDropdownThresholdPx) { setShowDropdown(true); } } }, [editorView, targetElementPos]); const docNode = editorView.state.doc.nodeAt(targetElementPos); const nodeEnd = targetElementPos + ((_docNode$nodeSize = docNode === null || docNode === void 0 ? void 0 : docNode.nodeSize) !== null && _docNode$nodeSize !== void 0 ? _docNode$nodeSize : 0); const isText = docNode === null || docNode === void 0 ? void 0 : docNode.isText; const handleConfigureClick = useCallback(() => { const tr = editorView.state.tr; if (isText) { tr.setSelection(TextSelection.create(tr.doc, targetElementPos, Math.min(nodeEnd, tr.doc.nodeSize))); } else { tr.setSelection(NodeSelection.create(tr.doc, targetElementPos)); } editorView.dispatch(tr); }, [editorView, isText, targetElementPos, nodeEnd]); const handleConfigureClickWithAnalytics = useCallback(() => { fireActionClickEvent('configureLink'); fireLinkClickEvent(); handleConfigureClick(); }, [fireLinkClickEvent, handleConfigureClick, fireActionClickEvent]); const { from, to } = editorView.state.selection; const isSelected = from === targetElementPos && to === nodeEnd; if (!targetElementPos || isSelected) { return null; } return jsx("span", { css: buttonWrapperStyles, "data-testid": testId }, showDropdown ? jsx(Dropdown, { testId: testId, onConfigureClick: handleConfigureClick, onOpenLinkClick: onOpenLinkClick, onDropdownChange: onDropdownChange, editorView: editorView }) : jsx(Tooltip, { content: configureLinkLabel, hideTooltipOnClick: true, testId: `${testId}-tooltip` }, jsx(StyledButton, { onClick: handleConfigureClickWithAnalytics, iconBefore: jsx(PreferencesIcon, { label: configureLinkLabel, testId: `${testId}-configure-icon` }) }))); });