UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

125 lines (122 loc) 6.62 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; /** * @jsxRuntime classic * @jsx jsx */ import React, { useEffect, useRef, useState } from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports import { css, jsx } from '@emotion/react'; import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'; import { akEditorFullPageNarrowBreakout } from '@atlaskit/editor-shared-styles'; // 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 { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; var RIGHT_CONTROL_HIDE_DELAY_MS = 150; var baseStyles = xcss({ transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out' }); var visibleStyles = xcss({ opacity: 1, visibility: 'visible' }); var hiddenStyles = xcss({ opacity: 0, visibility: 'hidden' }); var baseStylesCSS = css(_defineProperty({ transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out' }, "@container editor-area (max-width: ".concat(akEditorFullPageNarrowBreakout, "px)"), { opacity: 0, visibility: 'hidden' })); var visibleStylesCSS = css({ opacity: 1, visibility: 'visible' }); var hiddenStylesCSS = css({ opacity: 0, visibility: 'hidden' }); export var VisibilityContainer = function VisibilityContainer(_ref) { var api = _ref.api, children = _ref.children, controlSide = _ref.controlSide, forceVisibleOnMouseOut = _ref.forceVisibleOnMouseOut; var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['typeAhead', 'blockControls', 'editorViewMode', 'userIntent'], function (states) { var _states$typeAheadStat, _states$blockControls, _states$blockControls2, _states$blockControls3, _states$editorViewMod, _states$userIntentSta, _states$blockControls4; return { isTypeAheadOpen: (_states$typeAheadStat = states.typeAheadState) === null || _states$typeAheadStat === void 0 ? void 0 : _states$typeAheadStat.isOpen, isEditing: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.isEditing, isMouseOut: (_states$blockControls2 = states.blockControlsState) === null || _states$blockControls2 === void 0 ? void 0 : _states$blockControls2.isMouseOut, hoverSide: (_states$blockControls3 = states.blockControlsState) === null || _states$blockControls3 === void 0 ? void 0 : _states$blockControls3.hoverSide, editorViewMode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode, userIntent: (_states$userIntentSta = states.userIntentState) === null || _states$userIntentSta === void 0 ? void 0 : _states$userIntentSta.currentUserIntent, rightSideControlsEnabled: (_states$blockControls4 = states.blockControlsState) === null || _states$blockControls4 === void 0 ? void 0 : _states$blockControls4.rightSideControlsEnabled }; }), isTypeAheadOpen = _useSharedPluginState.isTypeAheadOpen, isEditing = _useSharedPluginState.isEditing, isMouseOut = _useSharedPluginState.isMouseOut, hoverSide = _useSharedPluginState.hoverSide, editorViewMode = _useSharedPluginState.editorViewMode, userIntent = _useSharedPluginState.userIntent, rightSideControlsEnabled = _useSharedPluginState.rightSideControlsEnabled; var isViewMode = editorViewMode === 'view'; // rightSideControlsEnabled is the single source of truth (confluence_remix_button_right_side_block_fg from preset) var shouldRestrictBySide = rightSideControlsEnabled && controlSide !== undefined && !isViewMode; // Only restrict by side when hoverSide is known (after mousemove). When undefined, show both // controls so drag handle is visible on load and for keyboard-only users. var sideHidden = shouldRestrictBySide && hoverSide !== undefined ? hoverSide !== controlSide : false; // In view mode with right-side controls, we delay hiding on isMouseOut (see below) so the right-edge // button stays visible when the user moves from the block toward the button (e.g. in edit/live // pages), avoiding flicker as the mouse crosses boundaries. var hideOnMouseOut = isMouseOut; // When forceVisibleOnMouseOut is true (e.g. drag handle focused via keyboard Shift+Ctrl+H), // override the mouse-out condition so the control stays visible regardless of mouse position. var shouldHideWhenMouseOut = forceVisibleOnMouseOut ? false : hideOnMouseOut; var shouldHideImmediate = isTypeAheadOpen || isEditing || shouldHideWhenMouseOut || userIntent === 'aiStreaming' || sideHidden; // Delay hiding the right control in view mode to reduce flickering when moving from block // toward the right-edge button (avoids rapid show/hide as mouse crosses boundaries). var isRightControlViewMode = isViewMode && rightSideControlsEnabled && controlSide === 'right'; // When in right-control view mode, we delay hiding so start visible; useEffect will update after delay var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), delayedShouldHide = _useState2[0], setDelayedShouldHide = _useState2[1]; var hideTimeoutRef = useRef(null); useEffect(function () { if (!isRightControlViewMode) { return; } if (!shouldHideImmediate) { if (hideTimeoutRef.current) { clearTimeout(hideTimeoutRef.current); hideTimeoutRef.current = null; } setDelayedShouldHide(false); return; } hideTimeoutRef.current = setTimeout(function () { hideTimeoutRef.current = null; setDelayedShouldHide(true); }, RIGHT_CONTROL_HIDE_DELAY_MS); return function () { if (hideTimeoutRef.current) { clearTimeout(hideTimeoutRef.current); } }; }, [shouldHideImmediate, isRightControlViewMode]); var shouldHide = isRightControlViewMode ? delayedShouldHide : shouldHideImmediate; if (editorExperiment('platform_editor_preview_panel_responsiveness', true, { exposure: true })) { return jsx("div", { css: [baseStylesCSS, shouldHide ? hiddenStylesCSS : visibleStylesCSS] }, children); } // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) return jsx(Box, { xcss: [baseStyles, shouldHide ? hiddenStyles : visibleStyles] }, children); };