UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

280 lines (278 loc) 14.9 kB
import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; var _excluded = ["width", "height", "children", "handleClassName", "className", "handleResize", "handleResizeStart", "handleResizeStop", "handleSize", "handleAlignmentMethod", "handlePositioning", "appearance", "handleStyles", "resizeRatio", "snap", "snapGap", "isHandleVisible", "handleHighlight", "handleTooltipContent", "needExtendedResizeZone", "childrenDOMRef", "labelComponent"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react'; import classnames from 'classnames'; import { Resizable } from 're-resizable'; import { useIntl } from 'react-intl'; // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss import { Box, xcss } from '@atlaskit/primitives'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import Tooltip from '@atlaskit/tooltip'; import { messages } from '../messages/breakout'; import { handleWrapperClass, resizerDangerClassName, resizerExtendedZone, resizerHandleClassName, resizerHandleThumbClassName, resizerHandleTrackClassName, resizerHandleZIndex, resizerHoverZoneClassName, resizerItemClassName } from '../styles/shared/resizer'; var resizerLabelStyles = xcss({ position: 'absolute', bottom: "var(--ds-space-0, 0px)", width: '100%', overflow: 'visible', display: 'flex', justifyContent: 'center', alignItems: 'center', height: "var(--ds-space-0, 0px)", zIndex: 'layer' // 400 same z-index as the floating toolbar }); var SUPPORTED_HANDLES = ['left', 'right']; var SUPPORTED_HANDLES_FOR_VERTICAL_RESIZE = ['left', 'right', 'bottom']; var inheritedCSS = { position: 'inherit', height: 'inherit', width: 'inherit', display: 'inherit', flexDirection: 'inherit', justifyContent: 'inherit', alignItems: 'inherit' }; var ResizerNext = function ResizerNext(props, ref) { var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), isResizing = _useState2[0], setIsResizing = _useState2[1]; var resizable = useRef(null); var resizeHandleThumbRef = useRef(null); useImperativeHandle(ref, function () { return { getResizerThumbEl: function getResizerThumbEl() { return resizeHandleThumbRef.current; } }; }, [resizeHandleThumbRef]); var width = props.width, height = props.height, children = props.children, handleClassName = props.handleClassName, className = props.className, handleResize = props.handleResize, handleResizeStart = props.handleResizeStart, handleResizeStop = props.handleResizeStop, _props$handleSize = props.handleSize, handleSize = _props$handleSize === void 0 ? 'medium' : _props$handleSize, _props$handleAlignmen = props.handleAlignmentMethod, handleAlignmentMethod = _props$handleAlignmen === void 0 ? 'center' : _props$handleAlignmen, _props$handlePosition = props.handlePositioning, handlePositioning = _props$handlePosition === void 0 ? 'overlap' : _props$handlePosition, appearance = props.appearance, handleStyles = props.handleStyles, _props$resizeRatio = props.resizeRatio, resizeRatio = _props$resizeRatio === void 0 ? 1 : _props$resizeRatio, snap = props.snap, snapGap = props.snapGap, _props$isHandleVisibl = props.isHandleVisible, isHandleVisible = _props$isHandleVisibl === void 0 ? false : _props$isHandleVisibl, _props$handleHighligh = props.handleHighlight, handleHighlight = _props$handleHighligh === void 0 ? 'none' : _props$handleHighligh, handleTooltipContent = props.handleTooltipContent, _props$needExtendedRe = props.needExtendedResizeZone, needExtendedResizeZone = _props$needExtendedRe === void 0 ? true : _props$needExtendedRe, childrenDOMRef = props.childrenDOMRef, labelComponent = props.labelComponent, otherProps = _objectWithoutProperties(props, _excluded); var supportedHandles = expValEquals('databases-native-embeds-v2', 'isEnabled', true) ? SUPPORTED_HANDLES_FOR_VERTICAL_RESIZE : SUPPORTED_HANDLES; var onResizeStart = useCallback(function (event) { // prevent creating a drag event on Firefox event.preventDefault(); setIsResizing(true); handleResizeStart(); }, [handleResizeStart]); var onResize = useCallback(function (_event, direction, _elementRef, delta) { if (!handleResize) { return; } var resizableCurrent = resizable.current; if (!resizableCurrent || !resizableCurrent.state.original) { return; } var originalState = { x: resizableCurrent.state.original.x, y: resizableCurrent.state.original.y, width: resizableCurrent.state.original.width, height: resizableCurrent.state.original.height }; if (expValEquals('databases-native-embeds-v2', 'isEnabled', true)) { handleResize(originalState, delta, direction); } else { handleResize(originalState, delta); } }, [handleResize]); var onResizeStop = useCallback(function (_event, direction, _elementRef, delta) { var resizableCurrent = resizable.current; if (!resizableCurrent || !resizableCurrent.state.original) { return; } var originalState = { x: resizableCurrent.state.original.x, y: resizableCurrent.state.original.y, width: resizableCurrent.state.original.width, height: resizableCurrent.state.original.height }; setIsResizing(false); if (expValEquals('databases-native-embeds-v2', 'isEnabled', true)) { handleResizeStop(originalState, delta, direction); } else { handleResizeStop(originalState, delta); } }, [handleResizeStop]); var handles = useMemo(function () { return supportedHandles.reduce(function (result, position) { return _objectSpread(_objectSpread({}, result), {}, _defineProperty({}, position, classnames(handleClassName !== null && handleClassName !== void 0 ? handleClassName : resizerHandleClassName, position, handleSize, position === 'bottom' && expValEquals('databases-native-embeds-v2', 'isEnabled', true) ? undefined : handleAlignmentMethod))); }, {}); }, [handleClassName, handleSize, handleAlignmentMethod, supportedHandles]); var handleWidth = handlePositioning === 'adjacent' ? "var(--ds-space-100, 8px)" : "var(--ds-space-300, 24px)"; var baseHorizontalHandleStyles = { width: handleWidth, zIndex: resizerHandleZIndex, pointerEvents: 'auto', alignItems: handlePositioning === 'adjacent' ? 'center' : undefined }; var baseBottomHandleStyles = { height: handleWidth, zIndex: resizerHandleZIndex, pointerEvents: 'auto', justifyContent: handlePositioning === 'adjacent' ? 'center' : undefined }; var memoizedBaseHorizontalHandleStyles = useMemo(function () { return { width: handleWidth, zIndex: resizerHandleZIndex, pointerEvents: 'auto', alignItems: handlePositioning === 'adjacent' ? 'center' : undefined }; }, [handleWidth, handlePositioning]); var memoizedBaseBottomHandleStyles = useMemo(function () { return { height: handleWidth, zIndex: resizerHandleZIndex, pointerEvents: 'auto', justifyContent: handlePositioning === 'adjacent' ? 'center' : undefined }; }, [handleWidth, handlePositioning]); var offset = handlePositioning === 'adjacent' ? "calc(".concat(handleWidth, " * -1)") : "calc(".concat(handleWidth, " * -0.5)"); var memoizedNextHandleStyles = useMemo(function () { return supportedHandles.reduce(function (result, position) { return _objectSpread(_objectSpread({}, result), {}, _defineProperty({}, position, _objectSpread(_objectSpread({}, position === 'bottom' ? memoizedBaseBottomHandleStyles : memoizedBaseHorizontalHandleStyles), {}, _defineProperty({}, position, offset), handleStyles === null || handleStyles === void 0 ? void 0 : handleStyles[position]))); }, {}); }, [memoizedBaseBottomHandleStyles, memoizedBaseHorizontalHandleStyles, offset, handleStyles, supportedHandles]); var nextHandleStyles = expValEquals('platform_editor_perf_lint_cleanup', 'isEnabled', true) ? memoizedNextHandleStyles : // eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- intentional fallback for experiment off path supportedHandles.reduce(function (result, position) { return _objectSpread(_objectSpread({}, result), {}, _defineProperty({}, position, _objectSpread(_objectSpread({}, position === 'bottom' ? baseBottomHandleStyles : baseHorizontalHandleStyles), {}, _defineProperty({}, position, offset), handleStyles === null || handleStyles === void 0 ? void 0 : handleStyles[position]))); }, {}); var resizerClassName = classnames(className, resizerItemClassName, _defineProperty({ 'is-resizing': isResizing, 'display-handle': isHandleVisible }, resizerDangerClassName, appearance === 'danger')); var resizerZoneClassName = classnames(resizerHoverZoneClassName, _defineProperty({}, resizerExtendedZone, needExtendedResizeZone)); var _useIntl = useIntl(), formatMessage = _useIntl.formatMessage; var handleComponent = useMemo(function () { return supportedHandles.reduce(function (result, position) { var thumb = /*#__PURE__*/React.createElement("button", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: resizerHandleThumbClassName, "data-testid": "resizer-handle-".concat(position, "-thumb"), "aria-label": formatMessage(messages.resizeHandle), contentEditable: false, ref: resizeHandleThumbRef, type: "button", tabIndex: -1 //We want to control focus on this button ourselves }); if ((!handleHighlight || handleHighlight === 'none') && !handleTooltipContent) { return _objectSpread(_objectSpread({}, result), {}, _defineProperty({}, position, thumb)); } var thumbWithTrack = /*#__PURE__*/ //It's important to have {thumb} element before the div, the thumb element is the one that gets focus and only the 1st element recives aria-descibedby attribute which is important for screen reader users React.createElement(React.Fragment, null, thumb, /*#__PURE__*/React.createElement("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: classnames(resizerHandleTrackClassName, handleHighlight), "data-testid": "resizer-handle-".concat(position, "-track") })); if (!!handleTooltipContent) { return _objectSpread(_objectSpread({}, result), {}, _defineProperty({}, position, /*#__PURE__*/ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 React.createElement("div", { contentEditable: false, style: inheritedCSS }, /*#__PURE__*/React.createElement(Tooltip, { content: handleTooltipContent, hideTooltipOnClick: true, position: "mouse", mousePosition: "auto-start", testId: "resizer-handle-".concat(position, "-tooltip") }, thumbWithTrack)))); } return _objectSpread(_objectSpread({}, result), {}, _defineProperty({}, position, /*#__PURE__*/ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 React.createElement("div", { contentEditable: false, style: inheritedCSS }, thumbWithTrack))); }, {}); }, [handleHighlight, handleTooltipContent, formatMessage, supportedHandles]); // snapGap is usually a constant, if snap.x?.length is 0 and snapGap has a value resizer cannot be resized var snapGapActual = useMemo(function () { var _snap$x, _snap$y; if (!snap || ((_snap$x = snap.x) === null || _snap$x === void 0 ? void 0 : _snap$x.length) === 0 && ((_snap$y = snap.y) === null || _snap$y === void 0 ? void 0 : _snap$y.length) === 0) { return undefined; } return snapGap; }, [snap, snapGap]); var resolvedHeight = expValEquals('databases-native-embeds-v2', 'isEnabled', true) ? height !== null && height !== void 0 ? height : 'auto' : 'auto'; var resizerAutoSize = useMemo(function () { return { width: width !== null && width !== void 0 ? width : 'auto', height: resolvedHeight }; }, [resolvedHeight, width]); var resizerSize = expValEquals('platform_editor_perf_lint_cleanup', 'isEnabled', true) ? resizerAutoSize : // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- intentional fallback for experiment off path { width: width !== null && width !== void 0 ? width : 'auto', height: resolvedHeight }; return /*#__PURE__*/React.createElement(Resizable, _extends({ ref: resizable, size: resizerSize // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: resizerClassName, handleClasses: handles, handleWrapperClass: handleWrapperClass, handleStyles: nextHandleStyles, onResizeStart: onResizeStart, onResize: onResize, onResizeStop: onResizeStop, resizeRatio: resizeRatio, snapGap: snapGapActual, snap: snap, handleComponent: handleComponent // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading }, otherProps), /*#__PURE__*/React.createElement("span", { className: resizerZoneClassName, ref: function ref(_ref) { return childrenDOMRef && childrenDOMRef(_ref); } }, children), labelComponent && editorExperiment('single_column_layouts', true) && /*#__PURE__*/React.createElement(Box, { xcss: resizerLabelStyles }, labelComponent)); }; var _default_1 = /*#__PURE__*/forwardRef(ResizerNext); export default _default_1;