@atlaskit/editor-plugin-block-controls 8.7.2 → 8.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/blockControlsPlugin.js +14 -3
  3. package/dist/cjs/pm-plugins/decorations-drag-handle.js +3 -0
  4. package/dist/cjs/pm-plugins/decorations-quick-insert-button.js +3 -0
  5. package/dist/cjs/pm-plugins/handle-mouse-over.js +27 -11
  6. package/dist/cjs/pm-plugins/interaction-tracking/commands.js +12 -1
  7. package/dist/cjs/pm-plugins/interaction-tracking/handle-mouse-move.js +96 -1
  8. package/dist/cjs/pm-plugins/interaction-tracking/pm-plugin.js +92 -3
  9. package/dist/cjs/pm-plugins/main.js +129 -25
  10. package/dist/cjs/pm-plugins/vanilla-quick-insert.js +36 -13
  11. package/dist/cjs/ui/drag-handle.js +19 -9
  12. package/dist/cjs/ui/global-styles.js +9 -4
  13. package/dist/cjs/ui/quick-insert-button.js +16 -3
  14. package/dist/cjs/ui/visibility-container.js +70 -9
  15. package/dist/es2019/blockControlsPlugin.js +12 -3
  16. package/dist/es2019/pm-plugins/decorations-drag-handle.js +3 -0
  17. package/dist/es2019/pm-plugins/decorations-quick-insert-button.js +3 -0
  18. package/dist/es2019/pm-plugins/handle-mouse-over.js +27 -11
  19. package/dist/es2019/pm-plugins/interaction-tracking/commands.js +11 -0
  20. package/dist/es2019/pm-plugins/interaction-tracking/handle-mouse-move.js +98 -3
  21. package/dist/es2019/pm-plugins/interaction-tracking/pm-plugin.js +89 -4
  22. package/dist/es2019/pm-plugins/main.js +73 -18
  23. package/dist/es2019/pm-plugins/vanilla-quick-insert.js +27 -3
  24. package/dist/es2019/ui/drag-handle.js +19 -9
  25. package/dist/es2019/ui/global-styles.js +9 -3
  26. package/dist/es2019/ui/quick-insert-button.js +17 -3
  27. package/dist/es2019/ui/visibility-container.js +65 -9
  28. package/dist/esm/blockControlsPlugin.js +14 -3
  29. package/dist/esm/pm-plugins/decorations-drag-handle.js +3 -0
  30. package/dist/esm/pm-plugins/decorations-quick-insert-button.js +3 -0
  31. package/dist/esm/pm-plugins/handle-mouse-over.js +27 -11
  32. package/dist/esm/pm-plugins/interaction-tracking/commands.js +11 -0
  33. package/dist/esm/pm-plugins/interaction-tracking/handle-mouse-move.js +98 -2
  34. package/dist/esm/pm-plugins/interaction-tracking/pm-plugin.js +93 -3
  35. package/dist/esm/pm-plugins/main.js +129 -25
  36. package/dist/esm/pm-plugins/vanilla-quick-insert.js +36 -13
  37. package/dist/esm/ui/drag-handle.js +19 -9
  38. package/dist/esm/ui/global-styles.js +9 -4
  39. package/dist/esm/ui/quick-insert-button.js +16 -3
  40. package/dist/esm/ui/visibility-container.js +68 -9
  41. package/dist/types/blockControlsPluginType.d.ts +25 -1
  42. package/dist/types/index.d.ts +1 -1
  43. package/dist/types/pm-plugins/interaction-tracking/commands.d.ts +2 -0
  44. package/dist/types/pm-plugins/interaction-tracking/handle-mouse-move.d.ts +2 -2
  45. package/dist/types/pm-plugins/interaction-tracking/pm-plugin.d.ts +5 -1
  46. package/dist/types/pm-plugins/main.d.ts +2 -2
  47. package/dist/types/ui/visibility-container.d.ts +2 -1
  48. package/dist/types-ts4.5/blockControlsPluginType.d.ts +27 -1
  49. package/dist/types-ts4.5/index.d.ts +1 -1
  50. package/dist/types-ts4.5/pm-plugins/interaction-tracking/commands.d.ts +2 -0
  51. package/dist/types-ts4.5/pm-plugins/interaction-tracking/handle-mouse-move.d.ts +2 -2
  52. package/dist/types-ts4.5/pm-plugins/interaction-tracking/pm-plugin.d.ts +5 -1
  53. package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -2
  54. package/dist/types-ts4.5/ui/visibility-container.d.ts +2 -1
  55. package/package.json +5 -7
