UNPKG

@atlaskit/editor-plugin-media

Version:

Media plugin for @atlaskit/editor-core

170 lines (166 loc) 5.5 kB
import _extends from "@babel/runtime/helpers/extends"; /** @jsx jsx */ import { useCallback, useEffect, useMemo, useState } from 'react'; import { jsx } from '@emotion/react'; import Button from '@atlaskit/button'; import Form, { Field } from '@atlaskit/form'; import Textfield from '@atlaskit/textfield'; import Tooltip from '@atlaskit/tooltip'; import { PIXELENTRY_MIGRATION_BUTTON_TESTID } from './constants'; import { messages } from './messages'; import { pixelEntryForm, pixelEntryHiddenSubmit, pixelSizingFullWidthLabelStyles, pixelSizingHeightInput, pixelSizingInput, pixelSizingLabel, pixelSizingWidthInput, pixelSizingWrapper } from './styles'; export const PixelEntry = ({ width, mediaWidth, mediaHeight, onSubmit, minWidth, maxWidth, onChange, intl: { formatMessage }, showMigration, onMigrate }) => { const ratioWidth = useMemo(() => { return mediaHeight / mediaWidth; }, [mediaHeight, mediaWidth]); const ratioHeight = useMemo(() => { return mediaWidth / mediaHeight; }, [mediaHeight, mediaWidth]); const [computedWidth, setComputedWidth] = useState(width); const [computedHeight, setComputedHeight] = useState(Math.round(ratioWidth * width)); // Handle update to width from outside component useEffect(() => { setComputedWidth(width); setComputedHeight(Math.round(ratioWidth * width)); }, [width, ratioWidth]); // Handle submit when user presses enter in form const handleOnSubmit = data => { if (data.inputWidth === '' || data.inputHeight === '') { return; } if (onSubmit) { let widthToBeSumitted = data.inputWidth; let 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 }); } }; // Handle updating computed fields based on const handleOnChange = useCallback(type => event => { const value = parseInt(event.currentTarget.value); const newInputValue = isNaN(value) ? '' : value; let newWidth = ''; switch (type) { case 'inputWidth': { newWidth = newInputValue; setComputedWidth(newInputValue); const newHeight = newInputValue !== '' ? Math.round(ratioWidth * newInputValue) : ''; setComputedHeight(newHeight); break; } case 'inputHeight': { setComputedHeight(newInputValue); newWidth = newInputValue !== '' ? Math.round(ratioHeight * newInputValue) : ''; setComputedWidth(newWidth); break; } } const 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))); } return jsx("div", { css: pixelEntryForm }, jsx(Form, { onSubmit: handleOnSubmit }, ({ formProps }) => { return jsx("form", formProps, jsx("div", { css: pixelSizingWrapper }, jsx(Field, { key: "inputWidth", name: "inputWidth", defaultValue: computedWidth }, ({ fieldProps }) => jsx(Tooltip, { hideTooltipOnMouseDown: true, content: formatMessage(messages.inputWidthTooltip, { maxWidth }), position: "top" }, jsx(Textfield, _extends({}, fieldProps, { css: [pixelSizingWidthInput, pixelSizingInput], appearance: "none", isCompact: true, onChange: handleOnChange('inputWidth'), pattern: "\\d*", "aria-label": formatMessage(messages.inputWidthAriaLabel, { maxWidth }) })))), jsx("span", { css: pixelSizingLabel }, "x"), jsx(Field, { key: "inputHeight", name: "inputHeight", defaultValue: computedHeight }, ({ fieldProps }) => jsx(Tooltip, { hideTooltipOnMouseDown: true, content: formatMessage(messages.inputHeightTooltip), position: "top" }, jsx(Textfield, _extends({}, fieldProps, { 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)))); })); }; export const FullWidthDisplay = ({ intl: { formatMessage } }) => { return jsx("div", { css: pixelSizingFullWidthLabelStyles }, jsx("span", null, formatMessage(messages.fullWidthLabel))); };