@atlaskit/editor-plugin-media
Version:
Media plugin for @atlaskit/editor-core
148 lines (146 loc) • 7.35 kB
JavaScript
/**
* @jsxRuntime classic
* @jsx jsx
*/
import { useCallback } from 'react';
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
import { jsx } from '@emotion/react';
import { pixelEntryMessages as messages } from '@atlaskit/editor-common/media';
import { calcMinWidth, DEFAULT_IMAGE_HEIGHT, DEFAULT_IMAGE_WIDTH } from '@atlaskit/editor-common/media-single';
import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
import { hasParentNode } from '@atlaskit/editor-prosemirror/utils';
import { akEditorDefaultLayoutWidth, akEditorFullWidthLayoutWidth } from '@atlaskit/editor-shared-styles';
import { Text } from '@atlaskit/primitives/compiled';
import { updateMediaSingleWidthTr } from '../../../ui/toolbar/commands';
import { getPixelWidthOfElement, calcNewLayout } from '../../../ui/toolbar/utils';
import { isVideo } from '../../utils/media-single';
import { closePixelEditorAndSave } from '../commands';
import { PixelEntryComponent } from './pixel-entry';
import { pixelSizingFullWidthLabelStyles } from './styles';
export const PixelEntry = ({
editorView,
selectedMediaSingleNode,
pluginInjectionApi,
intl,
pluginState,
hoverDecoration,
isEditorFullWidthEnabled,
triggerButtonSelector
}) => {
var _pluginInjectionApi$w, _pluginInjectionApi$m, _pluginInjectionApi$m2, _pluginInjectionApi$f, _pluginInjectionApi$f2;
const {
state,
dispatch
} = editorView;
const {
mediaSingle
} = state.schema.nodes;
const contentWidth = (pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$w = pluginInjectionApi.width.sharedState.currentState()) === null || _pluginInjectionApi$w === void 0 ? void 0 : _pluginInjectionApi$w.lineLength) || akEditorDefaultLayoutWidth;
const {
width: mediaSingleWidth,
widthType,
layout
} = selectedMediaSingleNode.node.attrs;
// hasParentNode will return falsey value if selection depth === 0
const isNested = hasParentNode(n => n.type !== state.schema.nodes.doc)(state.selection);
const updateNodeWithTr = useCallback((width, validation) => {
var _pluginInjectionApi$a;
const newLayout = calcNewLayout(width, layout, contentWidth, isEditorFullWidthEnabled, isNested);
return updateMediaSingleWidthTr(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions, state, width, validation, 'floatingToolBar', newLayout);
}, [layout, contentWidth, isEditorFullWidthEnabled, isNested, state, pluginInjectionApi]);
const selectedMediaNode = selectedMediaSingleNode.node.content.firstChild;
if (!selectedMediaNode) {
return null;
}
const {
width: mediaWidth,
height: mediaHeight
} = selectedMediaNode.attrs;
const maxWidthForNestedNode = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$m = pluginInjectionApi.media) === null || _pluginInjectionApi$m === void 0 ? void 0 : (_pluginInjectionApi$m2 = _pluginInjectionApi$m.sharedState.currentState()) === null || _pluginInjectionApi$m2 === void 0 ? void 0 : _pluginInjectionApi$m2.currentMaxWidth;
const maxWidth = maxWidthForNestedNode || akEditorFullWidthLayoutWidth;
const isVideoFile = isVideo(selectedMediaNode.attrs.__fileMimeType);
const minWidth = calcMinWidth(isVideoFile, maxWidthForNestedNode || contentWidth);
const hasPixelType = widthType === 'pixel';
const pixelWidthFromElement = getPixelWidthOfElement(editorView, selectedMediaSingleNode.pos + 1,
// get pos of media node
mediaWidth || DEFAULT_IMAGE_WIDTH);
const pixelWidth = hasPixelType ? mediaSingleWidth : pixelWidthFromElement;
const forceFocusSelector = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$f = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f === void 0 ? void 0 : (_pluginInjectionApi$f2 = _pluginInjectionApi$f.actions) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.forceFocusSelector;
const areAnyNewToolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.toolbar));
return jsx(PixelEntryComponent, {
intl: intl,
width: pluginState.isResizing ? pluginState.resizingWidth : pixelWidth,
showMigration: !pluginState.isResizing && !hasPixelType,
mediaWidth: mediaWidth || DEFAULT_IMAGE_WIDTH,
mediaHeight: mediaHeight || DEFAULT_IMAGE_HEIGHT,
minWidth: minWidth,
maxWidth: maxWidth
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onChange: valid => {
if (valid) {
hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, true, 'warning')(editorView.state, dispatch, editorView);
} else {
hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(mediaSingle, false)(editorView.state, dispatch, editorView);
}
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onSubmit: ({
width,
validation
}) => {
const tr = updateNodeWithTr(width, validation);
if (tr) {
dispatch(tr);
}
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onMigrate: () => {
let tr = state.tr.setNodeMarkup(selectedMediaSingleNode.pos, undefined, {
...selectedMediaSingleNode.node.attrs,
width: pixelWidthFromElement,
widthType: 'pixel'
});
tr.setMeta('scrollIntoView', false);
tr.setSelection(NodeSelection.create(tr.doc, selectedMediaSingleNode.pos));
if (triggerButtonSelector) {
const newTr = forceFocusSelector && forceFocusSelector(triggerButtonSelector)(tr);
tr = newTr !== undefined ? newTr : tr;
}
dispatch(tr);
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onCloseAndSave: ({
width,
validation
}, setFocus) => {
let tr = updateNodeWithTr(width, validation);
if (setFocus && triggerButtonSelector) {
const newTr = forceFocusSelector && tr && forceFocusSelector(triggerButtonSelector)(tr);
tr = newTr !== undefined ? newTr : tr;
}
if (tr) {
return closePixelEditorAndSave(() => tr)(state, dispatch);
}
},
isViewMode: pluginState.isResizing,
triggerButtonSelector: triggerButtonSelector,
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
});
};
export const FullWidthDisplay = ({
intl: {
formatMessage
}
}) => {
return (
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
jsx("div", {
css: pixelSizingFullWidthLabelStyles
}, jsx(Text, null, formatMessage(messages.fullWidthLabel)))
);
};