@@ -1,17 +1,20 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
1
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  /**
3
4
  * @jsxRuntime classic
4
5
  * @jsx jsx
5
6
  */
6
- import React from 'react';
7
+ import React, { useEffect, useRef, useState } from 'react';
7
8
 
8
9
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
9
10
  import { css, jsx } from '@emotion/react';
10
- import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
11
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
11
12
  import { akEditorFullPageNarrowBreakout } from '@atlaskit/editor-shared-styles';
12
13
  // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
13
14
  import { Box, xcss } from '@atlaskit/primitives';
15
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
16
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
17
+ var RIGHT_CONTROL_HIDE_DELAY_MS = 150;
15
18
  var baseStyles = xcss({
16
19
  transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out'
17
20
  });
@@ -39,14 +42,70 @@ var hiddenStylesCSS = css({
39
42
  });
40
43
  export var VisibilityContainer = function VisibilityContainer(_ref) {
41
44
  var api = _ref.api,
42
- children = _ref.children;
43
- var isTypeAheadOpen = useSharedPluginStateSelector(api, 'typeAhead.isOpen');
44
- var isEditing = useSharedPluginStateSelector(api, 'blockControls.isEditing');
45
- var isMouseOut = useSharedPluginStateSelector(api, 'blockControls.isMouseOut');
45
+ children = _ref.children,
46
+ controlSide = _ref.controlSide;
47
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['typeAhead', 'blockControls', 'editorViewMode', 'userIntent'], function (states) {
48
+ var _states$typeAheadStat, _states$blockControls, _states$blockControls2, _states$blockControls3, _states$editorViewMod, _states$userIntentSta, _states$blockControls4;
49
+ return {
50
+ isTypeAheadOpen: (_states$typeAheadStat = states.typeAheadState) === null || _states$typeAheadStat === void 0 ? void 0 : _states$typeAheadStat.isOpen,
51
+ isEditing: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.isEditing,
52
+ isMouseOut: (_states$blockControls2 = states.blockControlsState) === null || _states$blockControls2 === void 0 ? void 0 : _states$blockControls2.isMouseOut,
53
+ hoverSide: (_states$blockControls3 = states.blockControlsState) === null || _states$blockControls3 === void 0 ? void 0 : _states$blockControls3.hoverSide,
54
+ editorViewMode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode,
55
+ userIntent: (_states$userIntentSta = states.userIntentState) === null || _states$userIntentSta === void 0 ? void 0 : _states$userIntentSta.currentUserIntent,
56
+ rightSideControlsEnabled: (_states$blockControls4 = states.blockControlsState) === null || _states$blockControls4 === void 0 ? void 0 : _states$blockControls4.rightSideControlsEnabled
57
+ };
58
+ }),
59
+ isTypeAheadOpen = _useSharedPluginState.isTypeAheadOpen,
60
+ isEditing = _useSharedPluginState.isEditing,
61
+ isMouseOut = _useSharedPluginState.isMouseOut,
62
+ hoverSide = _useSharedPluginState.hoverSide,
63
+ editorViewMode = _useSharedPluginState.editorViewMode,
64
+ userIntent = _useSharedPluginState.userIntent,
65
+ rightSideControlsEnabled = _useSharedPluginState.rightSideControlsEnabled;
66
+ var isViewMode = editorViewMode === 'view';
67
+ var shouldRestrictBySide = rightSideControlsEnabled && expValEquals('confluence_remix_icon_right_side', 'isEnabled', true) && controlSide !== undefined && !isViewMode;
68
+ // Only restrict by side when hoverSide is known (after mousemove). When undefined, show both
69
+ // controls so drag handle is visible on load and for keyboard-only users.
70
+ var sideHidden = shouldRestrictBySide && hoverSide !== undefined ? hoverSide !== controlSide : false;
71
+ // In view mode with right-side controls, we delay hiding on isMouseOut (see below) so the right-edge
72
+ // button stays visible when the user moves from the block toward the button (e.g. in edit/live
73
+ // pages), avoiding flicker as the mouse crosses boundaries.
74
+ var hideOnMouseOut = isMouseOut;
75
+ var shouldHideImmediate = isTypeAheadOpen || isEditing || hideOnMouseOut || userIntent === 'aiStreaming' || sideHidden;
46
76
 
