@atlaskit/editor-plugin-media
Version:
Media plugin for @atlaskit/editor-core
378 lines (372 loc) • 14.5 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
/* eslint-disable jsdoc/check-tag-names */
/**
* @jsxRuntime classic
* @jsx jsx
*/
import { useCallback, useEffect, useMemo, useState, useRef, Fragment } from 'react';
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
import { jsx, css } from '@emotion/react';
import Button from '@atlaskit/button';
import { IconButton } from '@atlaskit/button/new';
import { pixelEntryMessages as messages } from '@atlaskit/editor-common/media';
import Form, { Field } from '@atlaskit/form';
import CrossIcon from '@atlaskit/icon/core/cross';
// eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives, @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
import { Inline, Box, Text, xcss } from '@atlaskit/primitives';
import Textfield from '@atlaskit/textfield';
import Tooltip from '@atlaskit/tooltip';
import { PIXEL_RESIZING_TOOLBAR_WIDTH, PIXEL_VIEW_MODE_TOOLBAR_WIDTH, PIXELENTRY_MIGRATION_BUTTON_TESTID } from './constants';
import { pixelEntryForm, pixelEntryHiddenSubmit, pixelSizingHeightInput, pixelSizingInput, pixelSizingWidthInput, pixelSizingWrapper } from './styles';
var pixelSizingLabel = xcss({
gridArea: 'label',
lineHeight: "var(--ds-space-300, 24px)"
});
export var PixelEntryComponent = function PixelEntryComponent(_ref) {
var width = _ref.width,
mediaWidth = _ref.mediaWidth,
mediaHeight = _ref.mediaHeight,
onSubmit = _ref.onSubmit,
minWidth = _ref.minWidth,
maxWidth = _ref.maxWidth,
onChange = _ref.onChange,
formatMessage = _ref.intl.formatMessage,
showMigration = _ref.showMigration,
onMigrate = _ref.onMigrate,
onCloseAndSave = _ref.onCloseAndSave,
isViewMode = _ref.isViewMode,
areAnyNewToolbarFlagsEnabled = _ref.areAnyNewToolbarFlagsEnabled;
var ratioWidth = useMemo(function () {
return mediaHeight / mediaWidth;
}, [mediaHeight, mediaWidth]);
var ratioHeight = useMemo(function () {
return mediaWidth / mediaHeight;
}, [mediaHeight, mediaWidth]);
var _useState = useState(width),
_useState2 = _slicedToArray(_useState, 2),
computedWidth = _useState2[0],
setComputedWidth = _useState2[1];
var _useState3 = useState(Math.round(ratioWidth * width)),
_useState4 = _slicedToArray(_useState3, 2),
computedHeight = _useState4[0],
setComputedHeight = _useState4[1];
// Handle update to width from outside component
useEffect(function () {
setComputedWidth(width);
setComputedHeight(Math.round(ratioWidth * width));
}, [width, ratioWidth]);
// Handle submit when user presses enter in form
var handleOnSubmit = function handleOnSubmit(data) {
if (data.inputWidth === '' || data.inputHeight === '') {
return;
}
if (onSubmit) {
var widthToBeSumitted = data.inputWidth;
var validation = 'valid';
if (data.inputWidth < minWidth) {
widthToBeSumitted = minWidth;
validation = 'less-than-min';
}
if (data.inputWidth > maxWidth) {
widthToBeSumitted = maxWidth;
validation = 'greater-than-max';
}
// If user keeps submitting an invalid input, node width attribute will be updated with the same value
// and won't upadte the state in useEffect (since width is the same)
// Thus, we set the state here to always display the correct dimension
if (validation !== 'valid') {
setComputedWidth(widthToBeSumitted);
setComputedHeight(Math.round(ratioWidth * widthToBeSumitted));
}
onSubmit({
width: widthToBeSumitted,
validation: validation
});
}
};
// Handle submit when user presses enter or click close button in PixelEntryComponentNext
var handleCloseAndSave = useCallback(function (data, setFocus) {
if (data.inputWidth === '' || data.inputHeight === '') {
return;
}
if (onCloseAndSave) {
var widthToBeSubmitted = data.inputWidth;
var validation = 'valid';
if (data.inputWidth < minWidth) {
widthToBeSubmitted = minWidth;
validation = 'less-than-min';
}
if (data.inputWidth > maxWidth) {
widthToBeSubmitted = maxWidth;
validation = 'greater-than-max';
}
// If user keeps submitting an invalid input, node width attribute will be updated with the same value
// and won't upadte the state in useEffect (since width is the same)
// Thus, we set the state here to always display the correct dimension
if (validation !== 'valid') {
setComputedWidth(widthToBeSubmitted);
setComputedHeight(Math.round(ratioWidth * widthToBeSubmitted));
}
onCloseAndSave({
width: widthToBeSubmitted,
validation: validation
}, setFocus);
}
}, [maxWidth, minWidth, onCloseAndSave, ratioWidth]);
// Handle updating computed fields based on
var handleOnChange = useCallback(function (type) {
return function (event) {
var value = parseInt(event.currentTarget.value);
var newInputValue = isNaN(value) ? '' : value;
var newWidth = '';
switch (type) {
case 'inputWidth':
{
newWidth = newInputValue;
setComputedWidth(newInputValue);
var newHeight = newInputValue !== '' ? Math.round(ratioWidth * newInputValue) : '';
setComputedHeight(newHeight);
break;
}
case 'inputHeight':
{
setComputedHeight(newInputValue);
newWidth = newInputValue !== '' ? Math.round(ratioHeight * newInputValue) : '';
setComputedWidth(newWidth);
break;
}
}
var isInvalidInputValid = newWidth !== '' && (newWidth < minWidth || newWidth > maxWidth);
onChange && onChange(isInvalidInputValid);
};
}, [minWidth, maxWidth, onChange, ratioWidth, ratioHeight]);
if (showMigration) {
return jsx(Tooltip, {
content: formatMessage(messages.migrationButtonTooltip)
}, jsx(Button, {
appearance: "warning",
spacing: "compact",
onClick: onMigrate,
testId: PIXELENTRY_MIGRATION_BUTTON_TESTID
}, formatMessage(messages.migrationButtonText)));
}
if (areAnyNewToolbarFlagsEnabled) {
return jsx(PixelEntryComponentNext, {
maxWidth: maxWidth,
formatMessage: formatMessage,
handleFieldChange: handleOnChange,
computedWidth: computedWidth,
computedHeight: computedHeight,
handleCloseAndSave: handleCloseAndSave,
isViewMode: isViewMode
});
}
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: pixelEntryForm
}, jsx(Form, {
onSubmit: handleOnSubmit
}, function (_ref2) {
var formProps = _ref2.formProps;
return (
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
jsx("form", formProps, jsx("div", {
css: pixelSizingWrapper
}, jsx(Field, {
key: "inputWidth",
name: "inputWidth",
defaultValue: computedWidth
}, function (_ref3) {
var fieldProps = _ref3.fieldProps;
return jsx(Tooltip, {
hideTooltipOnMouseDown: true,
content: formatMessage(messages.inputWidthTooltip, {
maxWidth: maxWidth
}),
position: "top"
}, jsx(Textfield
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, fieldProps, {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/no-unsafe-style-overrides, @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
css: [pixelSizingWidthInput, pixelSizingInput],
appearance: "none",
isCompact: true,
onChange: handleOnChange('inputWidth'),
pattern: "\\d*",
"aria-label": formatMessage(messages.inputWidthAriaLabel, {
maxWidth: maxWidth
})
})));
}), jsx(Box, {
as: "span",
xcss: pixelSizingLabel
}, "\xD7"), jsx(Field, {
key: "inputHeight",
name: "inputHeight",
defaultValue: computedHeight
}, function (_ref4) {
var fieldProps = _ref4.fieldProps;
return jsx(Tooltip, {
hideTooltipOnMouseDown: true,
content: formatMessage(messages.inputHeightTooltip),
position: "top"
}, jsx(Textfield
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, fieldProps, {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/no-unsafe-style-overrides, @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
css: [pixelSizingHeightInput, pixelSizingInput],
appearance: "none",
isCompact: true,
onChange: handleOnChange('inputHeight'),
pattern: "\\d*",
"aria-label": formatMessage(messages.inputHeightAriaLabel)
})));
}), jsx(Button, {
css: pixelEntryHiddenSubmit,
type: "submit"
}, formatMessage(messages.submitButtonText))))
);
}))
);
};
var pixelEntryWrapperStyles = xcss({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
width: "".concat(PIXEL_RESIZING_TOOLBAR_WIDTH, "px")
});
var pixelEntryWrapperViewModeStyles = xcss({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
width: "".concat(PIXEL_VIEW_MODE_TOOLBAR_WIDTH, "px")
});
var fieldStyles = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'[data-ds--text-field--input]': {
paddingBlock: "var(--ds-space-0, 0px)",
paddingInline: "var(--ds-space-100, 8px)"
},
flex: '1'
});
var dividerStyles = xcss({
width: '1px',
height: "var(--ds-space-500, 40px)",
background: "var(--ds-border, #0B120E24)",
marginInlineEnd: 'space.050'
});
export var PixelEntryComponentNext = function PixelEntryComponentNext(_ref5) {
var maxWidth = _ref5.maxWidth,
formatMessage = _ref5.formatMessage,
handleFieldChange = _ref5.handleFieldChange,
computedWidth = _ref5.computedWidth,
computedHeight = _ref5.computedHeight,
handleCloseAndSave = _ref5.handleCloseAndSave,
isViewMode = _ref5.isViewMode;
var widthInputRef = useRef(null);
useEffect(function () {
if (widthInputRef.current) {
if (isViewMode) {
widthInputRef.current.blur();
} else {
widthInputRef.current.focus();
}
}
}, [isViewMode, widthInputRef]);
var handleKeyDown = useCallback(function (event) {
if (event.key === 'Enter') {
var shouldSetFocus = true;
handleCloseAndSave({
inputWidth: computedWidth,
inputHeight: computedHeight
}, shouldSetFocus);
}
}, [computedWidth, computedHeight, handleCloseAndSave]);
var handleCloseButtonKeyDown = useCallback(function (event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
var shouldSetFocus = true;
handleCloseAndSave({
inputWidth: computedWidth,
inputHeight: computedHeight
}, shouldSetFocus);
}
}, [computedWidth, computedHeight, handleCloseAndSave]);
return (
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
jsx(Box, {
xcss: [pixelEntryWrapperStyles, isViewMode && pixelEntryWrapperViewModeStyles]
}, jsx(Inline, {
alignBlock: "center",
spread: "space-between"
}, jsx(Box, {
paddingInlineStart: "space.100"
}, jsx(Text, {
color: "color.text.subtlest"
}, formatMessage(messages.inputWidthLabel))), jsx("div", {
css: fieldStyles
}, jsx(Tooltip, {
hideTooltipOnMouseDown: true,
hideTooltipOnClick: true,
position: "top",
content: formatMessage(messages.inputWidthTooltip, {
maxWidth: maxWidth
})
}, jsx(Textfield, {
name: "inputWidth",
value: computedWidth,
ref: widthInputRef,
height: "var(--ds-space-250, 20px)",
appearance: "none",
pattern: "\\d*",
"aria-label": formatMessage(messages.inputWidthAriaLabel, {
maxWidth: maxWidth
}),
onChange: handleFieldChange('inputWidth'),
onKeyDown: handleKeyDown
}))), jsx(Box, {
paddingInlineStart: "space.100"
}, jsx(Text, {
color: "color.text.subtlest"
}, formatMessage(messages.inputHeightTooltip))), jsx("div", {
css: fieldStyles
}, jsx(Tooltip, {
hideTooltipOnMouseDown: true,
hideTooltipOnClick: true,
content: formatMessage(messages.inputHeightTooltip),
position: "top"
}, jsx(Textfield, {
name: "inputHeight",
value: computedHeight,
height: "var(--ds-space-250, 20px)",
appearance: "none",
pattern: "\\d*",
"aria-label": formatMessage(messages.inputHeightAriaLabel),
onChange: handleFieldChange('inputHeight'),
onKeyDown: handleKeyDown
}))), !isViewMode && jsx(Fragment, null, jsx(Box, {
xcss: dividerStyles
}), jsx(IconButton
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
, {
icon: function icon() {
return jsx(CrossIcon, {
label: "",
color: "var(--ds-icon-subtlest, #6B6E76)"
});
},
label: formatMessage(messages.closePixelEntry),
appearance: "subtle"
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onClick: function onClick() {
handleCloseAndSave({
inputWidth: computedWidth,
inputHeight: computedHeight
});
},
onKeyDown: handleCloseButtonKeyDown
}))))
);
};