UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

279 lines 15.8 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import React, { memo, useCallback, useMemo, useState } from 'react'; import { ACTION_SUBJECT_ID, EVENT_TYPE, ACTION, ACTION_SUBJECT } from '@atlaskit/editor-common/analytics'; import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'; import { HoverLinkOverlay } from '@atlaskit/editor-common/ui'; import { NodeSelection } from '@atlaskit/editor-prosemirror/state'; import { extractSmartLinkEmbed } from '@atlaskit/link-extractors'; import { isWithinPreviewPanelIFrame } from '@atlaskit/linking-common/utils'; import { getObjectAri, getObjectName, getObjectIconUrl } from '@atlaskit/smart-card'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import { registerRemoveOverlay } from '../pm-plugins/actions'; import { pluginKey } from '../pm-plugins/plugin-key'; import { AwarenessWrapper } from '../ui/AwarenessWrapper'; import { PreviewInvoker } from '../ui/preview/PreviewInvoker'; import { InlineCard } from './inlineCard'; var selector = function selector(states) { var _states$editorViewMod, _states$selectionStat; return { mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode, selection: (_states$selectionStat = states.selectionState) === null || _states$selectionStat === void 0 ? void 0 : _states$selectionStat.selection }; }; export var InlineCardWithAwareness = /*#__PURE__*/memo(function (_ref) { var _pluginInjectionApi$c; var node = _ref.node, cardContext = _ref.cardContext, actionOptions = _ref.actionOptions, useAlternativePreloader = _ref.useAlternativePreloader, view = _ref.view, getPos = _ref.getPos, pluginInjectionApi = _ref.pluginInjectionApi, onClick = _ref.onClick, isPulseEnabled = _ref.isPulseEnabled, isOverlayEnabled = _ref.isOverlayEnabled, isSelected = _ref.isSelected, isPageSSRed = _ref.isPageSSRed, provider = _ref.provider, appearance = _ref.appearance; var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), isHovered = _useState2[0], setIsHovered = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), isInserted = _useState4[0], setIsInserted = _useState4[1]; var _useState5 = useState(false), _useState6 = _slicedToArray(_useState5, 2), isResolvedViewRendered = _useState6[0], setIsResolvedViewRendered = _useState6[1]; var editorAppearance = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.card.sharedState.currentState()) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.editorAppearance; var onResolve = useCallback(function (tr, title) { var metadata = tr.getMeta(pluginKey); if (metadata && metadata.type === 'REGISTER') { registerRemoveOverlay(function () { return setIsInserted(false); }, metadata.info)(tr); } else { registerRemoveOverlay(function () { return setIsInserted(false); })(tr); } if (title) { setIsResolvedViewRendered(true); } }, []); var markMostRecentlyInsertedLink = useCallback(function (isLinkMostRecentlyInserted) { if (isOverlayEnabled) { setIsInserted(isLinkMostRecentlyInserted); } }, [isOverlayEnabled]); var setOverlayHoveredStyles = useCallback(function (isHovered) { if (isOverlayEnabled) { setIsHovered(isHovered); } }, [isOverlayEnabled]); var _useSharedPluginState = useSharedPluginStateWithSelector(pluginInjectionApi, ['selection', 'editorViewMode'], selector), mode = _useSharedPluginState.mode, selection = _useSharedPluginState.selection; var floatingToolbarNode = selection instanceof NodeSelection && selection.node; // This is a prop to show Hover card, Hover card should be shown only in Live View and Classic Renderer (note when only Editor controls enabled we don't show in Live view) var showHoverPreview = floatingToolbarNode !== node && editorExperiment('platform_editor_preview_panel_linking_exp', true, { exposure: true }); var innerCardWithOpenButtonOverlay = useMemo(function () { var _pluginInjectionApi$a; return /*#__PURE__*/React.createElement(HoverLinkOverlay, { isVisible: isResolvedViewRendered, url: node.attrs.url, compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless', editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions, view: view }, /*#__PURE__*/React.createElement(InlineCard, { node: node, view: view, getPos: getPos, useAlternativePreloader: useAlternativePreloader, actionOptions: actionOptions, onResolve: onResolve, onClick: onClick, cardContext: cardContext, isHovered: isHovered, isPageSSRed: isPageSSRed, provider: provider, pluginInjectionApi: pluginInjectionApi, disablePreviewPanel: true })); }, [isResolvedViewRendered, node, editorAppearance, view, getPos, useAlternativePreloader, actionOptions, onResolve, onClick, cardContext, isHovered, isPageSSRed, provider, pluginInjectionApi]); var innerCardOriginal = useMemo(function () { return /*#__PURE__*/React.createElement(InlineCard, { node: node, view: view, getPos: getPos, useAlternativePreloader: useAlternativePreloader, actionOptions: actionOptions, onResolve: onResolve, onClick: onClick, cardContext: cardContext, isHovered: isHovered, isPageSSRed: isPageSSRed, provider: provider, pluginInjectionApi: pluginInjectionApi, showHoverPreview: false }); }, [actionOptions, cardContext, getPos, isHovered, node, onClick, onResolve, useAlternativePreloader, view, isPageSSRed, provider, pluginInjectionApi]); var shouldShowOpenButtonOverlay = useMemo(function () { var shouldShowOpenButtonOverlayInChomeless = editorAppearance === 'chromeless'; return (mode === 'edit' || editorAppearance === 'comment' || shouldShowOpenButtonOverlayInChomeless) && (editorExperiment('platform_editor_controls', 'variant1') || editorExperiment('platform_editor_preview_panel_linking_exp', true, { exposure: true })); }, [mode, editorAppearance]); var innerCard = shouldShowOpenButtonOverlay ? innerCardWithOpenButtonOverlay : innerCardOriginal; if (mode === 'view' && editorExperiment('platform_editor_preview_panel_linking_exp', true, { exposure: true })) { var _cardContext$value; var url = node.attrs.url; var cardState = cardContext === null || cardContext === void 0 || (_cardContext$value = cardContext.value) === null || _cardContext$value === void 0 || (_cardContext$value = _cardContext$value.store) === null || _cardContext$value === void 0 ? void 0 : _cardContext$value.getState()[url]; if (cardState) { var _cardContext$value2, _cardContext$value2$i, _cardContext$value3; var ari = getObjectAri(cardState.details); var name = getObjectName(cardState.details); var iconUrl = getObjectIconUrl(cardState.details); var isPanelAvailable = ari && (cardContext === null || cardContext === void 0 || (_cardContext$value2 = cardContext.value) === null || _cardContext$value2 === void 0 || (_cardContext$value2$i = _cardContext$value2.isPreviewPanelAvailable) === null || _cardContext$value2$i === void 0 ? void 0 : _cardContext$value2$i.call(_cardContext$value2, { ari: ari })); var openPreviewPanel = cardContext === null || cardContext === void 0 || (_cardContext$value3 = cardContext.value) === null || _cardContext$value3 === void 0 ? void 0 : _cardContext$value3.openPreviewPanel; var isPreviewPanelAvailable = Boolean(openPreviewPanel && isPanelAvailable); var firePreviewPanelClickEvent = function firePreviewPanelClickEvent(_ref2) { var _cardContext$value4, _pluginInjectionApi$a2; var previewType = _ref2.previewType; var store = cardContext === null || cardContext === void 0 || (_cardContext$value4 = cardContext.value) === null || _cardContext$value4 === void 0 ? void 0 : _cardContext$value4.store; var urlState = store === null || store === void 0 ? void 0 : store.getState()[url || '']; if (pluginInjectionApi !== null && pluginInjectionApi !== void 0 && (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) !== null && _pluginInjectionApi$a2 !== void 0 && _pluginInjectionApi$a2.actions) { var _pluginInjectionApi$a3, _urlState$details$met, _urlState$details, _urlState$details$met2, _urlState$details2; pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 || (_pluginInjectionApi$a3 = _pluginInjectionApi$a3.actions) === null || _pluginInjectionApi$a3 === void 0 || _pluginInjectionApi$a3.fireAnalyticsEvent({ action: ACTION.CLICKED, actionSubject: ACTION_SUBJECT.SMART_LINK, actionSubjectId: ACTION_SUBJECT_ID.HOVER_LABEL, eventType: EVENT_TYPE.UI, attributes: { previewType: previewType, destinationProduct: (_urlState$details$met = urlState === null || urlState === void 0 || (_urlState$details = urlState.details) === null || _urlState$details === void 0 || (_urlState$details = _urlState$details.meta) === null || _urlState$details === void 0 ? void 0 : _urlState$details.product) !== null && _urlState$details$met !== void 0 ? _urlState$details$met : null, destinationSubproduct: (_urlState$details$met2 = urlState === null || urlState === void 0 || (_urlState$details2 = urlState.details) === null || _urlState$details2 === void 0 || (_urlState$details2 = _urlState$details2.meta) === null || _urlState$details2 === void 0 ? void 0 : _urlState$details2.subproduct) !== null && _urlState$details$met2 !== void 0 ? _urlState$details$met2 : null } }); } }; var innerCardWithPanelButtonOverlay = /*#__PURE__*/React.createElement(PreviewInvoker, { url: url, appearance: "inline" }, function (_ref3) { var canPreview = _ref3.canPreview, invokePreview = _ref3.invokePreview; var isPreviewModalAvailable = Boolean(canPreview && invokePreview); // In view mode we show HoverLinkOverlay only with if preview mode or panel is available // otherwise a use can click on smartlink itself to open the link in a new tab. var isPreviewAvailable = isPreviewPanelAvailable || isPreviewModalAvailable; // When inside preview panel iframe, hide the overlay button var isInPreviewPanel = isWithinPreviewPanelIFrame(); var showPanelButton = isInPreviewPanel ? isPreviewPanelAvailable : isPreviewAvailable; if (isPreviewAvailable) { var _pluginInjectionApi$a4; return /*#__PURE__*/React.createElement(HoverLinkOverlay, { isVisible: isResolvedViewRendered, url: url, compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless', editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.actions, view: view, showPanelButton: showPanelButton, showPanelButtonIcon: isPreviewAvailable && isPreviewPanelAvailable ? 'panel' : 'modal' // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , onClick: function onClick(event) { if (isPreviewPanelAvailable) { var _extractSmartLinkEmbe; event.preventDefault(); openPreviewPanel === null || openPreviewPanel === void 0 || openPreviewPanel({ url: url, ari: ari || '', name: name || '', iconUrl: iconUrl, panelData: { embedUrl: expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') ? (_extractSmartLinkEmbe = extractSmartLinkEmbed(cardState === null || cardState === void 0 ? void 0 : cardState.details)) === null || _extractSmartLinkEmbe === void 0 ? void 0 : _extractSmartLinkEmbe.src : undefined } }); firePreviewPanelClickEvent({ previewType: 'panel' }); } else if (isPreviewModalAvailable) { event.preventDefault(); invokePreview === null || invokePreview === void 0 || invokePreview(); firePreviewPanelClickEvent({ previewType: 'modal' }); } } }, /*#__PURE__*/React.createElement(InlineCard, { node: node, view: view, getPos: getPos, useAlternativePreloader: useAlternativePreloader, actionOptions: actionOptions, onResolve: onResolve, onClick: onClick, cardContext: cardContext, isHovered: isHovered, isPageSSRed: isPageSSRed, provider: provider, pluginInjectionApi: pluginInjectionApi, showHoverPreview: mode === 'view' && showHoverPreview, disablePreviewPanel: true })); } else { return /*#__PURE__*/React.createElement(InlineCard, { node: node, view: view, getPos: getPos, useAlternativePreloader: useAlternativePreloader, actionOptions: actionOptions, onResolve: onResolve, onClick: onClick, cardContext: cardContext, isHovered: isHovered, isPageSSRed: isPageSSRed, provider: provider, pluginInjectionApi: pluginInjectionApi, showHoverPreview: mode === 'view' && showHoverPreview }); } }); innerCard = innerCardWithPanelButtonOverlay; } } var getPosFunction = typeof getPos === 'function' ? getPos : undefined; var placeholderUniqId = (getPosFunction === null || getPosFunction === void 0 ? void 0 : getPosFunction()) || 0; return isOverlayEnabled || isPulseEnabled ? /*#__PURE__*/React.createElement(AwarenessWrapper, { isOverlayEnabled: isOverlayEnabled, isPulseEnabled: isPulseEnabled, cardContext: cardContext, getPos: getPos, isHovered: isHovered, isInserted: isInserted, url: node.attrs.url, isSelected: isSelected, isResolvedViewRendered: isResolvedViewRendered, markMostRecentlyInsertedLink: markMostRecentlyInsertedLink, pluginInjectionApi: pluginInjectionApi, setOverlayHoveredStyles: setOverlayHoveredStyles, appearance: appearance }, innerCard) : /*#__PURE__*/React.createElement("span", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: "card", "data-vc": "editor-plugin-inline-card", "data-ssr-placeholder": "editor-plugin-inline-card-".concat(placeholderUniqId), "data-ssr-placeholder-replace": "editor-plugin-inline-card-".concat(placeholderUniqId) }, innerCard); });