UNPKG

@atlaskit/editor-plugin-media

Version:

Media plugin for @atlaskit/editor-core

378 lines (372 loc) 14.5 kB
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 })))) ); };