47
- // when ai streaming, hide the block controls
48
- var userIntent = useSharedPluginStateSelector(api, 'userIntent.currentUserIntent');
49
- var shouldHide = isTypeAheadOpen || isEditing || isMouseOut || userIntent === 'aiStreaming';
77
+ // Delay hiding the right control in view mode to reduce flickering when moving from block
78
+ // toward the right-edge button (avoids rapid show/hide as mouse crosses boundaries).
79
+ var isRightControlViewMode = isViewMode && rightSideControlsEnabled && expValEquals('confluence_remix_icon_right_side', 'isEnabled', true) && controlSide === 'right';
80
+ // When in right-control view mode, we delay hiding so start visible; useEffect will update after delay
81
+ var _useState = useState(false),
82
+ _useState2 = _slicedToArray(_useState, 2),
83
+ delayedShouldHide = _useState2[0],
84
+ setDelayedShouldHide = _useState2[1];
85
+ var hideTimeoutRef = useRef(null);
86
+ useEffect(function () {
87
+ if (!isRightControlViewMode) {
88
+ return;
89
+ }
90
+ if (!shouldHideImmediate) {
91
+ if (hideTimeoutRef.current) {
92
+ clearTimeout(hideTimeoutRef.current);
93
+ hideTimeoutRef.current = null;
94
+ }
95
+ setDelayedShouldHide(false);
96
+ return;
97
+ }
98
+ hideTimeoutRef.current = setTimeout(function () {
99
+ hideTimeoutRef.current = null;
100
+ setDelayedShouldHide(true);
101
+ }, RIGHT_CONTROL_HIDE_DELAY_MS);
102
+ return function () {
103
+ if (hideTimeoutRef.current) {
104
+ clearTimeout(hideTimeoutRef.current);
105
+ }
106
+ };
107
+ }, [shouldHideImmediate, isRightControlViewMode]);
108
+ var shouldHide = isRightControlViewMode ? delayedShouldHide : shouldHideImmediate;
50
109
  if (editorExperiment('platform_editor_preview_panel_responsiveness', true, {
51
110
  exposure: true
52
111
  })) {
@@ -1,10 +1,11 @@
1
1
  import type { IntlShape } from 'react-intl-next';
2
2
  import type { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
3
  import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
4
- import type { DIRECTION, EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
4
+ import type { DIRECTION, EditorCommand, NextEditorPlugin, OptionalPlugin, PublicPluginAPI } from '@atlaskit/editor-common/types';
5
5
  import type { AccessibilityUtilsPlugin } from '@atlaskit/editor-plugin-accessibility-utils';
6
6
  import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
7
7
  import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
8
+ import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode';
8
9
  import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
9
10
  import type { InteractionPlugin } from '@atlaskit/editor-plugin-interaction';
10
11
  import type { LimitedModePlugin } from '@atlaskit/editor-plugin-limited-mode';
@@ -77,6 +78,10 @@ export interface PluginState {
77
78
  preservedSelection?: Selection;
78
79
  }
79
80
  export type ReleaseHiddenDecoration = () => boolean | undefined;
81
+ export type BlockControlsPluginConfig = {
82
+ /** Enable left/right hover split: show left controls when hovering left, right controls when hovering right */
83
+ rightSideControlsEnabled?: boolean;
84
+ };
80
85
  export type BlockControlsSharedState = {
81
86
  activeDropTargetNode?: ActiveDropTargetNode;
82
87
  activeNode?: ActiveNode;
@@ -85,6 +90,7 @@ export type BlockControlsSharedState = {
85
90
  canMoveUp?: boolean;
86
91
  openedViaKeyboard?: boolean;
87
92
  };
93
+ hoverSide?: 'left' | 'right';
88
94
  isDragging: boolean;
89
95
  isEditing?: boolean;
90
96
  isMenuOpen: boolean;
@@ -97,10 +103,20 @@ export type BlockControlsSharedState = {
97
103
  menuTriggerByNode?: TriggerByNode;
98
104
  multiSelectDnD?: MultiSelectDnD;
99
105
  preservedSelection?: Selection;
106
+ /** Whether left/right hover split is enabled (from plugin config) */
107
+ rightSideControlsEnabled?: boolean;
100
108
  } | undefined;
101
109
  export type HandleOptions = {
102
110
  isFocused: boolean;
103
111
  } | undefined;
112
+ /**
113
+ * Props passed to custom right-edge button components (e.g. config.rightEdgeButton).
114
+ * Used by malleable-ui for BlockRemixButton when rendered via node decoration.
115
+ */
116
+ export type RightEdgeButtonProps = {
117
+ api: PublicPluginAPI<[BlockControlsPlugin]>;
118
+ getPos: () => number | undefined;
119
+ };
104
120
  export type NodeDecorationFactoryParams = {
105
121
  anchorName: string;
106
122
  editorState: EditorState;
@@ -110,14 +126,21 @@ export type NodeDecorationFactoryParams = {
110
126
  rootNodeType?: string;
111
127
  rootPos: number;
112
128
  };
129
+ /**
130
+ * When true, this factory's decorations are shown in view mode on block hover
131
+ * (without drag handle or quick insert). Used for right-edge controls.
132
+ */
113
133
  export type NodeDecorationFactory = {
114
134
  create: (params: NodeDecorationFactoryParams) => Decoration;
135
+ /** Show this decoration in view mode when hovering over a block */
136
+ showInViewMode?: boolean;
115
137
  type: string;
116
138
  };
117
139
  export type MoveNode = (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
118
140
  export type BlockControlsPluginDependencies = [
119
141
  OptionalPlugin<LimitedModePlugin>,
120
142
  OptionalPlugin<EditorDisabledPlugin>,
143
+ OptionalPlugin<EditorViewModePlugin>,
121
144
  OptionalPlugin<WidthPlugin>,
122
145
  OptionalPlugin<FeatureFlagsPlugin>,
123
146
  OptionalPlugin<AnalyticsPlugin>,
@@ -175,6 +198,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
175
198
  }) => EditorCommand;
176
199
  };
177
200
  dependencies: BlockControlsPluginDependencies;
201
+ pluginConfiguration?: BlockControlsPluginConfig;
178
202
  sharedState: BlockControlsSharedState;
179
203
  }>;
180
204
  export type BlockControlsMeta = {
@@ -1,2 +1,2 @@
1
1
  export { blockControlsPlugin } from './blockControlsPlugin';
2
- export type { BlockControlsPlugin, BlockControlsSharedState, HandleOptions, MoveNodeMethod, BlockControlsPluginDependencies, NodeDecorationFactory, NodeDecorationFactoryParams, PluginState, MoveNode, } from './blockControlsPluginType';
2
+ export type { BlockControlsPlugin, BlockControlsPluginConfig, BlockControlsSharedState, HandleOptions, MoveNodeMethod, BlockControlsPluginDependencies, NodeDecorationFactory, NodeDecorationFactoryParams, PluginState, RightEdgeButtonProps, MoveNode, } from './blockControlsPluginType';
@@ -3,3 +3,5 @@ export declare const stopEditing: (view: EditorView) => void;
3
3
  export declare const startEditing: (view: EditorView) => void;
4
4
  export declare const mouseLeave: (view: EditorView) => void;
5
5
  export declare const mouseEnter: (view: EditorView) => void;
6
+ export declare const setHoverSide: (view: EditorView, side: "left" | "right") => void;
7
+ export declare const clearHoverSide: (view: EditorView) => void;
@@ -1,4 +1,4 @@
1
1
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
- export declare const handleMouseMove: (view: EditorView) => boolean;
3
- export declare const handleMouseLeave: (view: EditorView) => boolean;
2
+ export declare const handleMouseMove: (view: EditorView, event: Event, rightSideControlsEnabled?: boolean) => boolean;
3
+ export declare const handleMouseLeave: (view: EditorView, rightSideControlsEnabled?: boolean) => boolean;
4
4
  export declare const handleMouseEnter: (view: EditorView) => boolean;
@@ -2,6 +2,10 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
4
  export type InteractionTrackingPluginState = {
5
+ /**
6
+ * Tracks which side of the editor the mouse is currently on.
7
+ */
8
+ hoverSide?: 'left' | 'right';
5
9
  /**
6
10
  * Tracks if a users intention is to edit the document (e.g. typing, deleting, etc.)
7
11
  */
@@ -12,5 +16,5 @@ export type InteractionTrackingPluginState = {
12
16
  isMouseOut?: boolean;
13
17
  };
14
18
  export declare const interactionTrackingPluginKey: PluginKey<InteractionTrackingPluginState>;
15
- export declare const createInteractionTrackingPlugin: () => SafePlugin<InteractionTrackingPluginState>;
19
+ export declare const createInteractionTrackingPlugin: (rightSideControlsEnabled?: boolean) => SafePlugin<InteractionTrackingPluginState>;
16
20
  export declare const getInteractionTrackingState: (state: EditorState) => InteractionTrackingPluginState | undefined;
@@ -13,7 +13,7 @@ export interface FlagType {
13
13
  toolbarFlagsEnabled: boolean;
14
14
  }
15
15
  export declare const getDecorations: (state: EditorState) => DecorationSet | undefined;
16
- export declare const apply: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, formatMessage: IntlShape["formatMessage"], tr: ReadonlyTransaction, currentState: PluginState, newState: EditorState, flags: FlagType, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[], anchorRectCache?: AnchorRectCache, resizeObserverWidth?: ResizeObserver, pragmaticCleanup?: (() => void) | null) => PluginState | {
16
+ export declare const apply: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, formatMessage: IntlShape["formatMessage"], tr: ReadonlyTransaction, currentState: PluginState, newState: EditorState, flags: FlagType, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[], rightSideControlsEnabled?: boolean, anchorRectCache?: AnchorRectCache, resizeObserverWidth?: ResizeObserver, pragmaticCleanup?: (() => void) | null) => PluginState | {
17
17
  activeDropTargetNode: ActiveDropTargetNode | undefined;
18
18
  activeNode: any;
19
19
  blockMenuOptions: {
@@ -37,7 +37,7 @@ export declare const apply: (api: ExtractInjectionAPI<BlockControlsPlugin> | und
37
37
  menuTriggerByNode: any;
38
38
  multiSelectDnD: MultiSelectDnD | undefined;
39
39
  };
40
- export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, getIntl: () => IntlShape, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[]) => SafePlugin<PluginState | {
40
+ export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, getIntl: () => IntlShape, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[], rightSideControlsEnabled?: boolean) => SafePlugin<PluginState | {
41
41
  activeDropTargetNode: ActiveDropTargetNode | undefined;
42
42
  activeNode: any;
43
43
  blockMenuOptions: {
@@ -9,6 +9,7 @@ import type { BlockControlsPlugin } from '../blockControlsPluginType';
9
9
  interface VisibilityContainerProps {
10
10
  api?: ExtractInjectionAPI<BlockControlsPlugin>;
11
11
  children: React.ReactNode;
12
+ controlSide?: 'left' | 'right';
12
13
  }
13
- export declare const VisibilityContainer: ({ api, children }: VisibilityContainerProps) => jsx.JSX.Element;
14
+ export declare const VisibilityContainer: ({ api, children, controlSide }: VisibilityContainerProps) => jsx.JSX.Element;
14
15
  export {};
@@ -1,10 +1,11 @@
1
1
  import type { IntlShape } from 'react-intl-next';
2
2
  import type { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
3
  import type { PortalProviderAPI } from '@atlaskit/editor-common/portal';
4
- import type { DIRECTION, EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
4
+ import type { DIRECTION, EditorCommand, NextEditorPlugin, OptionalPlugin, PublicPluginAPI } from '@atlaskit/editor-common/types';
5
5
  import type { AccessibilityUtilsPlugin } from '@atlaskit/editor-plugin-accessibility-utils';
6
6
  import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
7
7
  import type { EditorDisabledPlugin } from '@atlaskit/editor-plugin-editor-disabled';
8
+ import type { EditorViewModePlugin } from '@atlaskit/editor-plugin-editor-viewmode';
8
9
  import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
9
10
  import type { InteractionPlugin } from '@atlaskit/editor-plugin-interaction';
10
11
  import type { LimitedModePlugin } from '@atlaskit/editor-plugin-limited-mode';
@@ -77,6 +78,10 @@ export interface PluginState {
77
78
  preservedSelection?: Selection;
78
79
  }
79
80
  export type ReleaseHiddenDecoration = () => boolean | undefined;
81
+ export type BlockControlsPluginConfig = {
82
+ /** Enable left/right hover split: show left controls when hovering left, right controls when hovering right */
83
+ rightSideControlsEnabled?: boolean;
84
+ };
80
85
  export type BlockControlsSharedState = {
81
86
  activeDropTargetNode?: ActiveDropTargetNode;
82
87
  activeNode?: ActiveNode;
@@ -85,6 +90,7 @@ export type BlockControlsSharedState = {
85
90
  canMoveUp?: boolean;
86
91
  openedViaKeyboard?: boolean;
87
92
  };
93
+ hoverSide?: 'left' | 'right';
88
94
  isDragging: boolean;
89
95
  isEditing?: boolean;
90
96
  isMenuOpen: boolean;
@@ -97,10 +103,22 @@ export type BlockControlsSharedState = {
97
103
  menuTriggerByNode?: TriggerByNode;
98
104
  multiSelectDnD?: MultiSelectDnD;
99
105
  preservedSelection?: Selection;
106
+ /** Whether left/right hover split is enabled (from plugin config) */
107
+ rightSideControlsEnabled?: boolean;
100
108
  } | undefined;
101
109
  export type HandleOptions = {
102
110
  isFocused: boolean;
103
111
  } | undefined;
112
+ /**
113
+ * Props passed to custom right-edge button components (e.g. config.rightEdgeButton).
114
+ * Used by malleable-ui for BlockRemixButton when rendered via node decoration.
115
+ */
116
+ export type RightEdgeButtonProps = {
117
+ api: PublicPluginAPI<[
118
+ BlockControlsPlugin
119
+ ]>;
120
+ getPos: () => number | undefined;
121
+ };
104
122
  export type NodeDecorationFactoryParams = {
105
123
  anchorName: string;
106
124
  editorState: EditorState;
@@ -110,14 +128,21 @@ export type NodeDecorationFactoryParams = {
110
128
  rootNodeType?: string;
111
129
  rootPos: number;
112
130
  };
131
+ /**
132
+ * When true, this factory's decorations are shown in view mode on block hover
133
+ * (without drag handle or quick insert). Used for right-edge controls.
134
+ */
113
135
  export type NodeDecorationFactory = {
114
136
  create: (params: NodeDecorationFactoryParams) => Decoration;
137
+ /** Show this decoration in view mode when hovering over a block */
138
+ showInViewMode?: boolean;
115
139
  type: string;
116
140
  };
117
141
  export type MoveNode = (start: number, to: number, inputMethod?: MoveNodeMethod, formatMessage?: IntlShape['formatMessage']) => EditorCommand;
118
142
  export type BlockControlsPluginDependencies = [
119
143
  OptionalPlugin<LimitedModePlugin>,
120
144
  OptionalPlugin<EditorDisabledPlugin>,
145
+ OptionalPlugin<EditorViewModePlugin>,
121
146
  OptionalPlugin<WidthPlugin>,
122
147
  OptionalPlugin<FeatureFlagsPlugin>,
123
148
  OptionalPlugin<AnalyticsPlugin>,
@@ -175,6 +200,7 @@ export type BlockControlsPlugin = NextEditorPlugin<'blockControls', {
175
200
  }) => EditorCommand;
176
201
  };
177
202
  dependencies: BlockControlsPluginDependencies;
203
+ pluginConfiguration?: BlockControlsPluginConfig;
178
204
  sharedState: BlockControlsSharedState;
179
205
  }>;
180
206
  export type BlockControlsMeta = {
@@ -1,2 +1,2 @@
1
1
  export { blockControlsPlugin } from './blockControlsPlugin';
2
- export type { BlockControlsPlugin, BlockControlsSharedState, HandleOptions, MoveNodeMethod, BlockControlsPluginDependencies, NodeDecorationFactory, NodeDecorationFactoryParams, PluginState, MoveNode, } from './blockControlsPluginType';
2
+ export type { BlockControlsPlugin, BlockControlsPluginConfig, BlockControlsSharedState, HandleOptions, MoveNodeMethod, BlockControlsPluginDependencies, NodeDecorationFactory, NodeDecorationFactoryParams, PluginState, RightEdgeButtonProps, MoveNode, } from './blockControlsPluginType';
@@ -3,3 +3,5 @@ export declare const stopEditing: (view: EditorView) => void;
3
3
  export declare const startEditing: (view: EditorView) => void;
4
4
  export declare const mouseLeave: (view: EditorView) => void;
5
5
  export declare const mouseEnter: (view: EditorView) => void;
6
+ export declare const setHoverSide: (view: EditorView, side: "left" | "right") => void;
7
+ export declare const clearHoverSide: (view: EditorView) => void;
@@ -1,4 +1,4 @@
1
1
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
2
- export declare const handleMouseMove: (view: EditorView) => boolean;
3
- export declare const handleMouseLeave: (view: EditorView) => boolean;
2
+ export declare const handleMouseMove: (view: EditorView, event: Event, rightSideControlsEnabled?: boolean) => boolean;
3
+ export declare const handleMouseLeave: (view: EditorView, rightSideControlsEnabled?: boolean) => boolean;
4
4
  export declare const handleMouseEnter: (view: EditorView) => boolean;
@@ -2,6 +2,10 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
2
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
4
  export type InteractionTrackingPluginState = {
5
+ /**
6
+ * Tracks which side of the editor the mouse is currently on.
7
+ */
8
+ hoverSide?: 'left' | 'right';
5
9
  /**
6
10
  * Tracks if a users intention is to edit the document (e.g. typing, deleting, etc.)
7
11
  */
@@ -12,5 +16,5 @@ export type InteractionTrackingPluginState = {
12
16
  isMouseOut?: boolean;
13
17
  };
14
18
  export declare const interactionTrackingPluginKey: PluginKey<InteractionTrackingPluginState>;
15
- export declare const createInteractionTrackingPlugin: () => SafePlugin<InteractionTrackingPluginState>;
19
+ export declare const createInteractionTrackingPlugin: (rightSideControlsEnabled?: boolean) => SafePlugin<InteractionTrackingPluginState>;
16
20
  export declare const getInteractionTrackingState: (state: EditorState) => InteractionTrackingPluginState | undefined;
@@ -13,7 +13,7 @@ export interface FlagType {
13
13
  toolbarFlagsEnabled: boolean;
14
14
  }
15
15
  export declare const getDecorations: (state: EditorState) => DecorationSet | undefined;
16
- export declare const apply: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, formatMessage: IntlShape["formatMessage"], tr: ReadonlyTransaction, currentState: PluginState, newState: EditorState, flags: FlagType, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[], anchorRectCache?: AnchorRectCache, resizeObserverWidth?: ResizeObserver, pragmaticCleanup?: (() => void) | null) => PluginState | {
16
+ export declare const apply: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, formatMessage: IntlShape["formatMessage"], tr: ReadonlyTransaction, currentState: PluginState, newState: EditorState, flags: FlagType, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[], rightSideControlsEnabled?: boolean, anchorRectCache?: AnchorRectCache, resizeObserverWidth?: ResizeObserver, pragmaticCleanup?: (() => void) | null) => PluginState | {
17
17
  activeDropTargetNode: ActiveDropTargetNode | undefined;
18
18
  activeNode: any;
19
19
  blockMenuOptions: {
@@ -37,7 +37,7 @@ export declare const apply: (api: ExtractInjectionAPI<BlockControlsPlugin> | und
37
37
  menuTriggerByNode: any;
38
38
  multiSelectDnD: MultiSelectDnD | undefined;
39
39
  };
40
- export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, getIntl: () => IntlShape, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[]) => SafePlugin<PluginState | {
40
+ export declare const createPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined, getIntl: () => IntlShape, nodeViewPortalProviderAPI: PortalProviderAPI, nodeDecorationRegistry: NodeDecorationFactory[], rightSideControlsEnabled?: boolean) => SafePlugin<PluginState | {
41
41
  activeDropTargetNode: ActiveDropTargetNode | undefined;
42
42
  activeNode: any;
43
43
  blockMenuOptions: {
@@ -9,6 +9,7 @@ import type { BlockControlsPlugin } from '../blockControlsPluginType';
9
9
  interface VisibilityContainerProps {
10
10
  api?: ExtractInjectionAPI<BlockControlsPlugin>;
11
11
  children: React.ReactNode;
12
+ controlSide?: 'left' | 'right';
12
13
  }
13
- export declare const VisibilityContainer: ({ api, children }: VisibilityContainerProps) => jsx.JSX.Element;
14
+ export declare const VisibilityContainer: ({ api, children, controlSide }: VisibilityContainerProps) => jsx.JSX.Element;
14
15
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "8.7.2",
3
+ "version": "8.8.0",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -28,12 +28,13 @@
28
28
  ],
29
29
  "atlaskit:src": "src/index.ts",
30
30
  "dependencies": {
31
- "@atlaskit/adf-schema": "^52.0.0",
31
+ "@atlaskit/adf-schema": "^52.1.0",
32
32
  "@atlaskit/browser-apis": "^0.0.1",
33
33
  "@atlaskit/button": "^23.9.0",
34
34
  "@atlaskit/editor-plugin-accessibility-utils": "^7.0.0",
35
35
  "@atlaskit/editor-plugin-analytics": "^7.0.0",
36
36
  "@atlaskit/editor-plugin-editor-disabled": "^7.0.0",
37
+ "@atlaskit/editor-plugin-editor-viewmode": "^9.0.0",
37
38
  "@atlaskit/editor-plugin-feature-flags": "^6.0.0",
38
39
  "@atlaskit/editor-plugin-interaction": "^14.0.0",
39
40
  "@atlaskit/editor-plugin-limited-mode": "^4.0.0",
@@ -56,7 +57,7 @@
56
57
  "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
57
58
  "@atlaskit/primitives": "^18.0.0",
58
59
  "@atlaskit/theme": "^21.0.0",
59
- "@atlaskit/tmp-editor-statsig": "^32.2.0",
60
+ "@atlaskit/tmp-editor-statsig": "^32.5.0",
60
61
  "@atlaskit/tokens": "^11.0.0",
61
62
  "@atlaskit/tooltip": "^20.14.0",
62
63
  "@babel/runtime": "^7.0.0",
@@ -67,7 +68,7 @@
67
68
  "uuid": "^3.1.0"
68
69
  },
69
70
  "peerDependencies": {
70
- "@atlaskit/editor-common": "^111.20.0",
71
+ "@atlaskit/editor-common": "^111.23.0",
71
72
  "react": "^18.2.0",
72
73
  "react-dom": "^18.2.0",
73
74
  "react-intl-next": "npm:react-intl@^5.18.1"
@@ -129,9 +130,6 @@
129
130
  "platform_editor_fix_widget_destroy": {
130
131
  "type": "boolean"
131
132
  },
132
- "dst-a11y__replace-anchor-with-link__editor-jenga": {
133
- "type": "boolean"
134
- },
135
133
  "editor_native_anchor_remove_decoration_in_apply": {
136
134
  "type": "boolean"
137
135
  },