@atlaskit/editor-plugin-paste-options-toolbar
Version:
Paste options toolbar for @atlaskit/editor-core
112 lines (108 loc) • 4.35 kB
JavaScript
/* PasteActionsMenuContent.tsx generated by @compiled/babel-plugin v2.0.0 */
import "./PasteActionsMenuContent.compiled.css";
import { ax, ix } from "@compiled/react/runtime";
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
import { PASTE_MENU } from '@atlaskit/editor-common/toolbar';
import { OutsideClickTargetRefContext } from '@atlaskit/editor-common/ui-react';
import { ToolbarMenuContainer } from '@atlaskit/editor-toolbar/toolbar-menu-container';
import { SurfaceRenderer } from '@atlaskit/editor-ui-control-model';
import { Box } from '@atlaskit/primitives/compiled';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { getSingleSmartLinkUrlFromSlice } from '../utils/current-pasted-smart-link';
import { evaluateAsyncHidden } from './async-hidden';
const styles = {
container: "_2rko12b0 _bfhk1bhr _16qs130s"
};
const pasteMenuSurface = {
type: PASTE_MENU.type,
key: PASTE_MENU.key
};
export const PasteActionsMenuContent = ({
onMouseDown,
onMouseEnter,
components,
contentRef,
pastedSlice
}) => {
const setOutsideClickTargetRef = useContext(OutsideClickTargetRefContext);
// Extract the pasted URL (if the pasted content was a single smart link).
// Uses the reactive pasted slice from the paste plugin state so pastedUrl
// updates when paste state changes.
const pastedUrl = getSingleSmartLinkUrlFromSlice(pastedSlice);
// Components with isAsyncHidden are hidden until the async check resolves.
// This prevents flash-of-visible content for items that
// should ultimately be hidden. A generation counter discards stale results.
const [asyncHiddenResults, setAsyncHiddenResults] = useState(() => {
return Object.fromEntries(components.map(component => [component.key, true]));
});
const generationRef = useRef(0);
useEffect(() => {
const asyncComponents = [];
for (const component of components) {
if (typeof component.isAsyncHidden === 'function') {
asyncComponents.push(component);
}
}
if (asyncComponents.length === 0) {
setAsyncHiddenResults({});
return;
}
// Reset: mark all async components as hidden until this round resolves.
const pending = {};
for (const c of asyncComponents) {
pending[c.key] = true;
}
setAsyncHiddenResults(pending);
const generation = ++generationRef.current;
const context = {
pastedUrl
};
void evaluateAsyncHidden(asyncComponents, context).then(results => {
// Discard if a newer effect has already started.
if (generation === generationRef.current) {
setAsyncHiddenResults(results);
}
});
}, [components, pastedUrl]);
// SurfaceRenderer evaluates isHidden() itself on each component. Override
// isHidden on async components so SurfaceRenderer sees the resolved value.
const visibleComponents = components.map(component => {
if (typeof component.isAsyncHidden !== 'function') {
// No async check — pass through unchanged.
return component;
}
const asyncResult = asyncHiddenResults[component.key];
return {
...component,
isHidden: () => {
var _component$isHidden;
return asyncResult === true || Boolean((_component$isHidden = component.isHidden) === null || _component$isHidden === void 0 ? void 0 : _component$isHidden.call(component));
}
};
});
const mergedRef = useCallback(node => {
setOutsideClickTargetRef === null || setOutsideClickTargetRef === void 0 ? void 0 : setOutsideClickTargetRef(node);
if (contentRef) {
contentRef.current = node;
}
}, [setOutsideClickTargetRef, contentRef]);
if (expValEquals('platform_editor_menu_radius_update', 'isEnabled', true)) {
return /*#__PURE__*/React.createElement(ToolbarMenuContainer, {
ref: mergedRef,
onMouseDown: onMouseDown,
onMouseEnter: onMouseEnter
}, /*#__PURE__*/React.createElement(SurfaceRenderer, {
surface: pasteMenuSurface,
components: visibleComponents
}));
}
return /*#__PURE__*/React.createElement(Box, {
ref: mergedRef,
xcss: styles.container,
onMouseDown: onMouseDown,
onMouseEnter: onMouseEnter
}, /*#__PURE__*/React.createElement(SurfaceRenderer, {
surface: pasteMenuSurface,
components: visibleComponents
}));
};